@@ -40,21 +40,42 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
40
40
predicate : self . infcx . resolve_vars_if_possible ( obligation. predicate ) ,
41
41
} ;
42
42
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
-
57
43
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
+ }
58
79
59
80
// Negative trait predicates have different rules than positive trait predicates.
60
81
if obligation. polarity ( ) == ty:: PredicatePolarity :: Negative {
@@ -66,8 +87,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
66
87
67
88
// Other bounds. Consider both in-scope bounds from fn decl
68
89
// 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 ( ) ;
71
90
72
91
if tcx. is_lang_item ( def_id, LangItem :: Copy ) {
73
92
debug ! ( obligation_self_ty = ?obligation. predicate. skip_binder( ) . self_ty( ) ) ;
0 commit comments