@@ -16,6 +16,7 @@ use hir::def_id::DefId;
1616use rustc:: ty:: subst:: Substs ;
1717use rustc:: traits;
1818use rustc:: ty:: { self , LvaluePreference , NoPreference , PreferMutLvalue , Ty } ;
19+ use rustc:: ty:: subst:: Subst ;
1920use rustc:: ty:: adjustment:: { Adjustment , Adjust , AutoBorrow , OverloadedDeref } ;
2021use rustc:: ty:: fold:: TypeFoldable ;
2122use rustc:: infer:: { self , InferOk } ;
@@ -84,9 +85,6 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
8485 // Adjust the self expression the user provided and obtain the adjusted type.
8586 let self_ty = self . adjust_self_ty ( unadjusted_self_ty, & pick) ;
8687
87- // Make sure nobody calls `drop()` explicitly.
88- self . enforce_illegal_method_limitations ( & pick) ;
89-
9088 // Create substitutions for the method's type parameters.
9189 let rcvr_substs = self . fresh_receiver_substs ( self_ty, & pick) ;
9290 let all_substs = self . instantiate_method_substs ( & pick, segment, rcvr_substs) ;
@@ -96,6 +94,22 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
9694 // Create the final signature for the method, replacing late-bound regions.
9795 let ( method_sig, method_predicates) = self . instantiate_method_sig ( & pick, all_substs) ;
9896
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+
99113 // If there is a `Self: Sized` bound and `Self` is a trait object, it is possible that
100114 // something which derefs to `Self` actually implements the trait and the caller
101115 // 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> {
106120 // appropriate hint suggesting to import the trait.
107121 let illegal_sized_bound = self . predicates_require_illegal_sized_bound ( & method_predicates) ;
108122
109- // Unify the (adjusted) self type with what the method expects.
110- self . unify_receivers ( self_ty, method_sig. inputs ( ) [ 0 ] ) ;
111-
112123 // Add any trait/regions obligations specified on the method's type parameters.
113124 // We won't add these if we encountered an illegal sized bound, so that we can use
114125 // a custom error in that case.
@@ -338,6 +349,9 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
338349 ///////////////////////////////////////////////////////////////////////////
339350 //
340351
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.
341355 fn instantiate_method_sig ( & mut self ,
342356 pick : & probe:: Pick < ' tcx > ,
343357 all_substs : & ' tcx Substs < ' tcx > )
@@ -352,8 +366,6 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
352366 let def_id = pick. item . def_id ;
353367 let method_predicates = self . tcx . predicates_of ( def_id)
354368 . instantiate ( self . tcx , all_substs) ;
355- let method_predicates = self . normalize_associated_types_in ( self . span ,
356- & method_predicates) ;
357369
358370 debug ! ( "method_predicates after subst = {:?}" , method_predicates) ;
359371
@@ -369,7 +381,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
369381 debug ! ( "late-bound lifetimes from method instantiated, method_sig={:?}" ,
370382 method_sig) ;
371383
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) ;
373385 debug ! ( "type scheme substituted, method_sig={:?}" , method_sig) ;
374386
375387 ( method_sig, method_predicates)
0 commit comments