update auto trait handling
This commit is contained in:
parent
b112bc5529
commit
3adedc93a9
11 changed files with 339 additions and 78 deletions
|
@ -124,11 +124,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
self.assemble_candidates_from_projected_tys(obligation, &mut candidates);
|
||||
self.assemble_candidates_from_caller_bounds(stack, &mut candidates)?;
|
||||
// Auto implementations have lower priority, so we only
|
||||
// consider triggering a default if there is no other impl that can apply.
|
||||
if candidates.vec.is_empty() {
|
||||
self.assemble_candidates_from_auto_impls(obligation, &mut candidates);
|
||||
}
|
||||
self.assemble_candidates_from_auto_impls(obligation, &mut candidates);
|
||||
}
|
||||
debug!("candidate list size: {}", candidates.vec.len());
|
||||
Ok(candidates)
|
||||
|
@ -516,7 +512,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// for an example of a test case that exercises
|
||||
// this path.
|
||||
}
|
||||
ty::Infer(ty::TyVar(_)) => {
|
||||
ty::Infer(ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_)) => {
|
||||
// The auto impl might apply; we don't know.
|
||||
candidates.ambiguous = true;
|
||||
}
|
||||
|
@ -536,7 +532,49 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
_ => candidates.vec.push(AutoImplCandidate),
|
||||
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
|
||||
bug!(
|
||||
"asked to assemble auto trait candidates of unexpected type: {:?}",
|
||||
self_ty
|
||||
);
|
||||
}
|
||||
|
||||
// Only consider auto impls if there are no manual impls for the root of `self_ty`.
|
||||
//
|
||||
// For example, we only consider auto candidates for `&i32: Auto` if no explicit impl
|
||||
// for `&SomeType: Auto` exists. Due to E0321 the only crate where impls
|
||||
// for `&SomeType: Auto` can be defined is the crate where `Auto` has been defined.
|
||||
//
|
||||
// Generally, we have to guarantee that for all `SimplifiedType`s the only crate
|
||||
// which may define impls for that type is either the crate defining the type
|
||||
// or the trait. This should be guaranteed by the orphan check.
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
| ty::Int(_)
|
||||
| ty::Uint(_)
|
||||
| ty::Float(_)
|
||||
| ty::Str
|
||||
| ty::Array(_, _)
|
||||
| ty::Slice(_)
|
||||
| ty::Adt(..)
|
||||
| ty::RawPtr(_)
|
||||
| ty::Ref(..)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::Closure(_, _)
|
||||
| ty::Generator(..)
|
||||
| ty::Never
|
||||
| ty::Tuple(_)
|
||||
| ty::Alias(_, _)
|
||||
| ty::GeneratorWitness(_)
|
||||
| ty::GeneratorWitnessMIR(..) => {
|
||||
let mut has_impl = false;
|
||||
self.tcx().for_each_relevant_impl(def_id, self_ty, |_| has_impl = true);
|
||||
if !has_impl {
|
||||
candidates.vec.push(AutoImplCandidate)
|
||||
}
|
||||
}
|
||||
ty::Error(_) => {} // do not add an auto trait impl for `ty::Error` for now.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1814,6 +1814,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||
/// candidates and prefer where-clause candidates.
|
||||
///
|
||||
/// See the comment for "SelectionCandidate" for more details.
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn candidate_should_be_dropped_in_favor_of(
|
||||
&mut self,
|
||||
victim: &EvaluatedCandidate<'tcx>,
|
||||
|
@ -1837,13 +1838,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||
// This is a fix for #53123 and prevents winnowing from accidentally extending the
|
||||
// lifetime of a variable.
|
||||
match (&other.candidate, &victim.candidate) {
|
||||
(_, AutoImplCandidate) | (AutoImplCandidate, _) => {
|
||||
bug!(
|
||||
"default implementations shouldn't be recorded \
|
||||
when there are other valid candidates"
|
||||
);
|
||||
}
|
||||
|
||||
// FIXME(@jswrenn): this should probably be more sophisticated
|
||||
(TransmutabilityCandidate, _) | (_, TransmutabilityCandidate) => DropVictim::No,
|
||||
|
||||
|
@ -1885,6 +1879,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||
(
|
||||
ParamCandidate(ref other_cand),
|
||||
ImplCandidate(..)
|
||||
| AutoImplCandidate
|
||||
| ClosureCandidate { .. }
|
||||
| GeneratorCandidate
|
||||
| FutureCandidate
|
||||
|
@ -1912,6 +1907,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||
}
|
||||
(
|
||||
ImplCandidate(_)
|
||||
| AutoImplCandidate
|
||||
| ClosureCandidate { .. }
|
||||
| GeneratorCandidate
|
||||
| FutureCandidate
|
||||
|
@ -1945,6 +1941,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||
(
|
||||
ObjectCandidate(_) | ProjectionCandidate(..),
|
||||
ImplCandidate(..)
|
||||
| AutoImplCandidate
|
||||
| ClosureCandidate { .. }
|
||||
| GeneratorCandidate
|
||||
| FutureCandidate
|
||||
|
@ -1958,6 +1955,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||
|
||||
(
|
||||
ImplCandidate(..)
|
||||
| AutoImplCandidate
|
||||
| ClosureCandidate { .. }
|
||||
| GeneratorCandidate
|
||||
| FutureCandidate
|
||||
|
@ -2048,6 +2046,19 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
(AutoImplCandidate, ImplCandidate(_)) | (ImplCandidate(_), AutoImplCandidate) => {
|
||||
DropVictim::No
|
||||
}
|
||||
|
||||
(AutoImplCandidate, _) | (_, AutoImplCandidate) => {
|
||||
bug!(
|
||||
"default implementations shouldn't be recorded \
|
||||
when there are other global candidates: {:?} {:?}",
|
||||
other,
|
||||
victim
|
||||
);
|
||||
}
|
||||
|
||||
// Everything else is ambiguous
|
||||
(
|
||||
ImplCandidate(_)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue