@@ -95,7 +95,8 @@ use rustc::infer::opaque_types::OpaqueTypeDecl;
95
95
use rustc:: infer:: type_variable:: { TypeVariableOrigin } ;
96
96
use rustc:: middle:: region;
97
97
use 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 } ;
99
100
use rustc:: traits:: { self , ObligationCause , ObligationCauseCode , TraitEngine } ;
100
101
use rustc:: ty:: { self , Ty , TyCtxt , GenericParamDefKind , Visibility , ToPredicate , RegionKind } ;
101
102
use rustc:: ty:: adjustment:: { Adjust , Adjustment , AllowTwoPhase , AutoBorrow , AutoBorrowMutability } ;
@@ -2166,7 +2167,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2166
2167
/// This should be invoked **before any unifications have
2167
2168
/// occurred**, so that annotations like `Vec<_>` are preserved
2168
2169
/// 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
+ ) {
2170
2176
debug ! (
2171
2177
"write_user_substs_from_substs({:?}, {:?}) in fcx {}" ,
2172
2178
hir_id,
@@ -2177,7 +2183,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
2177
2183
if !substs. is_noop ( ) {
2178
2184
let user_substs = self . infcx . canonicalize_response ( & UserSubsts {
2179
2185
substs,
2180
- user_self_ty : None , // TODO -- fix in future commit
2186
+ user_self_ty,
2181
2187
} ) ;
2182
2188
debug ! ( "instantiate_value_path: user_substs = {:?}" , user_substs) ;
2183
2189
self . write_user_substs ( hir_id, user_substs) ;
@@ -3623,7 +3629,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
3623
3629
if let Some ( ( variant, did, substs) ) = variant {
3624
3630
debug ! ( "check_struct_path: did={:?} substs={:?}" , did, substs) ;
3625
3631
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 ) ;
3627
3633
3628
3634
// Check bounds on type arguments used in the path.
3629
3635
let bounds = self . instantiate_bounds ( path_span, did, substs) ;
@@ -5011,7 +5017,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5011
5017
5012
5018
let path_segs = self . def_ids_for_path_segments ( segments, def) ;
5013
5019
5014
- let mut ufcs_associated = None ;
5020
+ let mut user_self_ty = None ;
5015
5021
match def {
5016
5022
Def :: Method ( def_id) |
5017
5023
Def :: AssociatedConst ( def_id) => {
@@ -5020,12 +5026,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5020
5026
ty:: TraitContainer ( trait_did) => {
5021
5027
callee:: check_legal_trait_for_method_call ( self . tcx , span, trait_did)
5022
5028
}
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
+ }
5029
5043
}
5030
5044
}
5031
5045
_ => { }
@@ -5179,6 +5193,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5179
5193
assert ! ( !substs. has_escaping_regions( ) ) ;
5180
5194
assert ! ( !ty. has_escaping_regions( ) ) ;
5181
5195
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
+
5182
5200
// Add all the obligations that are required, substituting and
5183
5201
// normalized appropriately.
5184
5202
let bounds = self . instantiate_bounds ( span, def_id, & substs) ;
@@ -5190,7 +5208,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5190
5208
// the referenced item.
5191
5209
let ty_substituted = self . instantiate_type_scheme ( span, & substs, & ty) ;
5192
5210
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 {
5194
5212
// In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
5195
5213
// is inherent, there is no `Self` parameter, instead, the impl needs
5196
5214
// type parameters, which we can infer by unifying the provided `Self`
@@ -5214,16 +5232,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5214
5232
debug ! ( "instantiate_value_path: type of {:?} is {:?}" ,
5215
5233
node_id,
5216
5234
ty_substituted) ;
5217
- let hir_id = self . tcx . hir . node_to_hir_id ( node_id) ;
5218
5235
self . write_substs ( hir_id, substs) ;
5219
5236
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
-
5227
5237
( ty_substituted, new_def)
5228
5238
}
5229
5239
0 commit comments