diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2018-10-11 20:38:23 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2018-10-15 16:25:08 -0400 |
| commit | 16a382407be00a1a7d3a9f9853378ecf69ff662c (patch) | |
| tree | 2dc27abf92f65a4605a85f9b1a033c4fe1beea18 /src | |
| parent | 547182ea9463cdc4cf72f0af1372f4db17f700e8 (diff) | |
| download | rust-16a382407be00a1a7d3a9f9853378ecf69ff662c.tar.gz rust-16a382407be00a1a7d3a9f9853378ecf69ff662c.zip | |
pass along `user_self_ty`
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 62e4ef0f05c..c472aae4f6b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -95,7 +95,8 @@ use rustc::infer::opaque_types::OpaqueTypeDecl; use rustc::infer::type_variable::{TypeVariableOrigin}; use rustc::middle::region; use rustc::mir::interpret::{ConstValue, GlobalId}; -use rustc::ty::subst::{CanonicalUserSubsts, UnpackedKind, Subst, Substs, UserSubsts}; +use rustc::ty::subst::{CanonicalUserSubsts, UnpackedKind, Subst, Substs, + UserSelfTy, UserSubsts}; use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine}; use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, Visibility, ToPredicate, RegionKind}; use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; @@ -2166,7 +2167,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { /// This should be invoked **before any unifications have /// occurred**, so that annotations like `Vec<_>` are preserved /// properly. - pub fn write_user_substs_from_substs(&self, hir_id: hir::HirId, substs: &'tcx Substs<'tcx>) { + pub fn write_user_substs_from_substs( + &self, + hir_id: hir::HirId, + substs: &'tcx Substs<'tcx>, + user_self_ty: Option<UserSelfTy<'tcx>>, + ) { debug!( "write_user_substs_from_substs({:?}, {:?}) in fcx {}", hir_id, @@ -2177,7 +2183,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if !substs.is_noop() { let user_substs = self.infcx.canonicalize_response(&UserSubsts { substs, - user_self_ty: None, // TODO -- fix in future commit + user_self_ty, }); debug!("instantiate_value_path: user_substs = {:?}", user_substs); self.write_user_substs(hir_id, user_substs); @@ -3623,7 +3629,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some((variant, did, substs)) = variant { debug!("check_struct_path: did={:?} substs={:?}", did, substs); let hir_id = self.tcx.hir.node_to_hir_id(node_id); - self.write_user_substs_from_substs(hir_id, substs); + self.write_user_substs_from_substs(hir_id, substs, None); // Check bounds on type arguments used in the path. let bounds = self.instantiate_bounds(path_span, did, substs); @@ -5011,7 +5017,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let path_segs = self.def_ids_for_path_segments(segments, def); - let mut ufcs_associated = None; + let mut user_self_ty = None; match def { Def::Method(def_id) | Def::AssociatedConst(def_id) => { @@ -5020,12 +5026,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty::TraitContainer(trait_did) => { callee::check_legal_trait_for_method_call(self.tcx, span, trait_did) } - ty::ImplContainer(_) => {} - } - if segments.len() == 1 { - // `<T>::assoc` will end up here, and so can `T::assoc`. - let self_ty = self_ty.expect("UFCS sugared assoc missing Self"); - ufcs_associated = Some((container, self_ty)); + ty::ImplContainer(impl_def_id) => { + if segments.len() == 1 { + // `<T>::assoc` will end up here, and so + // can `T::assoc`. It this came from an + // inherent impl, we need to record the + // `T` for posterity (see `UserSelfTy` for + // details). + let self_ty = self_ty.expect("UFCS sugared assoc missing Self"); + user_self_ty = Some(UserSelfTy { + impl_def_id, + self_ty, + }); + } + } } } _ => {} @@ -5179,6 +5193,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { assert!(!substs.has_escaping_regions()); assert!(!ty.has_escaping_regions()); + // Write the "user substs" down first thing for later. + let hir_id = self.tcx.hir.node_to_hir_id(node_id); + self.write_user_substs_from_substs(hir_id, substs, user_self_ty); + // Add all the obligations that are required, substituting and // normalized appropriately. let bounds = self.instantiate_bounds(span, def_id, &substs); @@ -5190,7 +5208,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // the referenced item. let ty_substituted = self.instantiate_type_scheme(span, &substs, &ty); - if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated { + if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty { // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method` // is inherent, there is no `Self` parameter, instead, the impl needs // type parameters, which we can infer by unifying the provided `Self` @@ -5214,16 +5232,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { debug!("instantiate_value_path: type of {:?} is {:?}", node_id, ty_substituted); - let hir_id = self.tcx.hir.node_to_hir_id(node_id); self.write_substs(hir_id, substs); - debug!( - "instantiate_value_path: id={:?} substs={:?}", - node_id, - substs, - ); - self.write_user_substs_from_substs(hir_id, substs); - (ty_substituted, new_def) } |
