Skip to content

Commit 16a3824

Browse files
committed
pass along user_self_ty
1 parent 547182e commit 16a3824

File tree

1 file changed

+30
-20
lines changed
  • src/librustc_typeck/check

1 file changed

+30
-20
lines changed

src/librustc_typeck/check/mod.rs

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ use rustc::infer::opaque_types::OpaqueTypeDecl;
9595
use rustc::infer::type_variable::{TypeVariableOrigin};
9696
use rustc::middle::region;
9797
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};
99100
use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
100101
use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, Visibility, ToPredicate, RegionKind};
101102
use 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

Comments
 (0)