@@ -124,11 +124,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
124124
125125 self . assemble_candidates_from_projected_tys ( obligation, & mut candidates) ;
126126 self . assemble_candidates_from_caller_bounds ( stack, & mut candidates) ?;
127- // Auto implementations have lower priority, so we only
128- // consider triggering a default if there is no other impl that can apply.
129- if candidates. vec . is_empty ( ) {
130- self . assemble_candidates_from_auto_impls ( obligation, & mut candidates) ;
131- }
127+ self . assemble_candidates_from_auto_impls ( obligation, & mut candidates) ;
132128 }
133129 debug ! ( "candidate list size: {}" , candidates. vec. len( ) ) ;
134130 Ok ( candidates)
@@ -513,7 +509,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
513509 // for an example of a test case that exercises
514510 // this path.
515511 }
516- ty:: Infer ( ty:: TyVar ( _) ) => {
512+ ty:: Infer ( ty:: TyVar ( _) | ty :: IntVar ( _ ) | ty :: FloatVar ( _ ) ) => {
517513 // The auto impl might apply; we don't know.
518514 candidates. ambiguous = true ;
519515 }
@@ -533,7 +529,63 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
533529 }
534530 }
535531
536- _ => candidates. vec . push ( AutoImplCandidate ) ,
532+ ty:: Infer ( ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) ) => {
533+ bug ! (
534+ "asked to assemble auto trait candidates of unexpected type: {:?}" ,
535+ self_ty
536+ ) ;
537+ }
538+
539+ ty:: Alias ( _, _)
540+ if candidates. vec . iter ( ) . any ( |c| matches ! ( c, ProjectionCandidate ( ..) ) ) =>
541+ {
542+ // We do not generate an auto impl candidate for `impl Trait`s which already
543+ // reference our auto trait.
544+ //
545+ // For example during candidate assembly for `impl Send: Send`, we don't have
546+ // to look at the constituent types for this opaque types to figure out that this
547+ // trivially holds.
548+ //
549+ // Note that this is only sound as projection candidates of opaque types
550+ // are always applicable for auto traits.
551+ }
552+ ty:: Alias ( _, _) => candidates. vec . push ( AutoImplCandidate ) ,
553+
554+ ty:: Bool
555+ | ty:: Char
556+ | ty:: Int ( _)
557+ | ty:: Uint ( _)
558+ | ty:: Float ( _)
559+ | ty:: Str
560+ | ty:: Array ( _, _)
561+ | ty:: Slice ( _)
562+ | ty:: Adt ( ..)
563+ | ty:: RawPtr ( _)
564+ | ty:: Ref ( ..)
565+ | ty:: FnDef ( ..)
566+ | ty:: FnPtr ( _)
567+ | ty:: Closure ( _, _)
568+ | ty:: Generator ( ..)
569+ | ty:: Never
570+ | ty:: Tuple ( _)
571+ | ty:: GeneratorWitness ( _)
572+ | ty:: GeneratorWitnessMIR ( ..) => {
573+ // Only consider auto impls if there are no manual impls for the root of `self_ty`.
574+ //
575+ // For example, we only consider auto candidates for `&i32: Auto` if no explicit impl
576+ // for `&SomeType: Auto` exists. Due to E0321 the only crate where impls
577+ // for `&SomeType: Auto` can be defined is the crate where `Auto` has been defined.
578+ //
579+ // Generally, we have to guarantee that for all `SimplifiedType`s the only crate
580+ // which may define impls for that type is either the crate defining the type
581+ // or the trait. This should be guaranteed by the orphan check.
582+ let mut has_impl = false ;
583+ self . tcx ( ) . for_each_relevant_impl ( def_id, self_ty, |_| has_impl = true ) ;
584+ if !has_impl {
585+ candidates. vec . push ( AutoImplCandidate )
586+ }
587+ }
588+ ty:: Error ( _) => { } // do not add an auto trait impl for `ty::Error` for now.
537589 }
538590 }
539591 }
0 commit comments