@@ -169,6 +169,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
169
169
) -> ( Option < ExpectedSig < ' tcx > > , Option < ty:: ClosureKind > ) {
170
170
match * expected_ty. kind ( ) {
171
171
ty:: Opaque ( def_id, substs) => self . deduce_signature_from_predicates (
172
+ // Elaborating expectations from explicit_item_bounds shouldn't include any variable shenanigans
173
+ |ty| ty == expected_ty,
172
174
self . tcx . bound_explicit_item_bounds ( def_id) . subst_iter_copied ( self . tcx , substs) ,
173
175
) ,
174
176
ty:: Dynamic ( ref object_type, ..) => {
@@ -181,9 +183,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
181
183
. and_then ( |did| self . tcx . fn_trait_kind_from_lang_item ( did) ) ;
182
184
( sig, kind)
183
185
}
184
- ty:: Infer ( ty:: TyVar ( vid) ) => self . deduce_signature_from_predicates (
185
- self . obligations_for_self_ty ( vid) . map ( |obl| ( obl. predicate , obl. cause . span ) ) ,
186
- ) ,
186
+ ty:: Infer ( ty:: TyVar ( vid) ) => {
187
+ let root_vid = self . root_var ( vid) ;
188
+ self . deduce_signature_from_predicates (
189
+ // We need to do equality "modulo root vids" here, since that's
190
+ // how `obligations_for_self_ty` filters its predicates.
191
+ |ty| self . self_type_matches_expected_vid ( ty, root_vid) ,
192
+ self . obligations_for_self_ty ( root_vid)
193
+ . map ( |obl| ( obl. predicate , obl. cause . span ) ) ,
194
+ )
195
+ }
187
196
ty:: FnPtr ( sig) => {
188
197
let expected_sig = ExpectedSig { cause_span : None , sig } ;
189
198
( Some ( expected_sig) , Some ( ty:: ClosureKind :: Fn ) )
@@ -194,6 +203,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
194
203
195
204
fn deduce_signature_from_predicates (
196
205
& self ,
206
+ eq_expected_ty : impl Fn ( Ty < ' tcx > ) -> bool ,
197
207
predicates : impl DoubleEndedIterator < Item = ( ty:: Predicate < ' tcx > , Span ) > ,
198
208
) -> ( Option < ExpectedSig < ' tcx > > , Option < ty:: ClosureKind > ) {
199
209
let mut expected_sig = None ;
@@ -213,6 +223,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
213
223
// the complete signature.
214
224
if expected_sig. is_none ( )
215
225
&& let ty:: PredicateKind :: Projection ( proj_predicate) = bound_predicate. skip_binder ( )
226
+ && eq_expected_ty ( proj_predicate. projection_ty . self_ty ( ) )
216
227
{
217
228
expected_sig = self . normalize_associated_types_in (
218
229
obligation. cause . span ,
@@ -228,10 +239,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
228
239
// like `F : Fn<A>`. Note that due to subtyping we could encounter
229
240
// many viable options, so pick the most restrictive.
230
241
let trait_def_id = match bound_predicate. skip_binder ( ) {
231
- ty:: PredicateKind :: Projection ( data) => {
242
+ ty:: PredicateKind :: Projection ( data)
243
+ if eq_expected_ty ( data. projection_ty . self_ty ( ) ) =>
244
+ {
232
245
Some ( data. projection_ty . trait_def_id ( self . tcx ) )
233
246
}
234
- ty:: PredicateKind :: Trait ( data) => Some ( data. def_id ( ) ) ,
247
+ ty:: PredicateKind :: Trait ( data) if eq_expected_ty ( data. self_ty ( ) ) => {
248
+ Some ( data. def_id ( ) )
249
+ }
235
250
_ => None ,
236
251
} ;
237
252
if let Some ( closure_kind) =
0 commit comments