@@ -40,21 +40,42 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
4040 predicate : self . infcx . resolve_vars_if_possible ( obligation. predicate ) ,
4141 } ;
4242
43- if obligation. predicate . skip_binder ( ) . self_ty ( ) . is_ty_var ( ) {
44- debug ! ( ty = ?obligation. predicate. skip_binder( ) . self_ty( ) , "ambiguous inference var or opaque type" ) ;
45- // Self is a type variable (e.g., `_: AsRef<str>`).
46- //
47- // This is somewhat problematic, as the current scheme can't really
48- // handle it turning to be a projection. This does end up as truly
49- // ambiguous in most cases anyway.
50- //
51- // Take the fast path out - this also improves
52- // performance by preventing assemble_candidates_from_impls from
53- // matching every impl for this trait.
54- return Ok ( SelectionCandidateSet { vec : vec ! [ ] , ambiguous : true } ) ;
55- }
56-
5743 let mut candidates = SelectionCandidateSet { vec : Vec :: new ( ) , ambiguous : false } ;
44+ let def_id = obligation. predicate . def_id ( ) ;
45+ let tcx = self . tcx ( ) ;
46+
47+ match obligation. predicate . skip_binder ( ) . self_ty ( ) . kind ( ) {
48+ // Opaque types in their defining scope are just like inference vars...
49+ ty:: Alias ( ty:: Opaque , alias) if self . infcx . can_define_opaque_ty ( alias. def_id ) => {
50+ if tcx. is_lang_item ( def_id, LangItem :: Unsize ) {
51+ self . assemble_candidates_for_unsizing ( obligation, & mut candidates) ;
52+ }
53+ self . assemble_candidates_from_impls ( obligation, & mut candidates) ;
54+ // .. unless we are looking for candidates just on the opaque signature, ...
55+ self . assemble_candidates_from_projected_tys ( obligation, & mut candidates) ;
56+ // .. or for auto traits, which look at the hidden type.
57+ // Auto traits must be collected after projected tys, because opaque types
58+ // do not emit auto trait candidates if a projection for the same auto trait
59+ // already exists (e.g. due to the bounds on the opaque).
60+ self . assemble_candidates_from_auto_impls ( obligation, & mut candidates) ;
61+ return Ok ( candidates) ;
62+ }
63+ ty:: Infer ( ty:: TyVar ( vid) ) => {
64+ debug ! ( ?vid, "ambiguous inference var" ) ;
65+ // Self is a type variable (e.g., `_: AsRef<str>`).
66+ //
67+ // This is somewhat problematic, as the current scheme can't really
68+ // handle it turning to be a projection. This does end up as truly
69+ // ambiguous in most cases anyway.
70+ //
71+ // Take the fast path out - this also improves
72+ // performance by preventing assemble_candidates_from_impls from
73+ // matching every impl for this trait.
74+ candidates. ambiguous = true ;
75+ return Ok ( candidates) ;
76+ }
77+ _ => { }
78+ }
5879
5980 // Negative trait predicates have different rules than positive trait predicates.
6081 if obligation. polarity ( ) == ty:: PredicatePolarity :: Negative {
@@ -66,8 +87,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
6687
6788 // Other bounds. Consider both in-scope bounds from fn decl
6889 // and applicable impls. There is a certain set of precedence rules here.
69- let def_id = obligation. predicate . def_id ( ) ;
70- let tcx = self . tcx ( ) ;
7190
7291 if tcx. is_lang_item ( def_id, LangItem :: Copy ) {
7392 debug ! ( obligation_self_ty = ?obligation. predicate. skip_binder( ) . self_ty( ) ) ;
0 commit comments