@@ -95,7 +95,8 @@ use rustc::infer::opaque_types::OpaqueTypeDecl;
9595use rustc:: infer:: type_variable:: { TypeVariableOrigin } ;
9696use rustc:: middle:: region;
9797use rustc:: mir:: interpret:: { ConstValue , GlobalId } ;
98- use rustc:: ty:: subst:: { CanonicalUserSubsts , UnpackedKind , Subst , Substs , UserSubsts } ;
98+ use rustc:: ty:: subst:: { CanonicalUserSubsts , UnpackedKind , Subst , Substs ,
99+ UserSelfTy , UserSubsts } ;
99100use rustc:: traits:: { self , ObligationCause , ObligationCauseCode , TraitEngine } ;
100101use rustc:: ty:: { self , Ty , TyCtxt , GenericParamDefKind , Visibility , ToPredicate , RegionKind } ;
101102use rustc:: ty:: adjustment:: { Adjust , Adjustment , AllowTwoPhase , AutoBorrow , AutoBorrowMutability } ;
@@ -2166,7 +2167,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
21662167 /// This should be invoked **before any unifications have
21672168 /// occurred**, so that annotations like `Vec<_>` are preserved
21682169 /// properly.
2169- pub fn write_user_substs_from_substs ( & self , hir_id : hir:: HirId , substs : & ' tcx Substs < ' tcx > ) {
2170+ pub fn write_user_substs_from_substs (
2171+ & self ,
2172+ hir_id : hir:: HirId ,
2173+ substs : & ' tcx Substs < ' tcx > ,
2174+ user_self_ty : Option < UserSelfTy < ' tcx > > ,
2175+ ) {
21702176 debug ! (
21712177 "write_user_substs_from_substs({:?}, {:?}) in fcx {}" ,
21722178 hir_id,
@@ -2177,7 +2183,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
21772183 if !substs. is_noop ( ) {
21782184 let user_substs = self . infcx . canonicalize_response ( & UserSubsts {
21792185 substs,
2180- user_self_ty : None , // TODO -- fix in future commit
2186+ user_self_ty,
21812187 } ) ;
21822188 debug ! ( "instantiate_value_path: user_substs = {:?}" , user_substs) ;
21832189 self . write_user_substs ( hir_id, user_substs) ;
@@ -3623,7 +3629,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
36233629 if let Some ( ( variant, did, substs) ) = variant {
36243630 debug ! ( "check_struct_path: did={:?} substs={:?}" , did, substs) ;
36253631 let hir_id = self . tcx . hir . node_to_hir_id ( node_id) ;
3626- self . write_user_substs_from_substs ( hir_id, substs) ;
3632+ self . write_user_substs_from_substs ( hir_id, substs, None ) ;
36273633
36283634 // Check bounds on type arguments used in the path.
36293635 let bounds = self . instantiate_bounds ( path_span, did, substs) ;
@@ -5011,7 +5017,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
50115017
50125018 let path_segs = self . def_ids_for_path_segments ( segments, def) ;
50135019
5014- let mut ufcs_associated = None ;
5020+ let mut user_self_ty = None ;
50155021 match def {
50165022 Def :: Method ( def_id) |
50175023 Def :: AssociatedConst ( def_id) => {
@@ -5020,12 +5026,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
50205026 ty:: TraitContainer ( trait_did) => {
50215027 callee:: check_legal_trait_for_method_call ( self . tcx , span, trait_did)
50225028 }
5023- ty:: ImplContainer ( _) => { }
5024- }
5025- if segments. len ( ) == 1 {
5026- // `<T>::assoc` will end up here, and so can `T::assoc`.
5027- let self_ty = self_ty. expect ( "UFCS sugared assoc missing Self" ) ;
5028- ufcs_associated = Some ( ( container, self_ty) ) ;
5029+ ty:: ImplContainer ( impl_def_id) => {
5030+ if segments. len ( ) == 1 {
5031+ // `<T>::assoc` will end up here, and so
5032+ // can `T::assoc`. It this came from an
5033+ // inherent impl, we need to record the
5034+ // `T` for posterity (see `UserSelfTy` for
5035+ // details).
5036+ let self_ty = self_ty. expect ( "UFCS sugared assoc missing Self" ) ;
5037+ user_self_ty = Some ( UserSelfTy {
5038+ impl_def_id,
5039+ self_ty,
5040+ } ) ;
5041+ }
5042+ }
50295043 }
50305044 }
50315045 _ => { }
@@ -5179,6 +5193,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
51795193 assert ! ( !substs. has_escaping_regions( ) ) ;
51805194 assert ! ( !ty. has_escaping_regions( ) ) ;
51815195
5196+ // Write the "user substs" down first thing for later.
5197+ let hir_id = self . tcx . hir . node_to_hir_id ( node_id) ;
5198+ self . write_user_substs_from_substs ( hir_id, substs, user_self_ty) ;
5199+
51825200 // Add all the obligations that are required, substituting and
51835201 // normalized appropriately.
51845202 let bounds = self . instantiate_bounds ( span, def_id, & substs) ;
@@ -5190,7 +5208,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
51905208 // the referenced item.
51915209 let ty_substituted = self . instantiate_type_scheme ( span, & substs, & ty) ;
51925210
5193- if let Some ( ( ty :: ImplContainer ( impl_def_id) , self_ty) ) = ufcs_associated {
5211+ if let Some ( UserSelfTy { impl_def_id, self_ty } ) = user_self_ty {
51945212 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
51955213 // is inherent, there is no `Self` parameter, instead, the impl needs
51965214 // type parameters, which we can infer by unifying the provided `Self`
@@ -5214,16 +5232,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
52145232 debug ! ( "instantiate_value_path: type of {:?} is {:?}" ,
52155233 node_id,
52165234 ty_substituted) ;
5217- let hir_id = self . tcx . hir . node_to_hir_id ( node_id) ;
52185235 self . write_substs ( hir_id, substs) ;
52195236
5220- debug ! (
5221- "instantiate_value_path: id={:?} substs={:?}" ,
5222- node_id,
5223- substs,
5224- ) ;
5225- self . write_user_substs_from_substs ( hir_id, substs) ;
5226-
52275237 ( ty_substituted, new_def)
52285238 }
52295239
0 commit comments