@@ -124,11 +124,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
124
124
125
125
self . assemble_candidates_from_projected_tys ( obligation, & mut candidates) ;
126
126
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) ;
132
128
}
133
129
debug ! ( "candidate list size: {}" , candidates. vec. len( ) ) ;
134
130
Ok ( candidates)
@@ -513,7 +509,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
513
509
// for an example of a test case that exercises
514
510
// this path.
515
511
}
516
- ty:: Infer ( ty:: TyVar ( _) ) => {
512
+ ty:: Infer ( ty:: TyVar ( _) | ty :: IntVar ( _ ) | ty :: FloatVar ( _ ) ) => {
517
513
// The auto impl might apply; we don't know.
518
514
candidates. ambiguous = true ;
519
515
}
@@ -533,7 +529,63 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
533
529
}
534
530
}
535
531
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.
537
589
}
538
590
}
539
591
}
0 commit comments