diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 63dc2e2d8e1..2615fdd86d6 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -19,8 +19,6 @@ use std::mem; use syntax_pos::symbol::InternedString; use ty; -impl_stable_hash_for!(struct ty::ItemSubsts<'tcx> { substs }); - impl<'a, 'tcx, T> HashStable> for &'tcx ty::Slice where T: HashStable> { fn hash_stable(&self, @@ -602,7 +600,7 @@ impl<'a, 'tcx> HashStable> for ty::TypeckTables<' let ty::TypeckTables { ref type_relative_path_defs, ref node_types, - ref item_substs, + ref node_substs, ref adjustments, ref method_map, ref upvar_capture_map, @@ -623,7 +621,7 @@ impl<'a, 'tcx> HashStable> for ty::TypeckTables<' hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { ich::hash_stable_nodemap(hcx, hasher, type_relative_path_defs); ich::hash_stable_nodemap(hcx, hasher, node_types); - ich::hash_stable_nodemap(hcx, hasher, item_substs); + ich::hash_stable_nodemap(hcx, hasher, node_substs); ich::hash_stable_nodemap(hcx, hasher, adjustments); ich::hash_stable_nodemap(hcx, hasher, method_map); ich::hash_stable_hashmap(hcx, hasher, upvar_capture_map, |hcx, up_var_id| { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 76882b94315..a0ad3da45e0 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -218,7 +218,7 @@ pub struct TypeckTables<'tcx> { /// of this node. This only applies to nodes that refer to entities /// parameterized by type parameters, such as generic fns, types, or /// other items. - pub item_substs: NodeMap>, + pub node_substs: NodeMap<&'tcx Substs<'tcx>>, pub adjustments: NodeMap>, @@ -273,7 +273,7 @@ impl<'tcx> TypeckTables<'tcx> { TypeckTables { type_relative_path_defs: NodeMap(), node_types: FxHashMap(), - item_substs: NodeMap(), + node_substs: NodeMap(), adjustments: NodeMap(), method_map: FxHashMap(), upvar_capture_map: FxHashMap(), @@ -313,8 +313,8 @@ impl<'tcx> TypeckTables<'tcx> { self.node_types.get(&id).cloned() } - pub fn node_id_item_substs(&self, id: NodeId) -> Option<&'tcx Substs<'tcx>> { - self.item_substs.get(&id).map(|ts| ts.substs) + pub fn node_substs(&self, id: NodeId) -> &'tcx Substs<'tcx> { + self.node_substs.get(&id).cloned().unwrap_or(Substs::empty()) } // Returns the type of a pattern as a monotype. Like @expr_ty, this function diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index d138b306732..a45f85db4c2 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1809,13 +1809,6 @@ impl<'a, 'gcx, 'tcx> FieldDef { } } -/// Records the substitutions used to translate the polytype for an -/// item into the monotype of an item reference. -#[derive(Clone, RustcEncodable, RustcDecodable)] -pub struct ItemSubsts<'tcx> { - pub substs: &'tcx Substs<'tcx>, -} - #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] pub enum ClosureKind { // Warning: Ordering is significant here! The ordering is chosen @@ -1893,12 +1886,6 @@ impl<'tcx> TyS<'tcx> { } } -impl<'tcx> ItemSubsts<'tcx> { - pub fn is_noop(&self) -> bool { - self.substs.is_noop() - } -} - #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum LvaluePreference { PreferMutLvalue, diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 53d516e581b..9336e7beae2 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -220,17 +220,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ClosureSubsts<'a> { } } -impl<'a, 'tcx> Lift<'tcx> for ty::ItemSubsts<'a> { - type Lifted = ty::ItemSubsts<'tcx>; - fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { - tcx.lift(&self.substs).map(|substs| { - ty::ItemSubsts { - substs: substs - } - }) - } -} - impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> { type Lifted = ty::adjustment::AutoBorrow<'tcx>; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option { @@ -654,18 +643,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for ty::ItemSubsts<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - ty::ItemSubsts { - substs: self.substs.fold_with(folder), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.substs.visit_with(visitor) - } -} - impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoBorrow<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { match *self { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 340e4f2cfcc..6f6d48cdf58 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -361,12 +361,6 @@ impl<'tcx> fmt::Display for ty::TypeAndMut<'tcx> { } } -impl<'tcx> fmt::Debug for ty::ItemSubsts<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "ItemSubsts({:?})", self.substs) - } -} - impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // when printing out the debug representation, we don't need diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index e79f23aee11..a6b39f22277 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -286,8 +286,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>, } } hir::ExprPath(ref qpath) => { - let substs = cx.tables.node_id_item_substs(e.id) - .unwrap_or_else(|| tcx.intern_substs(&[])); + let substs = cx.tables.node_substs(e.id); // Avoid applying substitutions if they're empty, that'd ICE. let substs = if cx.substs.is_empty() { diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index e15d63a63c2..d8e76218a4a 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -585,8 +585,7 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> { let kind = match def { Def::Const(def_id) | Def::AssociatedConst(def_id) => { let tcx = self.tcx.global_tcx(); - let substs = self.tables.node_id_item_substs(id) - .unwrap_or_else(|| tcx.intern_substs(&[])); + let substs = self.tables.node_substs(id); match eval::lookup_const_by_id(tcx, def_id, substs) { Some((def_id, _substs)) => { // Enter the inlined constant's tables temporarily. diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 13c69d10530..8a374358bb9 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -911,8 +911,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { }; match def { Def::Method(def_id) => { - let substs = cx.tables.node_id_item_substs(callee.id) - .unwrap_or_else(|| cx.tcx.intern_substs(&[])); + let substs = cx.tables.node_substs(callee.id); method_call_refers_to_method( cx.tcx, method, def_id, substs, id) } diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index eee1f1a9712..c11cd38fe34 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -297,8 +297,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, None }; if let Some((adt_def, index)) = adt_data { - let substs = cx.tables().node_id_item_substs(fun.id) - .unwrap_or_else(|| cx.tcx.intern_substs(&[])); + let substs = cx.tables().node_substs(fun.id); let field_refs = args.iter() .enumerate() .map(|(idx, e)| { @@ -735,8 +734,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, expr: &'tcx hir::Expr, def: Def) -> ExprKind<'tcx> { - let substs = cx.tables().node_id_item_substs(expr.id) - .unwrap_or_else(|| cx.tcx.intern_substs(&[])); + let substs = cx.tables().node_substs(expr.id); match def { // A regular function, constructor function or a constant. Def::Fn(def_id) | diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f8020794b98..0b0233103ef 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -52,7 +52,7 @@ can be broken down into several distinct phases: While type checking a function, the intermediate types for the expressions, blocks, and so forth contained within the function are -stored in `fcx.node_types` and `fcx.item_substs`. These types +stored in `fcx.node_types` and `fcx.node_substs`. These types may contain unresolved type variables. After type checking is complete, the functions in the writeback module are used to take the types from this table, resolve them, and then write them into their @@ -1758,14 +1758,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } - pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) { - if !substs.substs.is_noop() { + pub fn write_substs(&self, node_id: ast::NodeId, substs: &'tcx Substs<'tcx>) { + if !substs.is_noop() { debug!("write_substs({}, {:?}) in fcx {}", node_id, substs, self.tag()); - self.tables.borrow_mut().item_substs.insert(node_id, substs); + self.tables.borrow_mut().node_substs.insert(node_id, substs); } } @@ -1959,16 +1959,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } - pub fn opt_node_ty_substs(&self, - id: ast::NodeId, - f: F) where - F: FnOnce(&ty::ItemSubsts<'tcx>), - { - if let Some(s) = self.tables.borrow().item_substs.get(&id) { - f(s); - } - } - /// Registers an obligation for checking later, during regionck, that the type `ty` must /// outlive the region `r`. pub fn register_region_obligation(&self, @@ -3550,9 +3540,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // We always require that the type provided as the value for // a type parameter outlives the moment of instantiation. - self.opt_node_ty_substs(expr.id, |item_substs| { - self.add_wf_bounds(&item_substs.substs, expr); - }); + let substs = self.tables.borrow().node_substs(expr.id); + self.add_wf_bounds(substs, expr); ty } @@ -4375,9 +4364,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let ty = self.local_ty(span, nid); let ty = self.normalize_associated_types_in(span, &ty); self.write_ty(node_id, ty); - self.write_substs(node_id, ty::ItemSubsts { - substs: self.tcx.intern_substs(&[]) - }); return ty; } _ => {} @@ -4509,9 +4495,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { debug!("instantiate_value_path: type of {:?} is {:?}", node_id, ty_substituted); - self.write_substs(node_id, ty::ItemSubsts { - substs: substs - }); + self.write_substs(node_id, substs); ty_substituted } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 5cda50b428b..2fae9d8e70e 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -608,10 +608,9 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> { expr, self.repeating_scope); match expr.node { hir::ExprPath(_) => { - self.fcx.opt_node_ty_substs(expr.id, |item_substs| { - let origin = infer::ParameterOrigin::Path; - self.substs_wf_in_scope(origin, &item_substs.substs, expr.span, expr_region); - }); + let substs = self.tables.borrow().node_substs(expr.id); + let origin = infer::ParameterOrigin::Path; + self.substs_wf_in_scope(origin, substs, expr.span, expr_region); } hir::ExprCall(ref callee, ref args) => { diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 455a8e1cf16..dcdfed6cbd8 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -295,14 +295,12 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { debug!("Node {} has type {:?}", node_id, n_ty); // Resolve any substitutions - self.fcx.opt_node_ty_substs(node_id, |item_substs| { - let item_substs = self.resolve(item_substs, &span); - if !item_substs.is_noop() { - debug!("write_substs_to_tcx({}, {:?})", node_id, item_substs); - assert!(!item_substs.substs.needs_infer()); - self.tables.item_substs.insert(node_id, item_substs); - } - }); + if let Some(&substs) = self.fcx.tables.borrow().node_substs.get(&node_id) { + let substs = self.resolve(&substs, &span); + debug!("write_substs_to_tcx({}, {:?})", node_id, substs); + assert!(!substs.needs_infer()); + self.tables.node_substs.insert(node_id, substs); + } } fn visit_adjustments(&mut self, span: Span, node_id: ast::NodeId) {