@@ -16,6 +16,7 @@ use hir::def_id::DefId;
16
16
use rustc:: ty:: subst:: Substs ;
17
17
use rustc:: traits;
18
18
use rustc:: ty:: { self , LvaluePreference , NoPreference , PreferMutLvalue , Ty } ;
19
+ use rustc:: ty:: subst:: Subst ;
19
20
use rustc:: ty:: adjustment:: { Adjustment , Adjust , AutoBorrow , OverloadedDeref } ;
20
21
use rustc:: ty:: fold:: TypeFoldable ;
21
22
use rustc:: infer:: { self , InferOk } ;
@@ -84,9 +85,6 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
84
85
// Adjust the self expression the user provided and obtain the adjusted type.
85
86
let self_ty = self . adjust_self_ty ( unadjusted_self_ty, & pick) ;
86
87
87
- // Make sure nobody calls `drop()` explicitly.
88
- self . enforce_illegal_method_limitations ( & pick) ;
89
-
90
88
// Create substitutions for the method's type parameters.
91
89
let rcvr_substs = self . fresh_receiver_substs ( self_ty, & pick) ;
92
90
let all_substs = self . instantiate_method_substs ( & pick, segment, rcvr_substs) ;
@@ -96,6 +94,22 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
96
94
// Create the final signature for the method, replacing late-bound regions.
97
95
let ( method_sig, method_predicates) = self . instantiate_method_sig ( & pick, all_substs) ;
98
96
97
+ // Unify the (adjusted) self type with what the method expects.
98
+ //
99
+ // SUBTLE: if we want good error messages, because of "guessing" while matching
100
+ // traits, no trait system method can be called before this point because they
101
+ // could alter our Self-type, except for normalizing the receiver from the
102
+ // signature (which is also done during probing).
103
+ let method_sig_rcvr =
104
+ self . normalize_associated_types_in ( self . span , & method_sig. inputs ( ) [ 0 ] ) ;
105
+ self . unify_receivers ( self_ty, method_sig_rcvr) ;
106
+
107
+ let ( method_sig, method_predicates) =
108
+ self . normalize_associated_types_in ( self . span , & ( method_sig, method_predicates) ) ;
109
+
110
+ // Make sure nobody calls `drop()` explicitly.
111
+ self . enforce_illegal_method_limitations ( & pick) ;
112
+
99
113
// If there is a `Self: Sized` bound and `Self` is a trait object, it is possible that
100
114
// something which derefs to `Self` actually implements the trait and the caller
101
115
// wanted to make a static dispatch on it but forgot to import the trait.
@@ -106,9 +120,6 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
106
120
// appropriate hint suggesting to import the trait.
107
121
let illegal_sized_bound = self . predicates_require_illegal_sized_bound ( & method_predicates) ;
108
122
109
- // Unify the (adjusted) self type with what the method expects.
110
- self . unify_receivers ( self_ty, method_sig. inputs ( ) [ 0 ] ) ;
111
-
112
123
// Add any trait/regions obligations specified on the method's type parameters.
113
124
// We won't add these if we encountered an illegal sized bound, so that we can use
114
125
// a custom error in that case.
@@ -338,6 +349,9 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
338
349
///////////////////////////////////////////////////////////////////////////
339
350
//
340
351
352
+ // NOTE: this returns the *unnormalized* predicates and method sig. Because of
353
+ // inference guessing, the predicates and method signature can't be normalized
354
+ // until we unify the `Self` type.
341
355
fn instantiate_method_sig ( & mut self ,
342
356
pick : & probe:: Pick < ' tcx > ,
343
357
all_substs : & ' tcx Substs < ' tcx > )
@@ -352,8 +366,6 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
352
366
let def_id = pick. item . def_id ;
353
367
let method_predicates = self . tcx . predicates_of ( def_id)
354
368
. instantiate ( self . tcx , all_substs) ;
355
- let method_predicates = self . normalize_associated_types_in ( self . span ,
356
- & method_predicates) ;
357
369
358
370
debug ! ( "method_predicates after subst = {:?}" , method_predicates) ;
359
371
@@ -369,7 +381,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
369
381
debug ! ( "late-bound lifetimes from method instantiated, method_sig={:?}" ,
370
382
method_sig) ;
371
383
372
- let method_sig = self . instantiate_type_scheme ( self . span , all_substs, & method_sig ) ;
384
+ let method_sig = method_sig . subst ( self . tcx , all_substs) ;
373
385
debug ! ( "type scheme substituted, method_sig={:?}" , method_sig) ;
374
386
375
387
( method_sig, method_predicates)
0 commit comments