From e6646ef8b0f20e63c6a191c6fb130921e2feaba9 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 22 Dec 2017 16:16:44 +0100 Subject: [PATCH 01/21] Deduplicate instances --- src/librustc/dep_graph/dep_node.rs | 1 + src/librustc/ty/instance.rs | 114 ++++++++++++++++++++- src/librustc/ty/maps/config.rs | 6 ++ src/librustc/ty/maps/mod.rs | 8 ++ src/librustc/ty/maps/plumbing.rs | 1 + src/librustc/ty/mod.rs | 48 +++++++++ src/librustc/ty/util.rs | 4 +- src/librustc_mir/monomorphize/collector.rs | 6 ++ src/librustc_trans/abi.rs | 2 +- src/librustc_trans/base.rs | 2 +- src/librustc_trans/callee.rs | 33 +++++- src/librustc_trans/common.rs | 51 +-------- src/librustc_trans/declare.rs | 2 +- src/librustc_trans/mir/block.rs | 2 +- 14 files changed, 222 insertions(+), 58 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 42cda6a05a1a7..616894f7ebcab 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -640,6 +640,7 @@ define_dep_nodes!( <'tcx> [] NormalizeProjectionTy(CanonicalProjectionGoal<'tcx>), [] NormalizeTyAfterErasingRegions(ParamEnvAnd<'tcx, Ty<'tcx>>), [] DropckOutlives(CanonicalTyGoal<'tcx>), + [] CollapseInterchangableInstances { instance: Instance<'tcx> }, [] SubstituteNormalizeAndTestPredicates { key: (DefId, &'tcx Substs<'tcx>) }, diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 76f7a0b59a2a5..e0683beedab1f 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -8,9 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use rustc_data_structures::indexed_vec::IndexVec; + use hir::def_id::DefId; -use ty::{self, Ty, TypeFoldable, Substs, TyCtxt}; -use ty::subst::Kind; +use ty::{self, TyCtxt, Ty, TypeFoldable, Substs, ParamTy}; +use ty::subst::{Kind, UnpackedKind}; +use ty::fold::TypeFolder; +use mir::visit::{Visitor, TyContext}; use traits; use syntax::abi::Abi; use util::ppaux; @@ -243,6 +247,112 @@ impl<'a, 'b, 'tcx> Instance<'tcx> { _ => Instance::new(def_id, substs.substs) } } + + /// Replace substs which arent used by the function with TyError, + /// so that it doesnt end up in the binary multiple times + pub(in ty) fn _collapse_interchangable_instances(mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Instance<'tcx> { + use ty::subst::Kind; + info!("replace_unused_substs_with_ty_error({:?})", self); + + if self.substs.is_noop() || !tcx.is_mir_available(self.def_id()) { + return self; + } + match self.ty(tcx).sty { + ty::TyFnDef(_def_id, _) => { + // TODO: is fn a lang_item? + } + _ => return self, + } + + let used_substs = used_substs_for_instance(tcx, self); + self.substs = tcx._intern_substs(&self.substs.into_iter().enumerate().map(|(i, subst)| { + if let UnpackedKind::Type(ty) = subst.unpack() { + let ty = if used_substs.substs.iter().find(|p|p.idx == i as u32).is_some() { + ty.into() + } else if let ty::TyParam(ref _param) = ty.sty { // Dont replace and other internal params + if false /*param.name.as_str().starts_with("<")*/ { + ty.into() + } else { + tcx.mk_ty(ty::TyNever) + } + } else { + tcx.mk_ty(ty::TyNever) // Can't use TyError as it gives some ICE in rustc_trans::callee::get_fn + }; + Kind::from(ty) + } else { + (*subst).clone() + } + }).collect::>()); + info!("replace_unused_substs_with_ty_error(_) -> {:?}", self); + self + } +} + +#[derive(Debug, Default, Clone)] +pub struct UsedSubsts { + pub substs: Vec, + pub promoted: IndexVec<::mir::Promoted, UsedSubsts>, +} + +impl_stable_hash_for! { struct UsedSubsts { substs, promoted } } + +fn used_substs_for_instance<'a, 'tcx: 'a>(tcx: TyCtxt<'a ,'tcx, 'tcx>, instance: Instance<'tcx>) -> UsedSubsts { + struct SubstsVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a>(TyCtxt<'a, 'gcx, 'tcx>, UsedSubsts); + + impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> Visitor<'tcx> for SubstsVisitor<'a, 'gcx, 'tcx> { + fn visit_ty(&mut self, ty: &Ty<'tcx>, _: TyContext) { + self.fold_ty(ty); + } + } + + impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for SubstsVisitor<'a, 'gcx, 'tcx> { + fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { + self.0 + } + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + if !ty.needs_subst() { + return ty; + } + match ty.sty { + ty::TyParam(param) => { + self.1.substs.push(param); + ty + } + ty::TyFnDef(_, substs) => { + for subst in substs { + if let UnpackedKind::Type(ty) = subst.unpack() { + ty.fold_with(self); + } + } + ty.super_fold_with(self) + } + ty::TyClosure(_, closure_substs) => { + for subst in closure_substs.substs { + if let UnpackedKind::Type(ty) = subst.unpack() { + ty.fold_with(self); + } + } + ty.super_fold_with(self) + } + _ => ty.super_fold_with(self) + } + } + } + + let mir = tcx.instance_mir(instance.def); + let sig = ::ty::ty_fn_sig(tcx, instance.ty(tcx)); + let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); + + let mut substs_visitor = SubstsVisitor(tcx, UsedSubsts::default()); + substs_visitor.visit_mir(mir); + for ty in sig.inputs().iter() { + ty.fold_with(&mut substs_visitor); + } + sig.output().fold_with(&mut substs_visitor); + let mut used_substs = substs_visitor.1; + used_substs.substs.sort_by_key(|s|s.idx); + used_substs.substs.dedup_by_key(|s|s.idx); + used_substs } fn resolve_associated_item<'a, 'tcx>( diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index bb9467305e335..7be145001bc99 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -639,6 +639,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::typeck_tables_of<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::collapse_interchangable_instances<'tcx> { + fn describe(_tcx: TyCtxt, instance: ty::Instance<'tcx>) -> String { + format!("collapse interchangable instance {:?}", instance) + } +} + impl<'tcx> QueryDescription<'tcx> for queries::optimized_mir<'tcx> { #[inline] fn cache_on_disk(def_id: Self::Key) -> bool { diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 2bfb687032923..96cb366fac247 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -430,6 +430,8 @@ define_maps! { <'tcx> [] fn wasm_custom_sections: WasmCustomSections(CrateNum) -> Lrc>, [] fn wasm_import_module_map: WasmImportModuleMap(CrateNum) -> Lrc>, + + [] fn collapse_interchangable_instances: collapse_interchangable_instances_dep_node(ty::Instance<'tcx>) -> ty::Instance<'tcx>, } ////////////////////////////////////////////////////////////////////// @@ -592,3 +594,9 @@ fn instance_def_size_estimate_dep_node<'tcx>(instance_def: ty::InstanceDef<'tcx> instance_def } } + +fn collapse_interchangable_instances_dep_node<'tcx>(instance: ty::Instance<'tcx>) -> DepConstructor<'tcx> { + DepConstructor::CollapseInterchangableInstances { + instance, + } +} diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 50a19526ba8c4..9ffceabf5759d 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -777,6 +777,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::DropckOutlives | DepKind::SubstituteNormalizeAndTestPredicates | DepKind::InstanceDefSizeEstimate | + DepKind::CollapseInterchangableInstances | // This one should never occur in this context DepKind::Null => { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 72ba199eb2412..762f874656617 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -43,11 +43,13 @@ use std::cell::RefCell; use std::cmp; use std::fmt; use std::hash::{Hash, Hasher}; +use std::iter; use std::ops::Deref; use rustc_data_structures::sync::Lrc; use std::slice; use std::vec::IntoIter; use std::mem; +use syntax::abi::Abi; use syntax::ast::{self, DUMMY_NODE_ID, Name, Ident, NodeId}; use syntax::attr; use syntax::ext::hygiene::{Mark, SyntaxContext}; @@ -2761,6 +2763,7 @@ pub fn provide(providers: &mut ty::maps::Providers) { crate_hash, trait_impls_of: trait_def::trait_impls_of_provider, instance_def_size_estimate, + collapse_interchangable_instances: |tcx, instance| instance._collapse_interchangable_instances(tcx), ..*providers }; } @@ -2811,3 +2814,48 @@ impl fmt::Debug for SymbolName { fmt::Display::fmt(&self.name, fmt) } } + +pub fn ty_fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + ty: Ty<'tcx>) + -> ty::PolyFnSig<'tcx> +{ + match ty.sty { + ty::TyFnDef(..) | + // Shims currently have type TyFnPtr. Not sure this should remain. + ty::TyFnPtr(_) => ty.fn_sig(tcx), + ty::TyClosure(def_id, substs) => { + let sig = substs.closure_sig(def_id, tcx); + + let env_ty = tcx.closure_env_ty(def_id, substs).unwrap(); + sig.map_bound(|sig| tcx.mk_fn_sig( + iter::once(*env_ty.skip_binder()).chain(sig.inputs().iter().cloned()), + sig.output(), + sig.variadic, + sig.unsafety, + sig.abi + )) + } + ty::TyGenerator(def_id, substs, _) => { + let sig = substs.generator_poly_sig(def_id, tcx); + + let env_region = ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrEnv); + let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty); + + sig.map_bound(|sig| { + let state_did = tcx.lang_items().gen_state().unwrap(); + let state_adt_ref = tcx.adt_def(state_did); + let state_substs = tcx.mk_substs([sig.yield_ty.into(), + sig.return_ty.into()].iter()); + let ret_ty = tcx.mk_adt(state_adt_ref, state_substs); + + tcx.mk_fn_sig(iter::once(env_ty), + ret_ty, + false, + hir::Unsafety::Normal, + Abi::Rust + ) + }) + } + _ => bug!("unexpected type {:?} to ty_fn_sig", ty) + } +} diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index afe977d10baac..40997c4e0ba55 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -733,7 +733,9 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W> TyStr | TySlice(_) => {} - TyError | + // This can be generated by collapse_interchangable_instances + TyError => self.hash(""), + TyInfer(_) => bug!("TypeIdHasher: unexpected type {}", ty) } diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 446ef6bd32876..4b4e51c867089 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -315,6 +315,8 @@ pub fn collect_crate_mono_items<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, &mut inlining_map); } + tcx.sess.warn(&format!("{:#?}", visited)); + (visited, inlining_map) } @@ -374,6 +376,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Sanity check whether this ended up being collected accidentally debug_assert!(should_monomorphize_locally(tcx, &instance)); + let instance = tcx.collapse_interchangable_instances(instance); let ty = instance.ty(tcx); visit_drop_use(tcx, ty, true, &mut neighbors); @@ -397,6 +400,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, MonoItem::Fn(instance) => { // Sanity check whether this ended up being collected accidentally debug_assert!(should_monomorphize_locally(tcx, &instance)); + let instance = tcx.collapse_interchangable_instances(instance); // Keep track of the monomorphization recursion depth recursion_depth_reset = Some(check_recursion_limit(tcx, @@ -692,6 +696,8 @@ fn visit_instance_use<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, return } + let instance = tcx.collapse_interchangable_instances(instance); + match instance.def { ty::InstanceDef::Intrinsic(def_id) => { if !is_direct_call { diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index 19ae1fa0478ea..d0aa9cff84fc0 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -650,7 +650,7 @@ impl<'a, 'tcx> FnType<'tcx> { pub fn of_instance(cx: &CodegenCx<'a, 'tcx>, instance: &ty::Instance<'tcx>) -> Self { let fn_ty = instance.ty(cx.tcx); - let sig = ty_fn_sig(cx, fn_ty); + let sig = ty_fn_sig(cx.tcx, fn_ty); let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); FnType::new(cx, sig, &[]) } diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 3ab33c4134697..320050b42860b 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -464,7 +464,7 @@ pub fn trans_instance<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, instance: Instance<'tc info!("trans_instance({})", instance); let fn_ty = instance.ty(cx.tcx); - let sig = common::ty_fn_sig(cx, fn_ty); + let sig = common::ty_fn_sig(cx.tcx, fn_ty); let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); let lldecl = match cx.instances.borrow().get(&instance) { diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index 1dcf349e23bd8..327a49c386b93 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -43,6 +43,37 @@ pub fn get_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, debug!("get_fn(instance={:?})", instance); + let instance = tcx.collapse_interchangable_instances(instance); + + info!("get_fn(collapsed_instance={:?})", instance); + + struct ShowOnPanic(String); + impl Drop for ShowOnPanic { + fn drop(&mut self) { + if ::std::thread::panicking() { + info!("{}", self.0); + } + } + } + let mut mir = Vec::new(); + if !instance.substs.is_noop() { + //::rustc_mir::util::write_mir_pretty(tcx, Some(instance.def_id()), &mut mir).unwrap(); + } else { + use std::io::Write; + write!(mir, "no substs for instance").unwrap(); + } + let generics = tcx.generics_of(instance.def_id()); + + let _d = ShowOnPanic("mir: ".to_string() + &String::from_utf8(mir).unwrap()); + let _c = if let Some(parent) = generics.parent { + let parent_generics = tcx.generics_of(parent); + ShowOnPanic(format!("parent generics: {:#?}", parent_generics)) + } else { + ShowOnPanic("no parent generics".to_string()) + }; + let _b = ShowOnPanic(format!("generics: {:#?}", generics)); + let _a = ShowOnPanic(format!("instance: {:#?}", instance)); + assert!(!instance.substs.needs_infer()); assert!(!instance.substs.has_escaping_regions()); assert!(!instance.substs.has_param_types()); @@ -56,7 +87,7 @@ pub fn get_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, debug!("get_fn({:?}: {:?}) => {}", instance, fn_ty, sym); // Create a fn pointer with the substituted signature. - let fn_ptr_ty = tcx.mk_fn_ptr(common::ty_fn_sig(cx, fn_ty)); + let fn_ptr_ty = tcx.mk_fn_ptr(common::ty_fn_sig(cx.tcx, fn_ty)); let llptrty = cx.layout_of(fn_ptr_ty).llvm_type(cx); let llfn = if let Some(llfn) = declare::get_declared_value(cx, &sym) { diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index e83e73c8ae757..46946ace25dbd 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -30,13 +30,12 @@ use rustc::ty::layout::{HasDataLayout, LayoutOf}; use rustc::hir; use libc::{c_uint, c_char}; -use std::iter; -use syntax::abi::Abi; use syntax::symbol::InternedString; use syntax_pos::{Span, DUMMY_SP}; pub use context::CodegenCx; +pub use rustc::ty::ty_fn_sig; pub fn type_needs_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool { ty.needs_drop(tcx, ty::ParamEnv::reveal_all()) @@ -399,51 +398,3 @@ pub fn shift_mask_val<'a, 'tcx>( _ => bug!("shift_mask_val: expected Integer or Vector, found {:?}", kind), } } - -pub fn ty_fn_sig<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - ty: Ty<'tcx>) - -> ty::PolyFnSig<'tcx> -{ - match ty.sty { - ty::TyFnDef(..) | - // Shims currently have type TyFnPtr. Not sure this should remain. - ty::TyFnPtr(_) => ty.fn_sig(cx.tcx), - ty::TyClosure(def_id, substs) => { - let tcx = cx.tcx; - let sig = substs.closure_sig(def_id, tcx); - - let env_ty = tcx.closure_env_ty(def_id, substs).unwrap(); - sig.map_bound(|sig| tcx.mk_fn_sig( - iter::once(*env_ty.skip_binder()).chain(sig.inputs().iter().cloned()), - sig.output(), - sig.variadic, - sig.unsafety, - sig.abi - )) - } - ty::TyGenerator(def_id, substs, _) => { - let tcx = cx.tcx; - let sig = substs.generator_poly_sig(def_id, cx.tcx); - - let env_region = ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrEnv); - let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty); - - sig.map_bound(|sig| { - let state_did = tcx.lang_items().gen_state().unwrap(); - let state_adt_ref = tcx.adt_def(state_did); - let state_substs = tcx.mk_substs([sig.yield_ty.into(), - sig.return_ty.into()].iter()); - let ret_ty = tcx.mk_adt(state_adt_ref, state_substs); - - tcx.mk_fn_sig(iter::once(env_ty), - ret_ty, - false, - hir::Unsafety::Normal, - Abi::Rust - ) - }) - } - _ => bug!("unexpected type {:?} to ty_fn_sig", ty) - } -} - diff --git a/src/librustc_trans/declare.rs b/src/librustc_trans/declare.rs index c2010feb1b638..7c111ef513a64 100644 --- a/src/librustc_trans/declare.rs +++ b/src/librustc_trans/declare.rs @@ -126,7 +126,7 @@ pub fn declare_cfn(cx: &CodegenCx, name: &str, fn_type: Type) -> ValueRef { pub fn declare_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, name: &str, fn_type: Ty<'tcx>) -> ValueRef { debug!("declare_rust_fn(name={:?}, fn_type={:?})", name, fn_type); - let sig = common::ty_fn_sig(cx, fn_type); + let sig = common::ty_fn_sig(cx.tcx, fn_type); let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); debug!("declare_rust_fn (after region erasure) sig={:?}", sig); diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index 93bc89f0914f5..15fbf8fc69fe9 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -280,7 +280,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { let (drop_fn, fn_ty) = match ty.sty { ty::TyDynamic(..) => { let fn_ty = drop_fn.ty(bx.cx.tcx); - let sig = common::ty_fn_sig(bx.cx, fn_ty); + let sig = common::ty_fn_sig(bx.cx.tcx, fn_ty); let sig = bx.tcx().normalize_erasing_late_bound_regions( ty::ParamEnv::reveal_all(), &sig, From 5963148080b25bf0880e9748af55c8efbffd7811 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 22 Dec 2017 18:12:05 +0100 Subject: [PATCH 02/21] Ignore lang items --- src/librustc/ty/instance.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index e0683beedab1f..1a76ab9c9ff01 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -258,10 +258,15 @@ impl<'a, 'b, 'tcx> Instance<'tcx> { return self; } match self.ty(tcx).sty { - ty::TyFnDef(_def_id, _) => { - // TODO: is fn a lang_item? + ty::TyFnDef(def_id, _) => { + let attrs = tcx.item_attrs(def_id); + if attrs.iter().find(|attr| { + attr.name().map(|n|n.as_str() == "lang").unwrap_or(false) + }).is_some() { + return self; // Lang items dont work otherwise + } } - _ => return self, + _ => return self, // Closures dont work otherwise } let used_substs = used_substs_for_instance(tcx, self); From bc3b33c8ddaba384d6ec22d0382464954c04f805 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 23 Dec 2017 18:52:44 +0100 Subject: [PATCH 03/21] Really ignore lang items --- src/librustc/ty/instance.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 1a76ab9c9ff01..4a952ff301d41 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -259,10 +259,8 @@ impl<'a, 'b, 'tcx> Instance<'tcx> { } match self.ty(tcx).sty { ty::TyFnDef(def_id, _) => { - let attrs = tcx.item_attrs(def_id); - if attrs.iter().find(|attr| { - attr.name().map(|n|n.as_str() == "lang").unwrap_or(false) - }).is_some() { + //let attrs = tcx.item_attrs(def_id); + if tcx.lang_items().items().iter().find(|l|**l == Some(def_id)).is_some() { return self; // Lang items dont work otherwise } } From 6659fec26ac642d982f9cdaaa8974a2860e700fe Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 10 Feb 2018 11:06:56 +0100 Subject: [PATCH 04/21] Remove debug message --- src/librustc_mir/monomorphize/collector.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 4b4e51c867089..4ec9dce36e25d 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -315,7 +315,7 @@ pub fn collect_crate_mono_items<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, &mut inlining_map); } - tcx.sess.warn(&format!("{:#?}", visited)); + //tcx.sess.warn(&format!("{:#?}", visited)); (visited, inlining_map) } From ee83a7c43e7f6d05827c4eecb7f0383d85668a69 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 10 Feb 2018 12:29:47 +0100 Subject: [PATCH 05/21] Move collapse_interchangable_instances to src/librustc_mir --- src/librustc/ty/instance.rs | 117 +----------------- src/librustc/ty/mod.rs | 1 - src/librustc_mir/lib.rs | 2 + .../monomorphize/deduplicate_instances.rs | 113 +++++++++++++++++ src/librustc_mir/monomorphize/mod.rs | 1 + 5 files changed, 118 insertions(+), 116 deletions(-) create mode 100644 src/librustc_mir/monomorphize/deduplicate_instances.rs diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 4a952ff301d41..f68985832757a 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -8,13 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc_data_structures::indexed_vec::IndexVec; - use hir::def_id::DefId; -use ty::{self, TyCtxt, Ty, TypeFoldable, Substs, ParamTy}; -use ty::subst::{Kind, UnpackedKind}; -use ty::fold::TypeFolder; -use mir::visit::{Visitor, TyContext}; +use ty::{self, TyCtxt, Ty, TypeFoldable, Substs}; +use ty::subst::Kind; use traits; use syntax::abi::Abi; use util::ppaux; @@ -247,115 +243,6 @@ impl<'a, 'b, 'tcx> Instance<'tcx> { _ => Instance::new(def_id, substs.substs) } } - - /// Replace substs which arent used by the function with TyError, - /// so that it doesnt end up in the binary multiple times - pub(in ty) fn _collapse_interchangable_instances(mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Instance<'tcx> { - use ty::subst::Kind; - info!("replace_unused_substs_with_ty_error({:?})", self); - - if self.substs.is_noop() || !tcx.is_mir_available(self.def_id()) { - return self; - } - match self.ty(tcx).sty { - ty::TyFnDef(def_id, _) => { - //let attrs = tcx.item_attrs(def_id); - if tcx.lang_items().items().iter().find(|l|**l == Some(def_id)).is_some() { - return self; // Lang items dont work otherwise - } - } - _ => return self, // Closures dont work otherwise - } - - let used_substs = used_substs_for_instance(tcx, self); - self.substs = tcx._intern_substs(&self.substs.into_iter().enumerate().map(|(i, subst)| { - if let UnpackedKind::Type(ty) = subst.unpack() { - let ty = if used_substs.substs.iter().find(|p|p.idx == i as u32).is_some() { - ty.into() - } else if let ty::TyParam(ref _param) = ty.sty { // Dont replace and other internal params - if false /*param.name.as_str().starts_with("<")*/ { - ty.into() - } else { - tcx.mk_ty(ty::TyNever) - } - } else { - tcx.mk_ty(ty::TyNever) // Can't use TyError as it gives some ICE in rustc_trans::callee::get_fn - }; - Kind::from(ty) - } else { - (*subst).clone() - } - }).collect::>()); - info!("replace_unused_substs_with_ty_error(_) -> {:?}", self); - self - } -} - -#[derive(Debug, Default, Clone)] -pub struct UsedSubsts { - pub substs: Vec, - pub promoted: IndexVec<::mir::Promoted, UsedSubsts>, -} - -impl_stable_hash_for! { struct UsedSubsts { substs, promoted } } - -fn used_substs_for_instance<'a, 'tcx: 'a>(tcx: TyCtxt<'a ,'tcx, 'tcx>, instance: Instance<'tcx>) -> UsedSubsts { - struct SubstsVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a>(TyCtxt<'a, 'gcx, 'tcx>, UsedSubsts); - - impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> Visitor<'tcx> for SubstsVisitor<'a, 'gcx, 'tcx> { - fn visit_ty(&mut self, ty: &Ty<'tcx>, _: TyContext) { - self.fold_ty(ty); - } - } - - impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for SubstsVisitor<'a, 'gcx, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { - self.0 - } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if !ty.needs_subst() { - return ty; - } - match ty.sty { - ty::TyParam(param) => { - self.1.substs.push(param); - ty - } - ty::TyFnDef(_, substs) => { - for subst in substs { - if let UnpackedKind::Type(ty) = subst.unpack() { - ty.fold_with(self); - } - } - ty.super_fold_with(self) - } - ty::TyClosure(_, closure_substs) => { - for subst in closure_substs.substs { - if let UnpackedKind::Type(ty) = subst.unpack() { - ty.fold_with(self); - } - } - ty.super_fold_with(self) - } - _ => ty.super_fold_with(self) - } - } - } - - let mir = tcx.instance_mir(instance.def); - let sig = ::ty::ty_fn_sig(tcx, instance.ty(tcx)); - let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); - - let mut substs_visitor = SubstsVisitor(tcx, UsedSubsts::default()); - substs_visitor.visit_mir(mir); - for ty in sig.inputs().iter() { - ty.fold_with(&mut substs_visitor); - } - sig.output().fold_with(&mut substs_visitor); - let mut used_substs = substs_visitor.1; - used_substs.substs.sort_by_key(|s|s.idx); - used_substs.substs.dedup_by_key(|s|s.idx); - used_substs } fn resolve_associated_item<'a, 'tcx>( diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 762f874656617..66ec871fcb950 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2763,7 +2763,6 @@ pub fn provide(providers: &mut ty::maps::Providers) { crate_hash, trait_impls_of: trait_def::trait_impls_of_provider, instance_def_size_estimate, - collapse_interchangable_instances: |tcx, instance| instance._collapse_interchangable_instances(tcx), ..*providers }; } diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 7af3a397666e8..b814bc7246e40 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -31,6 +31,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(macro_vis_matcher)] #![cfg_attr(stage0, feature(match_default_bindings))] +#![feature(macro_lifetime_matcher)] #![feature(exhaustive_patterns)] #![feature(range_contains)] #![feature(rustc_diagnostic_macros)] @@ -82,6 +83,7 @@ pub fn provide(providers: &mut Providers) { transform::provide(providers); providers.const_eval = interpret::const_eval_provider; providers.check_match = hair::pattern::check_match; + providers.collapse_interchangable_instances = monomorphize::deduplicate_instances::collapse_interchangable_instances; } __build_diagnostic_array! { librustc_mir, DIAGNOSTICS } diff --git a/src/librustc_mir/monomorphize/deduplicate_instances.rs b/src/librustc_mir/monomorphize/deduplicate_instances.rs new file mode 100644 index 0000000000000..d59dbbae04bdb --- /dev/null +++ b/src/librustc_mir/monomorphize/deduplicate_instances.rs @@ -0,0 +1,113 @@ +use rustc_data_structures::indexed_vec::IndexVec; +use rustc::ty::{self, TyCtxt, Ty, TypeFoldable, Instance, ParamTy}; +use rustc::ty::fold::TypeFolder; +use rustc::ty::subst::{Kind, UnpackedKind}; +use rustc::mir::Promoted; +use rustc::mir::visit::{Visitor, TyContext}; + +/// Replace substs which arent used by the function with TyError, +/// so that it doesnt end up in the binary multiple times +pub(crate) fn collapse_interchangable_instances<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mut inst: Instance<'tcx>) -> Instance<'tcx> { + info!("replace_unused_substs_with_ty_error({:?})", inst); + + if inst.substs.is_noop() || !tcx.is_mir_available(inst.def_id()) { + return inst; + } + match inst.ty(tcx).sty { + ty::TyFnDef(def_id, _) => { + //let attrs = tcx.item_attrs(def_id); + if tcx.lang_items().items().iter().find(|l|**l == Some(def_id)).is_some() { + return inst; // Lang items dont work otherwise + } + } + _ => return inst, // Closures dont work otherwise + } + + let used_substs = used_substs_for_instance(tcx, inst); + inst.substs = tcx._intern_substs(&inst.substs.into_iter().enumerate().map(|(i, subst)| { + if let UnpackedKind::Type(ty) = subst.unpack() { + let ty = if used_substs.substs.iter().find(|p|p.idx == i as u32).is_some() { + ty.into() + } else if let ty::TyParam(ref _param) = ty.sty { // Dont replace and other internal params + if false /*param.name.as_str().starts_with("<")*/ { + ty.into() + } else { + tcx.mk_ty(ty::TyNever) + } + } else { + tcx.mk_ty(ty::TyNever) // Can't use TyError as it gives some ICE in rustc_trans::callee::get_fn + }; + Kind::from(ty) + } else { + (*subst).clone() + } + }).collect::>()); + info!("replace_unused_substs_with_ty_error(_) -> {:?}", inst); + inst +} + +#[derive(Debug, Default, Clone)] +pub struct UsedSubsts { + pub substs: Vec, + pub promoted: IndexVec, +} + +impl_stable_hash_for! { struct UsedSubsts { substs, promoted } } + +fn used_substs_for_instance<'a, 'tcx: 'a>(tcx: TyCtxt<'a ,'tcx, 'tcx>, instance: Instance<'tcx>) -> UsedSubsts { + struct SubstsVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a>(TyCtxt<'a, 'gcx, 'tcx>, UsedSubsts); + + impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> Visitor<'tcx> for SubstsVisitor<'a, 'gcx, 'tcx> { + fn visit_ty(&mut self, ty: &Ty<'tcx>, _: TyContext) { + self.fold_ty(ty); + } + } + + impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for SubstsVisitor<'a, 'gcx, 'tcx> { + fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { + self.0 + } + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + if !ty.needs_subst() { + return ty; + } + match ty.sty { + ty::TyParam(param) => { + self.1.substs.push(param); + ty + } + ty::TyFnDef(_, substs) => { + for subst in substs { + if let UnpackedKind::Type(ty) = subst.unpack() { + ty.fold_with(self); + } + } + ty.super_fold_with(self) + } + ty::TyClosure(_, closure_substs) => { + for subst in closure_substs.substs { + if let UnpackedKind::Type(ty) = subst.unpack() { + ty.fold_with(self); + } + } + ty.super_fold_with(self) + } + _ => ty.super_fold_with(self) + } + } + } + + let mir = tcx.instance_mir(instance.def); + let sig = ::rustc::ty::ty_fn_sig(tcx, instance.ty(tcx)); + let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); + let mut substs_visitor = SubstsVisitor(tcx, UsedSubsts::default()); + substs_visitor.visit_mir(mir); + for ty in sig.inputs().iter() { + ty.fold_with(&mut substs_visitor); + } + sig.output().fold_with(&mut substs_visitor); + let mut used_substs = substs_visitor.1; + used_substs.substs.sort_by_key(|s|s.idx); + used_substs.substs.dedup_by_key(|s|s.idx); + used_substs +} diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs index 5c38735d92034..2ca0e52ea2f1d 100644 --- a/src/librustc_mir/monomorphize/mod.rs +++ b/src/librustc_mir/monomorphize/mod.rs @@ -21,6 +21,7 @@ pub use self::item::{MonoItem, MonoItemExt}; pub mod collector; pub mod item; pub mod partitioning; +pub mod deduplicate_instances; #[inline(never)] // give this a place in the profiler pub fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trans_items: I) From 60cc1c4340b0067814201a0e30c52f97639916e6 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 10 Feb 2018 16:31:21 +0100 Subject: [PATCH 06/21] Fix it --- src/librustc/ty/maps/mod.rs | 7 +- src/librustc_mir/lib.rs | 3 +- src/librustc_mir/monomorphize/collector.rs | 1 + .../monomorphize/deduplicate_instances.rs | 115 ++++++++++++------ 4 files changed, 88 insertions(+), 38 deletions(-) diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 96cb366fac247..35307571d3f10 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -431,7 +431,8 @@ define_maps! { <'tcx> [] fn wasm_import_module_map: WasmImportModuleMap(CrateNum) -> Lrc>, - [] fn collapse_interchangable_instances: collapse_interchangable_instances_dep_node(ty::Instance<'tcx>) -> ty::Instance<'tcx>, + [] fn collapse_interchangable_instances: + collapse_interchangable_instances_dep_node(ty::Instance<'tcx>) -> ty::Instance<'tcx>, } ////////////////////////////////////////////////////////////////////// @@ -595,7 +596,9 @@ fn instance_def_size_estimate_dep_node<'tcx>(instance_def: ty::InstanceDef<'tcx> } } -fn collapse_interchangable_instances_dep_node<'tcx>(instance: ty::Instance<'tcx>) -> DepConstructor<'tcx> { +fn collapse_interchangable_instances_dep_node<'tcx>( + instance: ty::Instance<'tcx> +) -> DepConstructor<'tcx> { DepConstructor::CollapseInterchangableInstances { instance, } diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index b814bc7246e40..ae5202fe630fd 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -83,7 +83,8 @@ pub fn provide(providers: &mut Providers) { transform::provide(providers); providers.const_eval = interpret::const_eval_provider; providers.check_match = hair::pattern::check_match; - providers.collapse_interchangable_instances = monomorphize::deduplicate_instances::collapse_interchangable_instances; + providers.collapse_interchangable_instances = + monomorphize::deduplicate_instances::collapse_interchangable_instances; } __build_diagnostic_array! { librustc_mir, DIAGNOSTICS } diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 4ec9dce36e25d..028ca3cd2d443 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -889,6 +889,7 @@ fn create_mono_items_for_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty::ParamEnv::reveal_all(), def_id, substs).unwrap()) + .map(|instance|tcx.collapse_interchangable_instances(instance)) .filter(|&instance| should_monomorphize_locally(tcx, &instance)) .map(|instance| create_fn_mono_item(instance)); output.extend(methods); diff --git a/src/librustc_mir/monomorphize/deduplicate_instances.rs b/src/librustc_mir/monomorphize/deduplicate_instances.rs index d59dbbae04bdb..7546d7baca0da 100644 --- a/src/librustc_mir/monomorphize/deduplicate_instances.rs +++ b/src/librustc_mir/monomorphize/deduplicate_instances.rs @@ -1,13 +1,27 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + use rustc_data_structures::indexed_vec::IndexVec; use rustc::ty::{self, TyCtxt, Ty, TypeFoldable, Instance, ParamTy}; use rustc::ty::fold::TypeFolder; use rustc::ty::subst::{Kind, UnpackedKind}; -use rustc::mir::Promoted; +use rustc::middle::const_val::ConstVal; +use rustc::mir::{Mir, Rvalue, Promoted, Location}; use rustc::mir::visit::{Visitor, TyContext}; /// Replace substs which arent used by the function with TyError, /// so that it doesnt end up in the binary multiple times -pub(crate) fn collapse_interchangable_instances<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mut inst: Instance<'tcx>) -> Instance<'tcx> { +pub(crate) fn collapse_interchangable_instances<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + mut inst: Instance<'tcx> +) -> Instance<'tcx> { info!("replace_unused_substs_with_ty_error({:?})", inst); if inst.substs.is_noop() || !tcx.is_mir_available(inst.def_id()) { @@ -28,14 +42,16 @@ pub(crate) fn collapse_interchangable_instances<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, if let UnpackedKind::Type(ty) = subst.unpack() { let ty = if used_substs.substs.iter().find(|p|p.idx == i as u32).is_some() { ty.into() - } else if let ty::TyParam(ref _param) = ty.sty { // Dont replace and other internal params + } else if let ty::TyParam(ref _param) = ty.sty { + //^ Dont replace and other internal params if false /*param.name.as_str().starts_with("<")*/ { ty.into() } else { tcx.mk_ty(ty::TyNever) } } else { - tcx.mk_ty(ty::TyNever) // Can't use TyError as it gives some ICE in rustc_trans::callee::get_fn + // Can't use TyError as it gives some ICE in rustc_trans::callee::get_fn + tcx.mk_ty(ty::TyNever) }; Kind::from(ty) } else { @@ -54,59 +70,88 @@ pub struct UsedSubsts { impl_stable_hash_for! { struct UsedSubsts { substs, promoted } } -fn used_substs_for_instance<'a, 'tcx: 'a>(tcx: TyCtxt<'a ,'tcx, 'tcx>, instance: Instance<'tcx>) -> UsedSubsts { - struct SubstsVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a>(TyCtxt<'a, 'gcx, 'tcx>, UsedSubsts); +struct SubstsVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a>( + TyCtxt<'a, 'gcx, 'tcx>, + &'tcx Mir<'tcx>, + UsedSubsts +); + +impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> Visitor<'tcx> for SubstsVisitor<'a, 'gcx, 'tcx> { + fn visit_ty(&mut self, ty: &Ty<'tcx>, _: TyContext) { + self.fold_ty(ty); + } + + fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, _location: Location) { + if let ConstVal::Unevaluated(_def_id, substs) = constant.val { + for subst in substs { + if let UnpackedKind::Type(ty) = subst.unpack() { + ty.fold_with(self); + } + } + } + } - impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> Visitor<'tcx> for SubstsVisitor<'a, 'gcx, 'tcx> { - fn visit_ty(&mut self, ty: &Ty<'tcx>, _: TyContext) { - self.fold_ty(ty); + fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { + let tcx = self.0; + match *rvalue { + Rvalue::Cast(_kind, ref op, ty) => { + self.fold_ty(op.ty(&self.1.local_decls, tcx)); + self.fold_ty(ty); + } + _ => {} } + self.super_rvalue(rvalue, location); } +} - impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for SubstsVisitor<'a, 'gcx, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { - self.0 +impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for SubstsVisitor<'a, 'gcx, 'tcx> { + fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { + self.0 + } + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + if !ty.needs_subst() { + return ty; } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if !ty.needs_subst() { - return ty; + match ty.sty { + ty::TyParam(param) => { + self.2.substs.push(param); + ty } - match ty.sty { - ty::TyParam(param) => { - self.1.substs.push(param); - ty - } - ty::TyFnDef(_, substs) => { - for subst in substs { - if let UnpackedKind::Type(ty) = subst.unpack() { - ty.fold_with(self); - } + ty::TyFnDef(_, substs) => { + for subst in substs { + if let UnpackedKind::Type(ty) = subst.unpack() { + ty.fold_with(self); } - ty.super_fold_with(self) } - ty::TyClosure(_, closure_substs) => { - for subst in closure_substs.substs { - if let UnpackedKind::Type(ty) = subst.unpack() { - ty.fold_with(self); - } + ty.super_fold_with(self) + } + ty::TyClosure(_, closure_substs) => { + for subst in closure_substs.substs { + if let UnpackedKind::Type(ty) = subst.unpack() { + ty.fold_with(self); } - ty.super_fold_with(self) } - _ => ty.super_fold_with(self) + ty.super_fold_with(self) } + _ => ty.super_fold_with(self) } } +} +fn used_substs_for_instance<'a, 'tcx: 'a>( + tcx: TyCtxt<'a ,'tcx, 'tcx>, + instance: Instance<'tcx> +) -> UsedSubsts { let mir = tcx.instance_mir(instance.def); let sig = ::rustc::ty::ty_fn_sig(tcx, instance.ty(tcx)); let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); - let mut substs_visitor = SubstsVisitor(tcx, UsedSubsts::default()); + let mut substs_visitor = SubstsVisitor(tcx, mir, UsedSubsts::default()); substs_visitor.visit_mir(mir); for ty in sig.inputs().iter() { ty.fold_with(&mut substs_visitor); } sig.output().fold_with(&mut substs_visitor); - let mut used_substs = substs_visitor.1; + let mut used_substs = substs_visitor.2; used_substs.substs.sort_by_key(|s|s.idx); used_substs.substs.dedup_by_key(|s|s.idx); used_substs From 483bb4679eae315256ce67eb668e98ab4375b505 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 10 Feb 2018 18:08:02 +0100 Subject: [PATCH 07/21] WIP --- .../monomorphize/deduplicate_instances.rs | 18 +++++++++++++++++- .../item-collection/static-init.rs | 2 +- .../run-make-fulldeps/libtest-json/Makefile | 3 ++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/monomorphize/deduplicate_instances.rs b/src/librustc_mir/monomorphize/deduplicate_instances.rs index 7546d7baca0da..762b588ade721 100644 --- a/src/librustc_mir/monomorphize/deduplicate_instances.rs +++ b/src/librustc_mir/monomorphize/deduplicate_instances.rs @@ -47,10 +47,12 @@ pub(crate) fn collapse_interchangable_instances<'a, 'tcx>( if false /*param.name.as_str().starts_with("<")*/ { ty.into() } else { + tcx.sess.warn(&format!("Unused subst for {:?}", inst)); tcx.mk_ty(ty::TyNever) } } else { // Can't use TyError as it gives some ICE in rustc_trans::callee::get_fn + tcx.sess.warn(&format!("Unused subst for {:?}", inst)); tcx.mk_ty(ty::TyNever) }; Kind::from(ty) @@ -140,7 +142,7 @@ impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for SubstsVisitor<'a, fn used_substs_for_instance<'a, 'tcx: 'a>( tcx: TyCtxt<'a ,'tcx, 'tcx>, - instance: Instance<'tcx> + instance: Instance<'tcx>, ) -> UsedSubsts { let mir = tcx.instance_mir(instance.def); let sig = ::rustc::ty::ty_fn_sig(tcx, instance.ty(tcx)); @@ -154,5 +156,19 @@ fn used_substs_for_instance<'a, 'tcx: 'a>( let mut used_substs = substs_visitor.2; used_substs.substs.sort_by_key(|s|s.idx); used_substs.substs.dedup_by_key(|s|s.idx); + used_substs.promoted = mir.promoted.iter().map(|mir| used_substs_for_mir(tcx, mir)).collect(); + used_substs +} + +fn used_substs_for_mir<'a, 'tcx: 'a>( + tcx: TyCtxt<'a ,'tcx, 'tcx>, + mir: &'tcx Mir<'tcx>, +) -> UsedSubsts { + let mut substs_visitor = SubstsVisitor(tcx, mir, UsedSubsts::default()); + substs_visitor.visit_mir(mir); + let mut used_substs = substs_visitor.2; + used_substs.substs.sort_by_key(|s|s.idx); + used_substs.substs.dedup_by_key(|s|s.idx); + used_substs.promoted = mir.promoted.iter().map(|mir| used_substs_for_mir(tcx, mir)).collect(); used_substs } diff --git a/src/test/codegen-units/item-collection/static-init.rs b/src/test/codegen-units/item-collection/static-init.rs index 5ff7c3480b126..87260d8b89f26 100644 --- a/src/test/codegen-units/item-collection/static-init.rs +++ b/src/test/codegen-units/item-collection/static-init.rs @@ -17,7 +17,7 @@ pub static FN : fn() = foo::; pub fn foo() { } -//~ TRANS_ITEM fn static_init::foo[0] +//~ TRANS_ITEM fn static_init::foo[0] //~ TRANS_ITEM static static_init::FN[0] //~ TRANS_ITEM fn static_init::start[0] diff --git a/src/test/run-make-fulldeps/libtest-json/Makefile b/src/test/run-make-fulldeps/libtest-json/Makefile index ec91ddfb9f917..9a216c4a9b7eb 100644 --- a/src/test/run-make-fulldeps/libtest-json/Makefile +++ b/src/test/run-make-fulldeps/libtest-json/Makefile @@ -6,7 +6,8 @@ OUTPUT_FILE := $(TMPDIR)/libtest-json-output.json all: $(RUSTC) --test f.rs - $(call RUN,f) -Z unstable-options --test-threads=1 --format=json > $(OUTPUT_FILE) || true + RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=json \ + > $(OUTPUT_FILE) || true cat $(OUTPUT_FILE) | "$(PYTHON)" validate_json.py From e81770402748b5c1adeceb8771a1d00c3d2805db Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 15 Feb 2018 12:57:31 +0100 Subject: [PATCH 08/21] Address some review comments --- .../monomorphize/deduplicate_instances.rs | 73 +++++++++++-------- 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/src/librustc_mir/monomorphize/deduplicate_instances.rs b/src/librustc_mir/monomorphize/deduplicate_instances.rs index 762b588ade721..528a3b8e4b334 100644 --- a/src/librustc_mir/monomorphize/deduplicate_instances.rs +++ b/src/librustc_mir/monomorphize/deduplicate_instances.rs @@ -16,43 +16,56 @@ use rustc::middle::const_val::ConstVal; use rustc::mir::{Mir, Rvalue, Promoted, Location}; use rustc::mir::visit::{Visitor, TyContext}; -/// Replace substs which arent used by the function with TyError, -/// so that it doesnt end up in the binary multiple times +/// Replace substs which aren't used by the function with TyError, +/// so that it doesn't end up in the binary multiple times +/// For example in the code +/// +/// ```rust +/// fn foo() { } // here, T is clearly unused =) +/// +/// fn main() { +/// foo::(); +/// foo::(); +/// } +/// ``` +/// +/// `foo::` and `foo::` are collapsed to `foo::<{some dummy}>`, +/// because codegen for `foo` doesn't depend on the Subst for T. pub(crate) fn collapse_interchangable_instances<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, - mut inst: Instance<'tcx> + mut instance: Instance<'tcx> ) -> Instance<'tcx> { - info!("replace_unused_substs_with_ty_error({:?})", inst); + info!("replace_unused_substs_with_ty_error({:?})", instance); - if inst.substs.is_noop() || !tcx.is_mir_available(inst.def_id()) { - return inst; + if instance.substs.is_noop() || !tcx.is_mir_available(instance.def_id()) { + return instance; } - match inst.ty(tcx).sty { + match instance.ty(tcx).sty { ty::TyFnDef(def_id, _) => { //let attrs = tcx.item_attrs(def_id); if tcx.lang_items().items().iter().find(|l|**l == Some(def_id)).is_some() { - return inst; // Lang items dont work otherwise + return instance; // Lang items dont work otherwise } } - _ => return inst, // Closures dont work otherwise + _ => return instance, // Closures dont work otherwise } - let used_substs = used_substs_for_instance(tcx, inst); - inst.substs = tcx._intern_substs(&inst.substs.into_iter().enumerate().map(|(i, subst)| { + let used_substs = used_substs_for_instance(tcx, instance); + instance.substs = tcx._intern_substs(&instance.substs.into_iter().enumerate().map(|(i, subst)| { if let UnpackedKind::Type(ty) = subst.unpack() { - let ty = if used_substs.substs.iter().find(|p|p.idx == i as u32).is_some() { + let ty = if used_substs.parameters.iter().find(|p|p.idx == i as u32).is_some() { ty.into() } else if let ty::TyParam(ref _param) = ty.sty { //^ Dont replace and other internal params if false /*param.name.as_str().starts_with("<")*/ { ty.into() } else { - tcx.sess.warn(&format!("Unused subst for {:?}", inst)); + tcx.sess.warn(&format!("Unused subst for {:?}", instance)); tcx.mk_ty(ty::TyNever) } } else { // Can't use TyError as it gives some ICE in rustc_trans::callee::get_fn - tcx.sess.warn(&format!("Unused subst for {:?}", inst)); + tcx.sess.warn(&format!("Unused subst for {:?}", instance)); tcx.mk_ty(ty::TyNever) }; Kind::from(ty) @@ -60,22 +73,22 @@ pub(crate) fn collapse_interchangable_instances<'a, 'tcx>( (*subst).clone() } }).collect::>()); - info!("replace_unused_substs_with_ty_error(_) -> {:?}", inst); - inst + info!("replace_unused_substs_with_ty_error(_) -> {:?}", instance); + instance } #[derive(Debug, Default, Clone)] -pub struct UsedSubsts { - pub substs: Vec, - pub promoted: IndexVec, +pub struct UsedParameters { + pub parameters: Vec, + pub promoted: IndexVec, } -impl_stable_hash_for! { struct UsedSubsts { substs, promoted } } +impl_stable_hash_for! { struct UsedParameters { parameters, promoted } } struct SubstsVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a>( TyCtxt<'a, 'gcx, 'tcx>, &'tcx Mir<'tcx>, - UsedSubsts + UsedParameters, ); impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> Visitor<'tcx> for SubstsVisitor<'a, 'gcx, 'tcx> { @@ -116,7 +129,7 @@ impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for SubstsVisitor<'a, } match ty.sty { ty::TyParam(param) => { - self.2.substs.push(param); + self.2.parameters.push(param); ty } ty::TyFnDef(_, substs) => { @@ -143,19 +156,19 @@ impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for SubstsVisitor<'a, fn used_substs_for_instance<'a, 'tcx: 'a>( tcx: TyCtxt<'a ,'tcx, 'tcx>, instance: Instance<'tcx>, -) -> UsedSubsts { +) -> UsedParameters { let mir = tcx.instance_mir(instance.def); let sig = ::rustc::ty::ty_fn_sig(tcx, instance.ty(tcx)); let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); - let mut substs_visitor = SubstsVisitor(tcx, mir, UsedSubsts::default()); + let mut substs_visitor = SubstsVisitor(tcx, mir, UsedParameters::default()); substs_visitor.visit_mir(mir); for ty in sig.inputs().iter() { ty.fold_with(&mut substs_visitor); } sig.output().fold_with(&mut substs_visitor); let mut used_substs = substs_visitor.2; - used_substs.substs.sort_by_key(|s|s.idx); - used_substs.substs.dedup_by_key(|s|s.idx); + used_substs.parameters.sort_by_key(|s|s.idx); + used_substs.parameters.dedup_by_key(|s|s.idx); used_substs.promoted = mir.promoted.iter().map(|mir| used_substs_for_mir(tcx, mir)).collect(); used_substs } @@ -163,12 +176,12 @@ fn used_substs_for_instance<'a, 'tcx: 'a>( fn used_substs_for_mir<'a, 'tcx: 'a>( tcx: TyCtxt<'a ,'tcx, 'tcx>, mir: &'tcx Mir<'tcx>, -) -> UsedSubsts { - let mut substs_visitor = SubstsVisitor(tcx, mir, UsedSubsts::default()); +) -> UsedParameters { + let mut substs_visitor = SubstsVisitor(tcx, mir, UsedParameters::default()); substs_visitor.visit_mir(mir); let mut used_substs = substs_visitor.2; - used_substs.substs.sort_by_key(|s|s.idx); - used_substs.substs.dedup_by_key(|s|s.idx); + used_substs.parameters.sort_by_key(|s|s.idx); + used_substs.parameters.dedup_by_key(|s|s.idx); used_substs.promoted = mir.promoted.iter().map(|mir| used_substs_for_mir(tcx, mir)).collect(); used_substs } From f6a3eb0f53a6838e85065657f47d127176f8ade9 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 15 Feb 2018 19:05:11 +0100 Subject: [PATCH 09/21] Refactoring for future layout only param dependency dedup --- .../monomorphize/deduplicate_instances.rs | 98 +++++++++++++------ 1 file changed, 69 insertions(+), 29 deletions(-) diff --git a/src/librustc_mir/monomorphize/deduplicate_instances.rs b/src/librustc_mir/monomorphize/deduplicate_instances.rs index 528a3b8e4b334..9121b1f42647e 100644 --- a/src/librustc_mir/monomorphize/deduplicate_instances.rs +++ b/src/librustc_mir/monomorphize/deduplicate_instances.rs @@ -9,11 +9,11 @@ // except according to those terms. use rustc_data_structures::indexed_vec::IndexVec; -use rustc::ty::{self, TyCtxt, Ty, TypeFoldable, Instance, ParamTy}; +use rustc::ty::{self, TyCtxt, Ty, TypeFoldable, Instance}; use rustc::ty::fold::TypeFolder; use rustc::ty::subst::{Kind, UnpackedKind}; use rustc::middle::const_val::ConstVal; -use rustc::mir::{Mir, Rvalue, Promoted, Location}; +use rustc::mir::{Mir, Rvalue, Location}; use rustc::mir::visit::{Visitor, TyContext}; /// Replace substs which aren't used by the function with TyError, @@ -53,7 +53,26 @@ pub(crate) fn collapse_interchangable_instances<'a, 'tcx>( let used_substs = used_substs_for_instance(tcx, instance); instance.substs = tcx._intern_substs(&instance.substs.into_iter().enumerate().map(|(i, subst)| { if let UnpackedKind::Type(ty) = subst.unpack() { - let ty = if used_substs.parameters.iter().find(|p|p.idx == i as u32).is_some() { + /*let ty = if let ty::TyParam(ref _param) = ty.sty { + match used_substs.parameters[ParamIdx(i as u32)] { + ParamUsage::Unused => ty.into(), + ParamUsage::LayoutUsed | ParamUsage::Used => { + //^ Dont replace and other internal params + if false /*param.name.as_str().starts_with("<")*/ { + ty.into() + } else { + tcx.sess.warn(&format!("Unused subst for {:?}", instance)); + tcx.mk_ty(ty::TyNever) + } + } + } + } else { + tcx.sess.fatal("efjiofefio"); + // Can't use TyError as it gives some ICE in rustc_trans::callee::get_fn + tcx.sess.warn(&format!("Unused subst for {:?}", instance)); + tcx.mk_ty(ty::TyNever) + };*/ + let ty = if used_substs.parameters[ParamIdx(i as u32)] != ParamUsage::Unused { ty.into() } else if let ty::TyParam(ref _param) = ty.sty { //^ Dont replace and other internal params @@ -77,21 +96,59 @@ pub(crate) fn collapse_interchangable_instances<'a, 'tcx>( instance } +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +struct ParamIdx(u32); + +impl ::rustc_data_structures::indexed_vec::Idx for ParamIdx { + fn new(idx: usize) -> Self { + assert!(idx < ::std::u32::MAX as usize); + ParamIdx(idx as u32) + } + + fn index(self) -> usize { + self.0 as usize + } +} + +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +enum ParamUsage { + Unused = 0, + #[allow(dead_code)] + LayoutUsed = 1, + Used = 2, +} + +impl_stable_hash_for! { enum self::ParamUsage { Unused, LayoutUsed, Used} } + #[derive(Debug, Default, Clone)] -pub struct UsedParameters { - pub parameters: Vec, - pub promoted: IndexVec, +pub struct ParamsUsage { + parameters: IndexVec, } -impl_stable_hash_for! { struct UsedParameters { parameters, promoted } } +impl_stable_hash_for! { struct ParamsUsage { parameters } } + +impl ParamsUsage { + fn new(len: usize) -> ParamsUsage { + ParamsUsage { + parameters: IndexVec::from_elem_n(ParamUsage::Unused, len), + } + } +} struct SubstsVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a>( TyCtxt<'a, 'gcx, 'tcx>, &'tcx Mir<'tcx>, - UsedParameters, + ParamsUsage, ); impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> Visitor<'tcx> for SubstsVisitor<'a, 'gcx, 'tcx> { + fn visit_mir(&mut self, mir: &Mir<'tcx>) { + for promoted in &mir.promoted { + self.visit_mir(promoted); + } + self.super_mir(mir); + } + fn visit_ty(&mut self, ty: &Ty<'tcx>, _: TyContext) { self.fold_ty(ty); } @@ -129,7 +186,7 @@ impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for SubstsVisitor<'a, } match ty.sty { ty::TyParam(param) => { - self.2.parameters.push(param); + self.2.parameters[ParamIdx(param.idx)] = ParamUsage::Used; ty } ty::TyFnDef(_, substs) => { @@ -156,32 +213,15 @@ impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for SubstsVisitor<'a, fn used_substs_for_instance<'a, 'tcx: 'a>( tcx: TyCtxt<'a ,'tcx, 'tcx>, instance: Instance<'tcx>, -) -> UsedParameters { +) -> ParamsUsage { let mir = tcx.instance_mir(instance.def); let sig = ::rustc::ty::ty_fn_sig(tcx, instance.ty(tcx)); let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); - let mut substs_visitor = SubstsVisitor(tcx, mir, UsedParameters::default()); + let mut substs_visitor = SubstsVisitor(tcx, mir, ParamsUsage::new(instance.substs.len())); substs_visitor.visit_mir(mir); for ty in sig.inputs().iter() { ty.fold_with(&mut substs_visitor); } sig.output().fold_with(&mut substs_visitor); - let mut used_substs = substs_visitor.2; - used_substs.parameters.sort_by_key(|s|s.idx); - used_substs.parameters.dedup_by_key(|s|s.idx); - used_substs.promoted = mir.promoted.iter().map(|mir| used_substs_for_mir(tcx, mir)).collect(); - used_substs -} - -fn used_substs_for_mir<'a, 'tcx: 'a>( - tcx: TyCtxt<'a ,'tcx, 'tcx>, - mir: &'tcx Mir<'tcx>, -) -> UsedParameters { - let mut substs_visitor = SubstsVisitor(tcx, mir, UsedParameters::default()); - substs_visitor.visit_mir(mir); - let mut used_substs = substs_visitor.2; - used_substs.parameters.sort_by_key(|s|s.idx); - used_substs.parameters.dedup_by_key(|s|s.idx); - used_substs.promoted = mir.promoted.iter().map(|mir| used_substs_for_mir(tcx, mir)).collect(); - used_substs + substs_visitor.2 } From 22e68868ead83809fc2016f2b36f5f0cfaea1732 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 17 Feb 2018 17:56:55 +0100 Subject: [PATCH 10/21] WIP --- src/librustc/ty/sty.rs | 3 + .../monomorphize/deduplicate_instances.rs | 112 ++++++++++++------ src/librustc_mir/util/pretty.rs | 6 +- src/librustc_trans/debuginfo/metadata.rs | 2 + src/librustc_trans/trans_item.rs | 1 + 5 files changed, 85 insertions(+), 39 deletions(-) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index ed04d41ba1457..1233a7988ce9c 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -164,6 +164,9 @@ pub enum TypeVariants<'tcx> { /// A type parameter; for example, `T` in `fn f(x: T) {} TyParam(ParamTy), + /// Substitution for a unused type parameter; see rustc_mir::monomorphize::deduplicate_instances + TyUnusedParam, + /// A type variable used during type-checking. TyInfer(InferTy), diff --git a/src/librustc_mir/monomorphize/deduplicate_instances.rs b/src/librustc_mir/monomorphize/deduplicate_instances.rs index 9121b1f42647e..a94eaa0edbe45 100644 --- a/src/librustc_mir/monomorphize/deduplicate_instances.rs +++ b/src/librustc_mir/monomorphize/deduplicate_instances.rs @@ -9,7 +9,7 @@ // except according to those terms. use rustc_data_structures::indexed_vec::IndexVec; -use rustc::ty::{self, TyCtxt, Ty, TypeFoldable, Instance}; +use rustc::ty::{self, TyCtxt, Ty, ParamTy, TypeFoldable, Instance}; use rustc::ty::fold::TypeFolder; use rustc::ty::subst::{Kind, UnpackedKind}; use rustc::middle::const_val::ConstVal; @@ -53,39 +53,31 @@ pub(crate) fn collapse_interchangable_instances<'a, 'tcx>( let used_substs = used_substs_for_instance(tcx, instance); instance.substs = tcx._intern_substs(&instance.substs.into_iter().enumerate().map(|(i, subst)| { if let UnpackedKind::Type(ty) = subst.unpack() { - /*let ty = if let ty::TyParam(ref _param) = ty.sty { - match used_substs.parameters[ParamIdx(i as u32)] { - ParamUsage::Unused => ty.into(), - ParamUsage::LayoutUsed | ParamUsage::Used => { - //^ Dont replace and other internal params - if false /*param.name.as_str().starts_with("<")*/ { - ty.into() - } else { - tcx.sess.warn(&format!("Unused subst for {:?}", instance)); - tcx.mk_ty(ty::TyNever) + let ty = match used_substs.parameters[ParamIdx(i as u32)] { + ParamUsage::Unused => { + if false /*param.name.as_str().starts_with("<")*/ { + ty.into() + } else { + #[allow(unused_mut)] + let mut mir = Vec::new(); + ::util::write_mir_pretty(tcx, Some(instance.def_id()), &mut mir).unwrap(); + let mut generics = Some(tcx.generics_of(instance.def_id())); + let mut pretty_generics = String::new(); + loop { + if let Some(ref gen) = generics { + for ty in &gen.types { + pretty_generics.push_str(&format!("{}:{} at {:?}, ", ty.index, ty.name, tcx.def_span(ty.def_id))); + } + } else { + break; + } + generics = generics.and_then(|gen|gen.parent).map(|def_id|tcx.generics_of(def_id)); } + tcx.sess.warn(&format!("Unused subst {} for {:?}<{}>\n with mir: {}", i, instance, pretty_generics, String::from_utf8_lossy(&mir))); + tcx.mk_ty(ty::TyNever) } } - } else { - tcx.sess.fatal("efjiofefio"); - // Can't use TyError as it gives some ICE in rustc_trans::callee::get_fn - tcx.sess.warn(&format!("Unused subst for {:?}", instance)); - tcx.mk_ty(ty::TyNever) - };*/ - let ty = if used_substs.parameters[ParamIdx(i as u32)] != ParamUsage::Unused { - ty.into() - } else if let ty::TyParam(ref _param) = ty.sty { - //^ Dont replace and other internal params - if false /*param.name.as_str().starts_with("<")*/ { - ty.into() - } else { - tcx.sess.warn(&format!("Unused subst for {:?}", instance)); - tcx.mk_ty(ty::TyNever) - } - } else { - // Can't use TyError as it gives some ICE in rustc_trans::callee::get_fn - tcx.sess.warn(&format!("Unused subst for {:?}", instance)); - tcx.mk_ty(ty::TyNever) + ParamUsage::LayoutUsed | ParamUsage::Used => ty.into(), }; Kind::from(ty) } else { @@ -185,9 +177,18 @@ impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for SubstsVisitor<'a, return ty; } match ty.sty { - ty::TyParam(param) => { - self.2.parameters[ParamIdx(param.idx)] = ParamUsage::Used; - ty + /*ty::TyAdt(_, substs) => { + for subst in substs { + if let Some(ty) = subst.as_type() { + ty.fold_with(self); + } + } + } + ty::TyArray(ty, _) | + ty::TySlice(ty) | + ty::TyRawPtr(TypeAndMut { ty, .. }) | + ty::TyRef(_, TypeAndMut { ty, .. }) => { + ty.fold_with(self); } ty::TyFnDef(_, substs) => { for subst in substs { @@ -195,7 +196,11 @@ impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for SubstsVisitor<'a, ty.fold_with(self); } } - ty.super_fold_with(self) + } + ty::TyFnPtr(poly_fn_sig) => { + for ty in poly_fn_sig.skip_binder().inputs_and_outputs { + ty.fold_with(self); + } } ty::TyClosure(_, closure_substs) => { for subst in closure_substs.substs { @@ -203,10 +208,33 @@ impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for SubstsVisitor<'a, ty.fold_with(self); } } - ty.super_fold_with(self) } - _ => ty.super_fold_with(self) + ty::TyGenerator(_, closure_substs, generator_interior) => { + for subst in closure_substs.substs { + if let Some(ty) = subst.as_type() { + ty.fold_with(self); + } + } + generator_interior.witness.fold_with(self); + } + ty::TyTuple(types, _) => { + for ty in types { + ty.fold_with(self); + } + } + ty::TyProjection(projection_ty) => { + for subst in projection_ty.substs { + if let Some(ty) = subst.as_type() { + ty.fold_with(self); + } + } + }*/ + ty::TyParam(param) => { + self.2.parameters[ParamIdx(param.idx)] = ParamUsage::Used; + } + _ => {} } + ty.super_fold_with(self) } } @@ -215,13 +243,21 @@ fn used_substs_for_instance<'a, 'tcx: 'a>( instance: Instance<'tcx>, ) -> ParamsUsage { let mir = tcx.instance_mir(instance.def); + let generics = tcx.generics_of(instance.def_id()); let sig = ::rustc::ty::ty_fn_sig(tcx, instance.ty(tcx)); let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); let mut substs_visitor = SubstsVisitor(tcx, mir, ParamsUsage::new(instance.substs.len())); - substs_visitor.visit_mir(mir); + //substs_visitor.visit_mir(mir); + mir.fold_with(&mut substs_visitor); for ty in sig.inputs().iter() { ty.fold_with(&mut substs_visitor); } + for ty_param_def in &generics.types { + if ParamTy::for_def(ty_param_def).is_self() { + // The self parameter is important for trait selection + (substs_visitor.2).parameters[ParamIdx(ty_param_def.index)] = ParamUsage::Used; + } + } sig.output().fold_with(&mut substs_visitor); substs_visitor.2 } diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 4509cace794d4..2165adedaa6cb 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -517,7 +517,11 @@ pub fn write_mir_intro<'a, 'gcx, 'tcx>( mir: &Mir, w: &mut dyn Write, ) -> io::Result<()> { - write_mir_sig(tcx, src, mir, w)?; + if tcx.hir.as_local_node_id(src.def_id).is_some() { + write_mir_sig(tcx, src, mir, w)?; + } else { + write!(w, "fn () ")?; + } writeln!(w, "{{")?; // construct a scope tree and write it out diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index f3d95cf794bab..f027b54fd7a2e 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -1567,6 +1567,8 @@ fn create_struct_stub<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, unique_type_id: UniqueTypeId, containing_scope: DIScope) -> DICompositeType { + // TODO: ignore unused generic subsitutions + cx.tcx.sess.warn(&format!("create_struct_stub({:?})", struct_type)); let (struct_size, struct_align) = cx.size_and_align_of(struct_type); let name = CString::new(struct_type_name).unwrap(); diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index 06d94e8d15569..9dfd9e355b394 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -69,6 +69,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { } } MonoItem::Fn(instance) => { + cx.tcx.sess.warn(&format!("trans_instance({:?})", instance)); base::trans_instance(&cx, instance); } } From 402f41ad479df114b436fd038e838d8474985aa8 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 23 Feb 2018 13:47:58 +0100 Subject: [PATCH 11/21] Introduce TyUnusedSubst --- src/librustc/ich/impls_ty.rs | 3 ++- src/librustc/infer/canonical.rs | 3 ++- src/librustc/infer/freshen.rs | 1 + src/librustc/traits/coherence.rs | 3 ++- src/librustc/traits/error_reporting.rs | 3 ++- src/librustc/traits/query/dropck_outlives.rs | 2 ++ src/librustc/traits/select.rs | 4 +++- src/librustc/ty/context.rs | 2 ++ src/librustc/ty/error.rs | 1 + src/librustc/ty/fast_reject.rs | 2 +- src/librustc/ty/flags.rs | 1 + src/librustc/ty/item_path.rs | 1 + src/librustc/ty/layout.rs | 4 ++-- src/librustc/ty/mod.rs | 2 +- src/librustc/ty/outlives.rs | 1 + src/librustc/ty/structural_impls.rs | 4 ++-- src/librustc/ty/sty.rs | 1 + src/librustc/ty/util.rs | 5 ++++- src/librustc/ty/walk.rs | 4 ++-- src/librustc/ty/wf.rs | 1 + src/librustc/util/ppaux.rs | 3 ++- src/librustc_lint/types.rs | 3 ++- src/librustc_mir/monomorphize/item.rs | 1 + src/librustc_traits/dropck_outlives.rs | 2 ++ src/librustc_trans/debuginfo/type_names.rs | 3 +++ src/librustc_typeck/check/cast.rs | 1 + src/librustc_typeck/variance/constraints.rs | 1 + 27 files changed, 46 insertions(+), 16 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 594adfca6b3c0..c48e804708b7f 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -833,7 +833,8 @@ for ty::TypeVariants<'gcx> TyChar | TyStr | TyError | - TyNever => { + TyNever | + TyUnusedParam => { // Nothing more to hash. } TyInt(int_ty) => { diff --git a/src/librustc/infer/canonical.rs b/src/librustc/infer/canonical.rs index 4357c9a5a776a..aa14c655d8482 100644 --- a/src/librustc/infer/canonical.rs +++ b/src/librustc/infer/canonical.rs @@ -634,7 +634,8 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> | ty::TyProjection(..) | ty::TyForeign(..) | ty::TyParam(..) - | ty::TyAnon(..) => { + | ty::TyAnon(..) + | ty::TyUnusedParam => { if t.flags.intersects(self.needs_canonical_flags) { t.super_fold_with(self) } else { diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index 6074bfd083d46..c8d03059496cc 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -200,6 +200,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { ty::TyAnon(..) => { t.super_fold_with(self) } + ty::TyUnusedParam => bug!("Unexpected TyUnusedParam in TypeFreshener"), } } } diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index 31f8af1f96872..010483520953d 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -480,7 +480,8 @@ fn ty_is_local_constructor(ty: Ty, in_crate: InCrate) -> bool { ty::TyClosure(..) | ty::TyGenerator(..) | ty::TyGeneratorWitness(..) | - ty::TyAnon(..) => { + ty::TyAnon(..) | + ty::TyUnusedParam => { bug!("ty_is_local invoked on unexpected type: {:?}", ty) } } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index d2bde14732bbc..e2c4585b25c09 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -263,7 +263,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ty::TyGenerator(..) => Some(18), ty::TyForeign(..) => Some(19), ty::TyGeneratorWitness(..) => Some(20), - ty::TyInfer(..) | ty::TyError => None + ty::TyInfer(..) | ty::TyError => None, + ty::TyUnusedParam => bug!("unexpected TyUnusedParam in fuzzy_match_tys"), } } diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index af1d2c77c28a8..fb17f013e38d4 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -261,5 +261,7 @@ fn trivial_dropck_outlives<'cx, 'tcx>(tcx: TyCtxt<'cx, '_, 'tcx>, ty: Ty<'tcx>) | ty::TyAnon(..) | ty::TyInfer(_) | ty::TyGenerator(..) => false, + + ty::TyUnusedParam => bug!("Unexpected TyUnusedParam in trivial_dropck_outlives"), } } diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 93ae101eb1426..a8d360d2d65bf 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2037,7 +2037,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { )) } - ty::TyProjection(_) | ty::TyParam(_) | ty::TyAnon(..) => None, + ty::TyProjection(_) | ty::TyParam(_) | ty::TyUnusedParam | ty::TyAnon(..) => None, ty::TyInfer(ty::TyVar(_)) => Ambiguous, ty::TyInfer(ty::CanonicalTy(_)) | @@ -2114,6 +2114,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty); } + ty::TyUnusedParam => bug!("Unexpected TyUnusedParam in copy_clone_conditions"), } } @@ -2150,6 +2151,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ty::TyForeign(..) | ty::TyProjection(..) | ty::TyInfer(ty::CanonicalTy(_)) | + ty::TyUnusedParam | ty::TyInfer(ty::TyVar(_)) | ty::TyInfer(ty::FreshTy(_)) | ty::TyInfer(ty::FreshIntTy(_)) | diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index fdda2286da03b..84a5abdcb27b7 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1780,6 +1780,7 @@ macro_rules! sty_debug_print { region_infer: 0, ty_infer: 0, both_infer: 0, }; $(let mut $variant = total;)* + let mut TyUnusedParam = total; for &Interned(t) in tcx.interners.type_.borrow().iter() { @@ -1787,6 +1788,7 @@ macro_rules! sty_debug_print { ty::TyBool | ty::TyChar | ty::TyInt(..) | ty::TyUint(..) | ty::TyFloat(..) | ty::TyStr | ty::TyNever => continue, ty::TyError => /* unimportant */ continue, + ty::TyUnusedParam => &mut TyUnusedParam, $(ty::$variant(..) => &mut $variant,)* }; let region = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER); diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index eb3924186472c..e5278af66a259 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -232,6 +232,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { "type parameter".to_string() } } + ty::TyUnusedParam => "unused type parameter".to_string(), ty::TyAnon(..) => "anonymized type".to_string(), ty::TyError => "type error".to_string(), } diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 31b3ca44700e9..9ba2bf6cfb0ac 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -121,7 +121,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, ty::TyForeign(def_id) => { Some(ForeignSimplifiedType(def_id)) } - ty::TyInfer(_) | ty::TyError => None, + ty::TyInfer(_) | ty::TyError | ty::TyUnusedParam => None, } } diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 086fc66c70f9d..b5c94af56d29e 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -190,6 +190,7 @@ impl FlagComputation { &ty::TyFnPtr(f) => { self.add_fn_sig(f); } + &ty::TyUnusedParam => bug!("Unexpected TyUnusedParam in FlagComputation::for_sty"), } } diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 1f23b0a27e33d..082545ab68df2 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -373,6 +373,7 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option { ty::TyProjection(_) | ty::TyParam(_) | ty::TyAnon(..) | + ty::TyUnusedParam | ty::TyInfer(_) | ty::TyError | ty::TyGeneratorWitness(..) | diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 5f9c305d92f04..a0f2e6bf9f18c 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1712,7 +1712,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { ty::TyParam(_) => { return Err(LayoutError::Unknown(ty)); } - ty::TyGeneratorWitness(..) | ty::TyInfer(_) | ty::TyError => { + ty::TyUnusedParam | ty::TyGeneratorWitness(..) | ty::TyInfer(_) | ty::TyError => { bug!("LayoutDetails::compute: unexpected type `{}`", ty) } }) @@ -2287,7 +2287,7 @@ impl<'a, 'tcx> TyLayout<'tcx> { } } - ty::TyProjection(_) | ty::TyAnon(..) | ty::TyParam(_) | + ty::TyProjection(_) | ty::TyAnon(..) | ty::TyParam(_) | ty::TyUnusedParam | ty::TyInfer(_) | ty::TyError => { bug!("TyLayout::field_type: unexpected type `{}`", self.ty) } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 66ec871fcb950..d6c11cc0a24c9 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2069,7 +2069,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { } } - TyInfer(..) => { + TyUnusedParam | TyInfer(..) => { bug!("unexpected type `{:?}` in sized_constraint_for_ty", ty) } diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs index ff99a4b7ff638..d5946ffe39149 100644 --- a/src/librustc/ty/outlives.rs +++ b/src/librustc/ty/outlives.rs @@ -167,6 +167,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.compute_components(subty, out); } } + ty::TyUnusedParam => bug!("Unexpected TyUnusedParam in compute_components"), } } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 8cf662ccaea92..753a3b795951f 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -865,7 +865,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::TyAnon(did, substs) => ty::TyAnon(did, substs.fold_with(folder)), ty::TyBool | ty::TyChar | ty::TyStr | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyError | ty::TyInfer(_) | - ty::TyParam(..) | ty::TyNever | ty::TyForeign(..) => return self + ty::TyParam(..) | ty::TyUnusedParam | ty::TyNever | ty::TyForeign(..) => return self }; if self.sty == sty { @@ -900,7 +900,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::TyAnon(_, ref substs) => substs.visit_with(visitor), ty::TyBool | ty::TyChar | ty::TyStr | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyError | ty::TyInfer(_) | - ty::TyParam(..) | ty::TyNever | ty::TyForeign(..) => false, + ty::TyParam(..) | ty::TyUnusedParam | ty::TyNever | ty::TyForeign(..) => false, } } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 1233a7988ce9c..d2242b22ffbdf 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1636,6 +1636,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { TyTuple(..) | TyForeign(..) | TyParam(_) | + TyUnusedParam | TyInfer(_) | TyError => { vec![] diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 40997c4e0ba55..dd3b515684d51 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -734,8 +734,9 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W> TySlice(_) => {} // This can be generated by collapse_interchangable_instances - TyError => self.hash(""), + TyUnusedParam => self.hash(""), + TyError | TyInfer(_) => bug!("TypeIdHasher: unexpected type {}", ty) } @@ -1124,6 +1125,8 @@ fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def.variants.iter().any( |variant| variant.fields.iter().any( |field| needs_drop(field.ty(tcx, substs)))), + + ty::TyUnusedParam => bug!("Unexpected TyUnusedParam in needs_drop_raw"), } } diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index 46c048e839b4b..e05b6ba95633d 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -82,8 +82,8 @@ pub fn walk_shallow<'tcx>(ty: Ty<'tcx>) -> AccIntoIter> { fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) { match parent_ty.sty { ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | - ty::TyStr | ty::TyInfer(_) | ty::TyParam(_) | ty::TyNever | ty::TyError | - ty::TyForeign(..) => { + ty::TyStr | ty::TyInfer(_) | ty::TyParam(_) | ty::TyUnusedParam | ty::TyNever | + ty::TyError | ty::TyForeign(..) => { } ty::TyArray(ty, len) => { push_const(stack, len); diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index f05d56c9d8371..91d8ca7ae3bef 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -261,6 +261,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { ty::TyGeneratorWitness(..) | ty::TyNever | ty::TyParam(_) | + ty::TyUnusedParam | ty::TyForeign(..) => { // WfScalar, WfParameter, etc } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index d27cda4040e56..4a3fa68040b64 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -16,7 +16,7 @@ use ty::subst::{self, Subst}; use ty::{BrAnon, BrEnv, BrFresh, BrNamed}; use ty::{TyBool, TyChar, TyAdt}; use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr}; -use ty::{TyParam, TyRawPtr, TyRef, TyNever, TyTuple}; +use ty::{TyParam, TyUnusedParam, TyRawPtr, TyRef, TyNever, TyTuple}; use ty::{TyClosure, TyGenerator, TyGeneratorWitness, TyForeign, TyProjection, TyAnon}; use ty::{TyDynamic, TyInt, TyUint, TyInfer}; use ty::{self, Ty, TyCtxt, TypeFoldable}; @@ -1044,6 +1044,7 @@ define_print! { TyInfer(infer_ty) => write!(f, "{}", infer_ty), TyError => write!(f, "[type error]"), TyParam(ref param_ty) => write!(f, "{}", param_ty), + TyUnusedParam => write!(f, "[unused type param]"), TyAdt(def, substs) => cx.parameterized(f, substs, def.did, &[]), TyDynamic(data, r) => { data.print(f, cx)?; diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 445fe0cc40197..83c4448fc1bcf 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -705,6 +705,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { ty::TyForeign(..) => FfiSafe, ty::TyParam(..) | + ty::TyUnusedParam | ty::TyInfer(..) | ty::TyError | ty::TyClosure(..) | @@ -712,7 +713,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { ty::TyGeneratorWitness(..) | ty::TyProjection(..) | ty::TyAnon(..) | - ty::TyFnDef(..) => bug!("Unexpected type in foreign function"), + ty::TyFnDef(..) => bug!("Unexpected type `{:?}` in foreign function", ty), } } diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index c2f4359c0082b..8a7ddd5db22bb 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -387,6 +387,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { ty::TyInfer(_) | ty::TyProjection(..) | ty::TyParam(_) | + ty::TyUnusedParam | ty::TyGeneratorWitness(_) | ty::TyAnon(..) => { bug!("DefPathBasedNames: Trying to create type name for \ diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs index 1fe2f87128abd..71118792c71b8 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/src/librustc_traits/dropck_outlives.rs @@ -238,6 +238,8 @@ fn dtorck_constraint_for_ty<'a, 'gcx, 'tcx>( // be fully resolved. Err(NoSolution) } + + ty::TyUnusedParam => bug!("Unexpected TyUnusedParam in dtorck_constraint_for_ty"), }; debug!("dtorck_constraint_for_ty({:?}) = {:?}", ty, result); diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index 96ed4e8847115..b407ce5ff9000 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -171,6 +171,9 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ty::TyGenerator(..) => { output.push_str("generator"); } + ty::TyUnusedParam => { + output.push_str("[unused type param]"); + } ty::TyError | ty::TyInfer(_) | ty::TyProjection(..) | diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index e4bad8349ea2b..e2bf8dcc95088 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -137,6 +137,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { span, &format!("`{:?}` should be sized but is not?", t)); return Err(ErrorReported); } + ty::TyUnusedParam => bug!("Unexpected TyUnusedParam in FnCtxt::pointer_kind"), }) } } diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index a24e501aba950..67e7481a3c416 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -334,6 +334,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { // types, where we use TyError as the Self type } + ty::TyUnusedParam | ty::TyGeneratorWitness(..) | ty::TyInfer(..) => { bug!("unexpected type encountered in \ From 98a8b650bb21d723550fee7a40f2a3268be2fe8c Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 25 Feb 2018 11:14:51 +0100 Subject: [PATCH 12/21] Fix it --- src/librustc_trans/debuginfo/mod.rs | 3 ++- src/librustdoc/clean/mod.rs | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 7664c88679e0e..342d21c0e60af 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -206,7 +206,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, sig: ty::FnSig<'tcx>, llfn: ValueRef, mir: &mir::Mir) -> FunctionDebugContext { - if cx.sess().opts.debuginfo == NoDebugInfo { + let has_unused_subst = true; // FIXME: make it work with TyUnusedSubst + if cx.sess().opts.debuginfo == NoDebugInfo || has_unused_subst { return FunctionDebugContext::DebugInfoDisabled; } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3a79c14f4ec2a..c8d80914d33f7 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2836,6 +2836,7 @@ impl<'tcx> Clean for Ty<'tcx> { ty::TyClosure(..) | ty::TyGenerator(..) => Tuple(vec![]), // FIXME(pcwalton) + ty::TyUnusedParam => panic!("TyUnusedParam"), ty::TyGeneratorWitness(..) => panic!("TyGeneratorWitness"), ty::TyInfer(..) => panic!("TyInfer"), ty::TyError => panic!("TyError"), From 819bd7b8fc41d0a5c8c7fd62215056f94878d22b Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 25 Feb 2018 11:16:35 +0100 Subject: [PATCH 13/21] Cleanup a bit --- .../monomorphize/deduplicate_instances.rs | 52 ------------------- 1 file changed, 52 deletions(-) diff --git a/src/librustc_mir/monomorphize/deduplicate_instances.rs b/src/librustc_mir/monomorphize/deduplicate_instances.rs index a94eaa0edbe45..0648f57688bf2 100644 --- a/src/librustc_mir/monomorphize/deduplicate_instances.rs +++ b/src/librustc_mir/monomorphize/deduplicate_instances.rs @@ -177,58 +177,6 @@ impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for SubstsVisitor<'a, return ty; } match ty.sty { - /*ty::TyAdt(_, substs) => { - for subst in substs { - if let Some(ty) = subst.as_type() { - ty.fold_with(self); - } - } - } - ty::TyArray(ty, _) | - ty::TySlice(ty) | - ty::TyRawPtr(TypeAndMut { ty, .. }) | - ty::TyRef(_, TypeAndMut { ty, .. }) => { - ty.fold_with(self); - } - ty::TyFnDef(_, substs) => { - for subst in substs { - if let UnpackedKind::Type(ty) = subst.unpack() { - ty.fold_with(self); - } - } - } - ty::TyFnPtr(poly_fn_sig) => { - for ty in poly_fn_sig.skip_binder().inputs_and_outputs { - ty.fold_with(self); - } - } - ty::TyClosure(_, closure_substs) => { - for subst in closure_substs.substs { - if let UnpackedKind::Type(ty) = subst.unpack() { - ty.fold_with(self); - } - } - } - ty::TyGenerator(_, closure_substs, generator_interior) => { - for subst in closure_substs.substs { - if let Some(ty) = subst.as_type() { - ty.fold_with(self); - } - } - generator_interior.witness.fold_with(self); - } - ty::TyTuple(types, _) => { - for ty in types { - ty.fold_with(self); - } - } - ty::TyProjection(projection_ty) => { - for subst in projection_ty.substs { - if let Some(ty) = subst.as_type() { - ty.fold_with(self); - } - } - }*/ ty::TyParam(param) => { self.2.parameters[ParamIdx(param.idx)] = ParamUsage::Used; } From bfa6e725c3e9cab01add1563707914677bc31efb Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 27 Feb 2018 13:43:28 +0100 Subject: [PATCH 14/21] Fix tidy error --- .../monomorphize/deduplicate_instances.rs | 18 +++++++++++++++--- src/librustc_trans/debuginfo/metadata.rs | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/monomorphize/deduplicate_instances.rs b/src/librustc_mir/monomorphize/deduplicate_instances.rs index 0648f57688bf2..c983050071a79 100644 --- a/src/librustc_mir/monomorphize/deduplicate_instances.rs +++ b/src/librustc_mir/monomorphize/deduplicate_instances.rs @@ -66,14 +66,26 @@ pub(crate) fn collapse_interchangable_instances<'a, 'tcx>( loop { if let Some(ref gen) = generics { for ty in &gen.types { - pretty_generics.push_str(&format!("{}:{} at {:?}, ", ty.index, ty.name, tcx.def_span(ty.def_id))); + pretty_generics.push_str(&format!( + "{}:{} at {:?}, ", + ty.index, + ty.name, + tcx.def_span(ty.def_id) + )); } } else { break; } - generics = generics.and_then(|gen|gen.parent).map(|def_id|tcx.generics_of(def_id)); + generics = generics.and_then(|gen|gen.parent) + .map(|def_id|tcx.generics_of(def_id)); } - tcx.sess.warn(&format!("Unused subst {} for {:?}<{}>\n with mir: {}", i, instance, pretty_generics, String::from_utf8_lossy(&mir))); + tcx.sess.warn(&format!( + "Unused subst {} for {:?}<{}>\n with mir: {}", + i, + instance, + pretty_generics, + String::from_utf8_lossy(&mir) + )); tcx.mk_ty(ty::TyNever) } } diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index f027b54fd7a2e..ef80904a5fbf9 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -1567,7 +1567,7 @@ fn create_struct_stub<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, unique_type_id: UniqueTypeId, containing_scope: DIScope) -> DICompositeType { - // TODO: ignore unused generic subsitutions + // FIXME: ignore unused generic subsitutions cx.tcx.sess.warn(&format!("create_struct_stub({:?})", struct_type)); let (struct_size, struct_align) = cx.size_and_align_of(struct_type); From be529e99d8f7689a02259f67e89167222ffe8df5 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 28 Feb 2018 10:30:05 +0100 Subject: [PATCH 15/21] Disable very verbose debug code --- src/librustc/ty/instance.rs | 2 +- .../monomorphize/deduplicate_instances.rs | 4 +-- src/librustc_trans/callee.rs | 27 ------------------- src/librustc_trans/debuginfo/metadata.rs | 2 +- src/librustc_trans/trans_item.rs | 2 +- 5 files changed, 5 insertions(+), 32 deletions(-) diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index f68985832757a..76f7a0b59a2a5 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -9,7 +9,7 @@ // except according to those terms. use hir::def_id::DefId; -use ty::{self, TyCtxt, Ty, TypeFoldable, Substs}; +use ty::{self, Ty, TypeFoldable, Substs, TyCtxt}; use ty::subst::Kind; use traits; use syntax::abi::Abi; diff --git a/src/librustc_mir/monomorphize/deduplicate_instances.rs b/src/librustc_mir/monomorphize/deduplicate_instances.rs index c983050071a79..0e1d9277e6fa9 100644 --- a/src/librustc_mir/monomorphize/deduplicate_instances.rs +++ b/src/librustc_mir/monomorphize/deduplicate_instances.rs @@ -58,7 +58,7 @@ pub(crate) fn collapse_interchangable_instances<'a, 'tcx>( if false /*param.name.as_str().starts_with("<")*/ { ty.into() } else { - #[allow(unused_mut)] + /*#[allow(unused_mut)] let mut mir = Vec::new(); ::util::write_mir_pretty(tcx, Some(instance.def_id()), &mut mir).unwrap(); let mut generics = Some(tcx.generics_of(instance.def_id())); @@ -85,7 +85,7 @@ pub(crate) fn collapse_interchangable_instances<'a, 'tcx>( instance, pretty_generics, String::from_utf8_lossy(&mir) - )); + ));*/ tcx.mk_ty(ty::TyNever) } } diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index 327a49c386b93..b5654ba6fdb0a 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -47,33 +47,6 @@ pub fn get_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, info!("get_fn(collapsed_instance={:?})", instance); - struct ShowOnPanic(String); - impl Drop for ShowOnPanic { - fn drop(&mut self) { - if ::std::thread::panicking() { - info!("{}", self.0); - } - } - } - let mut mir = Vec::new(); - if !instance.substs.is_noop() { - //::rustc_mir::util::write_mir_pretty(tcx, Some(instance.def_id()), &mut mir).unwrap(); - } else { - use std::io::Write; - write!(mir, "no substs for instance").unwrap(); - } - let generics = tcx.generics_of(instance.def_id()); - - let _d = ShowOnPanic("mir: ".to_string() + &String::from_utf8(mir).unwrap()); - let _c = if let Some(parent) = generics.parent { - let parent_generics = tcx.generics_of(parent); - ShowOnPanic(format!("parent generics: {:#?}", parent_generics)) - } else { - ShowOnPanic("no parent generics".to_string()) - }; - let _b = ShowOnPanic(format!("generics: {:#?}", generics)); - let _a = ShowOnPanic(format!("instance: {:#?}", instance)); - assert!(!instance.substs.needs_infer()); assert!(!instance.substs.has_escaping_regions()); assert!(!instance.substs.has_param_types()); diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index ef80904a5fbf9..897418c63f906 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -1568,7 +1568,7 @@ fn create_struct_stub<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, containing_scope: DIScope) -> DICompositeType { // FIXME: ignore unused generic subsitutions - cx.tcx.sess.warn(&format!("create_struct_stub({:?})", struct_type)); + //cx.tcx.sess.warn(&format!("create_struct_stub({:?})", struct_type)); let (struct_size, struct_align) = cx.size_and_align_of(struct_type); let name = CString::new(struct_type_name).unwrap(); diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index 9dfd9e355b394..d39798ed4d4b2 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -69,7 +69,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { } } MonoItem::Fn(instance) => { - cx.tcx.sess.warn(&format!("trans_instance({:?})", instance)); + //cx.tcx.sess.warn(&format!("trans_instance({:?})", instance)); base::trans_instance(&cx, instance); } } From 286a502b601e057c6019067a7ccbf691b9301c81 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 6 Mar 2018 19:08:33 +0100 Subject: [PATCH 16/21] Prepare for layout use only params --- src/librustc/ich/impls_ty.rs | 2 +- src/librustc/infer/canonical.rs | 3 ++- src/librustc/infer/freshen.rs | 2 +- src/librustc/traits/coherence.rs | 2 +- src/librustc/traits/error_reporting.rs | 2 +- src/librustc/traits/query/dropck_outlives.rs | 4 +++- src/librustc/traits/select.rs | 5 +++-- src/librustc/ty/context.rs | 2 +- src/librustc/ty/error.rs | 2 +- src/librustc/ty/fast_reject.rs | 2 +- src/librustc/ty/flags.rs | 2 +- src/librustc/ty/item_path.rs | 2 +- src/librustc/ty/layout.rs | 6 +++--- src/librustc/ty/mod.rs | 2 +- src/librustc/ty/outlives.rs | 2 +- src/librustc/ty/structural_impls.rs | 4 ++-- src/librustc/ty/sty.rs | 6 +++++- src/librustc/ty/util.rs | 4 ++-- src/librustc/ty/walk.rs | 2 +- src/librustc/ty/wf.rs | 2 +- src/librustc/util/ppaux.rs | 2 +- src/librustc_lint/types.rs | 2 +- .../monomorphize/deduplicate_instances.rs | 17 +++++++++++++---- src/librustc_mir/monomorphize/item.rs | 2 +- src/librustc_traits/dropck_outlives.rs | 4 +++- src/librustc_trans/debuginfo/type_names.rs | 2 +- src/librustc_typeck/check/cast.rs | 2 +- src/librustc_typeck/variance/constraints.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- 29 files changed, 56 insertions(+), 37 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index c48e804708b7f..d3de8e4380080 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -834,7 +834,7 @@ for ty::TypeVariants<'gcx> TyStr | TyError | TyNever | - TyUnusedParam => { + TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => { // Nothing more to hash. } TyInt(int_ty) => { diff --git a/src/librustc/infer/canonical.rs b/src/librustc/infer/canonical.rs index aa14c655d8482..8866eadbddd59 100644 --- a/src/librustc/infer/canonical.rs +++ b/src/librustc/infer/canonical.rs @@ -635,7 +635,8 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> | ty::TyForeign(..) | ty::TyParam(..) | ty::TyAnon(..) - | ty::TyUnusedParam => { + | ty::TyUnusedParam + | ty::TyLayoutOnlyParam(..) => { if t.flags.intersects(self.needs_canonical_flags) { t.super_fold_with(self) } else { diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index c8d03059496cc..3f0e24ec1b997 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -200,7 +200,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { ty::TyAnon(..) => { t.super_fold_with(self) } - ty::TyUnusedParam => bug!("Unexpected TyUnusedParam in TypeFreshener"), + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => bug!("Unexpected TyUnusedParam in TypeFreshener"), } } } diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index 010483520953d..5294c1b831066 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -481,7 +481,7 @@ fn ty_is_local_constructor(ty: Ty, in_crate: InCrate) -> bool { ty::TyGenerator(..) | ty::TyGeneratorWitness(..) | ty::TyAnon(..) | - ty::TyUnusedParam => { + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => { bug!("ty_is_local invoked on unexpected type: {:?}", ty) } } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index e2c4585b25c09..a16e6ba105ccc 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -264,7 +264,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ty::TyForeign(..) => Some(19), ty::TyGeneratorWitness(..) => Some(20), ty::TyInfer(..) | ty::TyError => None, - ty::TyUnusedParam => bug!("unexpected TyUnusedParam in fuzzy_match_tys"), + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => bug!("unexpected TyUnusedParam in fuzzy_match_tys"), } } diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index fb17f013e38d4..54c2f01a66ad0 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -262,6 +262,8 @@ fn trivial_dropck_outlives<'cx, 'tcx>(tcx: TyCtxt<'cx, '_, 'tcx>, ty: Ty<'tcx>) | ty::TyInfer(_) | ty::TyGenerator(..) => false, - ty::TyUnusedParam => bug!("Unexpected TyUnusedParam in trivial_dropck_outlives"), + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => { + bug!("Unexpected {:?} in trivial_dropck_outlives", ty) + } } } diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index a8d360d2d65bf..821219c5c313d 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2037,7 +2037,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { )) } - ty::TyProjection(_) | ty::TyParam(_) | ty::TyUnusedParam | ty::TyAnon(..) => None, + ty::TyProjection(_) | ty::TyParam(_) | ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | ty::TyAnon(..) => None, ty::TyInfer(ty::TyVar(_)) => Ambiguous, ty::TyInfer(ty::CanonicalTy(_)) | @@ -2114,7 +2114,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty); } - ty::TyUnusedParam => bug!("Unexpected TyUnusedParam in copy_clone_conditions"), + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => bug!("Unexpected TyUnusedParam in copy_clone_conditions"), } } @@ -2152,6 +2152,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ty::TyProjection(..) | ty::TyInfer(ty::CanonicalTy(_)) | ty::TyUnusedParam | + ty::TyLayoutOnlyParam(_, _) | ty::TyInfer(ty::TyVar(_)) | ty::TyInfer(ty::FreshTy(_)) | ty::TyInfer(ty::FreshIntTy(_)) | diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 84a5abdcb27b7..f1574df66dfa7 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1829,7 +1829,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { self, TyAdt, TyArray, TySlice, TyRawPtr, TyRef, TyFnDef, TyFnPtr, TyGenerator, TyGeneratorWitness, TyDynamic, TyClosure, TyTuple, - TyParam, TyInfer, TyProjection, TyAnon, TyForeign); + TyParam, TyLayoutOnlyParam, TyInfer, TyProjection, TyAnon, TyForeign); println!("Substs interner: #{}", self.interners.substs.borrow().len()); println!("Region interner: #{}", self.interners.region.borrow().len()); diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index e5278af66a259..cc104de6cb454 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -232,7 +232,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { "type parameter".to_string() } } - ty::TyUnusedParam => "unused type parameter".to_string(), + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => "unused type parameter".to_string(), ty::TyAnon(..) => "anonymized type".to_string(), ty::TyError => "type error".to_string(), } diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 9ba2bf6cfb0ac..90117b7e41bba 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -121,7 +121,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, ty::TyForeign(def_id) => { Some(ForeignSimplifiedType(def_id)) } - ty::TyInfer(_) | ty::TyError | ty::TyUnusedParam => None, + ty::TyInfer(_) | ty::TyError | ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => None, } } diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index b5c94af56d29e..e307117bae7eb 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -190,7 +190,7 @@ impl FlagComputation { &ty::TyFnPtr(f) => { self.add_fn_sig(f); } - &ty::TyUnusedParam => bug!("Unexpected TyUnusedParam in FlagComputation::for_sty"), + &ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => bug!("Unexpected TyUnusedParam in FlagComputation::for_sty"), } } diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 082545ab68df2..e40de8f3cc51b 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -373,7 +373,7 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option { ty::TyProjection(_) | ty::TyParam(_) | ty::TyAnon(..) | - ty::TyUnusedParam | + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | ty::TyInfer(_) | ty::TyError | ty::TyGeneratorWitness(..) | diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index a0f2e6bf9f18c..77db77f686201 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -234,7 +234,7 @@ pub enum Endian { } /// Size of a type in bytes. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] pub struct Size { raw: u64 } @@ -1712,7 +1712,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { ty::TyParam(_) => { return Err(LayoutError::Unknown(ty)); } - ty::TyUnusedParam | ty::TyGeneratorWitness(..) | ty::TyInfer(_) | ty::TyError => { + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | ty::TyGeneratorWitness(..) | ty::TyInfer(_) | ty::TyError => { bug!("LayoutDetails::compute: unexpected type `{}`", ty) } }) @@ -2287,7 +2287,7 @@ impl<'a, 'tcx> TyLayout<'tcx> { } } - ty::TyProjection(_) | ty::TyAnon(..) | ty::TyParam(_) | ty::TyUnusedParam | + ty::TyProjection(_) | ty::TyAnon(..) | ty::TyParam(_) | ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | ty::TyInfer(_) | ty::TyError => { bug!("TyLayout::field_type: unexpected type `{}`", self.ty) } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index d6c11cc0a24c9..97521f3e595f5 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2069,7 +2069,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { } } - TyUnusedParam | TyInfer(..) => { + TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | TyInfer(..) => { bug!("unexpected type `{:?}` in sized_constraint_for_ty", ty) } diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs index d5946ffe39149..a7fc440785e1f 100644 --- a/src/librustc/ty/outlives.rs +++ b/src/librustc/ty/outlives.rs @@ -167,7 +167,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.compute_components(subty, out); } } - ty::TyUnusedParam => bug!("Unexpected TyUnusedParam in compute_components"), + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => bug!("Unexpected TyUnusedParam in compute_components"), } } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 753a3b795951f..353eda6dd4f5d 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -865,7 +865,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::TyAnon(did, substs) => ty::TyAnon(did, substs.fold_with(folder)), ty::TyBool | ty::TyChar | ty::TyStr | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyError | ty::TyInfer(_) | - ty::TyParam(..) | ty::TyUnusedParam | ty::TyNever | ty::TyForeign(..) => return self + ty::TyParam(..) | ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | ty::TyNever | ty::TyForeign(..) => return self }; if self.sty == sty { @@ -900,7 +900,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::TyAnon(_, ref substs) => substs.visit_with(visitor), ty::TyBool | ty::TyChar | ty::TyStr | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyError | ty::TyInfer(_) | - ty::TyParam(..) | ty::TyUnusedParam | ty::TyNever | ty::TyForeign(..) => false, + ty::TyParam(..) | ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | ty::TyNever | ty::TyForeign(..) => false, } } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index d2242b22ffbdf..3fe0c0ba2481f 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -18,6 +18,7 @@ use rustc_data_structures::indexed_vec::Idx; use ty::subst::{Substs, Subst, Kind, UnpackedKind}; use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable}; use ty::{Slice, TyS}; +use ty::layout::{Size, Align}; use util::captures::Captures; use std::iter; @@ -167,6 +168,9 @@ pub enum TypeVariants<'tcx> { /// Substitution for a unused type parameter; see rustc_mir::monomorphize::deduplicate_instances TyUnusedParam, + /// Substitution for a type parameter whose size and layout is the onlything that matters + TyLayoutOnlyParam(Size, Align), + /// A type variable used during type-checking. TyInfer(InferTy), @@ -1636,7 +1640,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { TyTuple(..) | TyForeign(..) | TyParam(_) | - TyUnusedParam | + TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | TyInfer(_) | TyError => { vec![] diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index dd3b515684d51..1f88a53837ed6 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -734,7 +734,7 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W> TySlice(_) => {} // This can be generated by collapse_interchangable_instances - TyUnusedParam => self.hash(""), + TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => self.hash(""), TyError | TyInfer(_) => bug!("TypeIdHasher: unexpected type {}", ty) @@ -1126,7 +1126,7 @@ fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, |variant| variant.fields.iter().any( |field| needs_drop(field.ty(tcx, substs)))), - ty::TyUnusedParam => bug!("Unexpected TyUnusedParam in needs_drop_raw"), + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => bug!("Unexpected TyUnusedParam in needs_drop_raw"), } } diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index e05b6ba95633d..9cc067f24feaf 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -82,7 +82,7 @@ pub fn walk_shallow<'tcx>(ty: Ty<'tcx>) -> AccIntoIter> { fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) { match parent_ty.sty { ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | - ty::TyStr | ty::TyInfer(_) | ty::TyParam(_) | ty::TyUnusedParam | ty::TyNever | + ty::TyStr | ty::TyInfer(_) | ty::TyParam(_) | ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | ty::TyNever | ty::TyError | ty::TyForeign(..) => { } ty::TyArray(ty, len) => { diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index 91d8ca7ae3bef..2211d485d0918 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -261,7 +261,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { ty::TyGeneratorWitness(..) | ty::TyNever | ty::TyParam(_) | - ty::TyUnusedParam | + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | ty::TyForeign(..) => { // WfScalar, WfParameter, etc } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 4a3fa68040b64..c2d9292db9a23 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1044,7 +1044,7 @@ define_print! { TyInfer(infer_ty) => write!(f, "{}", infer_ty), TyError => write!(f, "[type error]"), TyParam(ref param_ty) => write!(f, "{}", param_ty), - TyUnusedParam => write!(f, "[unused type param]"), + TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => write!(f, "[unused type param]"), TyAdt(def, substs) => cx.parameterized(f, substs, def.did, &[]), TyDynamic(data, r) => { data.print(f, cx)?; diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 83c4448fc1bcf..30cea94493440 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -705,7 +705,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { ty::TyForeign(..) => FfiSafe, ty::TyParam(..) | - ty::TyUnusedParam | + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | ty::TyInfer(..) | ty::TyError | ty::TyClosure(..) | diff --git a/src/librustc_mir/monomorphize/deduplicate_instances.rs b/src/librustc_mir/monomorphize/deduplicate_instances.rs index 0e1d9277e6fa9..929b3e952b4fb 100644 --- a/src/librustc_mir/monomorphize/deduplicate_instances.rs +++ b/src/librustc_mir/monomorphize/deduplicate_instances.rs @@ -9,9 +9,10 @@ // except according to those terms. use rustc_data_structures::indexed_vec::IndexVec; -use rustc::ty::{self, TyCtxt, Ty, ParamTy, TypeFoldable, Instance}; +use rustc::ty::{self, TyCtxt, Ty, TypeVariants, ParamTy, TypeFoldable, Instance, ParamEnv}; use rustc::ty::fold::TypeFolder; use rustc::ty::subst::{Kind, UnpackedKind}; +use rustc::ty::layout::{LayoutCx, LayoutOf}; use rustc::middle::const_val::ConstVal; use rustc::mir::{Mir, Rvalue, Location}; use rustc::mir::visit::{Visitor, TyContext}; @@ -42,7 +43,6 @@ pub(crate) fn collapse_interchangable_instances<'a, 'tcx>( } match instance.ty(tcx).sty { ty::TyFnDef(def_id, _) => { - //let attrs = tcx.item_attrs(def_id); if tcx.lang_items().items().iter().find(|l|**l == Some(def_id)).is_some() { return instance; // Lang items dont work otherwise } @@ -51,7 +51,7 @@ pub(crate) fn collapse_interchangable_instances<'a, 'tcx>( } let used_substs = used_substs_for_instance(tcx, instance); - instance.substs = tcx._intern_substs(&instance.substs.into_iter().enumerate().map(|(i, subst)| { + instance.substs = tcx.intern_substs(&instance.substs.into_iter().enumerate().map(|(i, subst)| { if let UnpackedKind::Type(ty) = subst.unpack() { let ty = match used_substs.parameters[ParamIdx(i as u32)] { ParamUsage::Unused => { @@ -89,7 +89,16 @@ pub(crate) fn collapse_interchangable_instances<'a, 'tcx>( tcx.mk_ty(ty::TyNever) } } - ParamUsage::LayoutUsed | ParamUsage::Used => ty.into(), + ParamUsage::LayoutUsed => { + let layout_cx = LayoutCx { + tcx, + param_env: ParamEnv::reveal_all(), + }; + let layout = layout_cx.layout_of(ty).unwrap(); + let (size, align) = layout.size_and_align(); + tcx.mk_ty(TypeVariants::TyLayoutOnlyParam(size, align)) + } + ParamUsage::Used => ty.into(), }; Kind::from(ty) } else { diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 8a7ddd5db22bb..889afc8d153a3 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -387,7 +387,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { ty::TyInfer(_) | ty::TyProjection(..) | ty::TyParam(_) | - ty::TyUnusedParam | + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | ty::TyGeneratorWitness(_) | ty::TyAnon(..) => { bug!("DefPathBasedNames: Trying to create type name for \ diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs index 71118792c71b8..80eedd7f4c2ec 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/src/librustc_traits/dropck_outlives.rs @@ -239,7 +239,9 @@ fn dtorck_constraint_for_ty<'a, 'gcx, 'tcx>( Err(NoSolution) } - ty::TyUnusedParam => bug!("Unexpected TyUnusedParam in dtorck_constraint_for_ty"), + ty::TyUnusedParam | ty::TyLayoutOnlyParam(..) => { + bug!("Unexpected {:?} in dtorck_constraint_for_ty", ty); + } }; debug!("dtorck_constraint_for_ty({:?}) = {:?}", ty, result); diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index b407ce5ff9000..3bc6faf253628 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -171,7 +171,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ty::TyGenerator(..) => { output.push_str("generator"); } - ty::TyUnusedParam => { + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => { output.push_str("[unused type param]"); } ty::TyError | diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index e2bf8dcc95088..8a742f1b61003 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -137,7 +137,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { span, &format!("`{:?}` should be sized but is not?", t)); return Err(ErrorReported); } - ty::TyUnusedParam => bug!("Unexpected TyUnusedParam in FnCtxt::pointer_kind"), + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => bug!("Unexpected TyUnusedParam in FnCtxt::pointer_kind"), }) } } diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 67e7481a3c416..ae5429f50dcf0 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -334,7 +334,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { // types, where we use TyError as the Self type } - ty::TyUnusedParam | + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | ty::TyGeneratorWitness(..) | ty::TyInfer(..) => { bug!("unexpected type encountered in \ diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c8d80914d33f7..a10f468c9ae23 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2836,7 +2836,7 @@ impl<'tcx> Clean for Ty<'tcx> { ty::TyClosure(..) | ty::TyGenerator(..) => Tuple(vec![]), // FIXME(pcwalton) - ty::TyUnusedParam => panic!("TyUnusedParam"), + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => panic!("TyUnusedParam"), ty::TyGeneratorWitness(..) => panic!("TyGeneratorWitness"), ty::TyInfer(..) => panic!("TyInfer"), ty::TyError => panic!("TyError"), From 598350c99d349d495e209ce1639be15b127b44ff Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 9 Mar 2018 10:30:17 +0100 Subject: [PATCH 17/21] Fix tidy errors --- src/librustc/infer/freshen.rs | 4 +++- src/librustc/traits/error_reporting.rs | 4 +++- src/librustc/traits/select.rs | 7 +++++-- src/librustc/ty/flags.rs | 4 +++- src/librustc/ty/layout.rs | 7 ++++--- src/librustc/ty/outlives.rs | 4 +++- src/librustc/ty/structural_impls.rs | 6 ++++-- src/librustc/ty/util.rs | 4 +++- src/librustc/ty/walk.rs | 4 ++-- src/librustc_typeck/check/cast.rs | 4 +++- 10 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index 3f0e24ec1b997..e8a1029a16937 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -200,7 +200,9 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { ty::TyAnon(..) => { t.super_fold_with(self) } - ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => bug!("Unexpected TyUnusedParam in TypeFreshener"), + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => { + bug!("Unexpected {:?} in TypeFreshener", t); + } } } } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index a16e6ba105ccc..ff34a100b83ca 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -264,7 +264,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ty::TyForeign(..) => Some(19), ty::TyGeneratorWitness(..) => Some(20), ty::TyInfer(..) | ty::TyError => None, - ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => bug!("unexpected TyUnusedParam in fuzzy_match_tys"), + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => { + bug!("unexpected {:?} in fuzzy_match_tys", t); + } } } diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 821219c5c313d..d8dd2e40c5505 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2037,7 +2037,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { )) } - ty::TyProjection(_) | ty::TyParam(_) | ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | ty::TyAnon(..) => None, + ty::TyProjection(_) | ty::TyParam(_) | ty::TyUnusedParam | + ty::TyLayoutOnlyParam(_, _) | ty::TyAnon(..) => None, ty::TyInfer(ty::TyVar(_)) => Ambiguous, ty::TyInfer(ty::CanonicalTy(_)) | @@ -2114,7 +2115,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty); } - ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => bug!("Unexpected TyUnusedParam in copy_clone_conditions"), + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => { + bug!("Unexpected {:?} in copy_clone_conditions", self_ty); + } } } diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index e307117bae7eb..2404f969b2181 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -190,7 +190,9 @@ impl FlagComputation { &ty::TyFnPtr(f) => { self.add_fn_sig(f); } - &ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => bug!("Unexpected TyUnusedParam in FlagComputation::for_sty"), + &ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => { + bug!("Unexpected {:?} in FlagComputation::for_sty", st); + } } } diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 77db77f686201..bc02b607c4697 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1712,7 +1712,8 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { ty::TyParam(_) => { return Err(LayoutError::Unknown(ty)); } - ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | ty::TyGeneratorWitness(..) | ty::TyInfer(_) | ty::TyError => { + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | ty::TyGeneratorWitness(..) | + ty::TyInfer(_) | ty::TyError => { bug!("LayoutDetails::compute: unexpected type `{}`", ty) } }) @@ -2287,8 +2288,8 @@ impl<'a, 'tcx> TyLayout<'tcx> { } } - ty::TyProjection(_) | ty::TyAnon(..) | ty::TyParam(_) | ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | - ty::TyInfer(_) | ty::TyError => { + ty::TyProjection(_) | ty::TyAnon(..) | ty::TyParam(_) | ty::TyUnusedParam | + ty::TyLayoutOnlyParam(_, _) | ty::TyInfer(_) | ty::TyError => { bug!("TyLayout::field_type: unexpected type `{}`", self.ty) } }) diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs index a7fc440785e1f..a7ce0a512054c 100644 --- a/src/librustc/ty/outlives.rs +++ b/src/librustc/ty/outlives.rs @@ -167,7 +167,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.compute_components(subty, out); } } - ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => bug!("Unexpected TyUnusedParam in compute_components"), + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => { + bug!("Unexpected TyUnusedParam in compute_components"); + } } } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 353eda6dd4f5d..13e9b9144584e 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -865,7 +865,8 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::TyAnon(did, substs) => ty::TyAnon(did, substs.fold_with(folder)), ty::TyBool | ty::TyChar | ty::TyStr | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyError | ty::TyInfer(_) | - ty::TyParam(..) | ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | ty::TyNever | ty::TyForeign(..) => return self + ty::TyParam(..) | ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | + ty::TyNever | ty::TyForeign(..) => return self }; if self.sty == sty { @@ -900,7 +901,8 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::TyAnon(_, ref substs) => substs.visit_with(visitor), ty::TyBool | ty::TyChar | ty::TyStr | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyError | ty::TyInfer(_) | - ty::TyParam(..) | ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | ty::TyNever | ty::TyForeign(..) => false, + ty::TyParam(..) | ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | + ty::TyNever | ty::TyForeign(..) => false, } } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 1f88a53837ed6..582380f3cb556 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -1126,7 +1126,9 @@ fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, |variant| variant.fields.iter().any( |field| needs_drop(field.ty(tcx, substs)))), - ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => bug!("Unexpected TyUnusedParam in needs_drop_raw"), + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => { + bug!("Unexpected type {:?} in needs_drop_raw", ty); + } } } diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index 9cc067f24feaf..022bcf790b1f2 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -82,8 +82,8 @@ pub fn walk_shallow<'tcx>(ty: Ty<'tcx>) -> AccIntoIter> { fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) { match parent_ty.sty { ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | - ty::TyStr | ty::TyInfer(_) | ty::TyParam(_) | ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | ty::TyNever | - ty::TyError | ty::TyForeign(..) => { + ty::TyStr | ty::TyInfer(_) | ty::TyParam(_) | ty::TyUnusedParam | + ty::TyLayoutOnlyParam(_, _) | ty::TyNever | ty::TyError | ty::TyForeign(..) => { } ty::TyArray(ty, len) => { push_const(stack, len); diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 8a742f1b61003..64f262ce7958b 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -137,7 +137,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { span, &format!("`{:?}` should be sized but is not?", t)); return Err(ErrorReported); } - ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => bug!("Unexpected TyUnusedParam in FnCtxt::pointer_kind"), + ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => { + bug!("Unexpected {:?} in FnCtxt::pointer_kind", t); + } }) } } From ad132c073d1052d7bb811546c318b4e363d1ca8a Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 14 Mar 2018 14:09:07 +0100 Subject: [PATCH 18/21] Correct TypeVariants' HashStable impl --- src/librustc/ich/impls_ty.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index d3de8e4380080..cd9c9ef5dd8aa 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -834,9 +834,13 @@ for ty::TypeVariants<'gcx> TyStr | TyError | TyNever | - TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => { + TyUnusedParam => { // Nothing more to hash. } + TyLayoutOnlyParam(size, align) => { + size.hash_stable(hcx, hasher); + align.hash_stable(hcx, hasher); + } TyInt(int_ty) => { int_ty.hash_stable(hcx, hasher); } From 5ca40947bfa834e72cc81e0e0fa2fba839f7bc62 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 14 Mar 2018 14:10:08 +0100 Subject: [PATCH 19/21] Better code formatting --- src/librustc/traits/coherence.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index 5294c1b831066..ff17d188f7064 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -481,7 +481,8 @@ fn ty_is_local_constructor(ty: Ty, in_crate: InCrate) -> bool { ty::TyGenerator(..) | ty::TyGeneratorWitness(..) | ty::TyAnon(..) | - ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => { + ty::TyUnusedParam | + ty::TyLayoutOnlyParam(_, _) => { bug!("ty_is_local invoked on unexpected type: {:?}", ty) } } From b4b51d6c910febf35fb4223a42b28c838997a475 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 14 Mar 2018 14:59:26 +0100 Subject: [PATCH 20/21] Hopefully partially fix debuginfo --- src/librustc_trans/debuginfo/mod.rs | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 342d21c0e60af..5341ee6b2d6e8 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -30,7 +30,8 @@ use abi::Abi; use common::CodegenCx; use builder::Builder; use monomorphize::Instance; -use rustc::ty::{self, ParamEnv, Ty}; +use rustc::ty::{self, TyCtxt, ParamEnv, Ty, TypeFoldable}; +use rustc::ty::fold::TypeFolder; use rustc::mir; use rustc::session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo}; use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet}; @@ -201,13 +202,30 @@ pub fn finalize(cx: &CodegenCx) { /// for debug info creation. The function may also return another variant of the /// FunctionDebugContext enum which indicates why no debuginfo should be created /// for the function. -pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, +pub fn create_function_debug_context<'a, 'tcx>(cx: &'a CodegenCx<'a, 'tcx>, instance: Instance<'tcx>, sig: ty::FnSig<'tcx>, llfn: ValueRef, - mir: &mir::Mir) -> FunctionDebugContext { - let has_unused_subst = true; // FIXME: make it work with TyUnusedSubst - if cx.sess().opts.debuginfo == NoDebugInfo || has_unused_subst { + mir: &'a mir::Mir<'tcx>) -> FunctionDebugContext { + struct UnusedParamVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a>(TyCtxt<'a, 'gcx, 'tcx>, bool); + impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for UnusedParamVisitor<'a, 'gcx, 'tcx> { + fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { + self.0 + } + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + match ty.sty { + ty::TyUnusedParam => { + self.1 = true; + } + _ => {} + } + ty.super_fold_with(self) + } + } + let mut has_unused_param_visitor = UnusedParamVisitor(cx.tcx, false); + mir.fold_with(&mut has_unused_param_visitor); + + if cx.sess().opts.debuginfo == NoDebugInfo || has_unused_param_visitor.1 { return FunctionDebugContext::DebugInfoDisabled; } From 7a158b049ea88a04d810b83ad8c9e3af07e89a9c Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 18 Mar 2018 18:25:00 +0100 Subject: [PATCH 21/21] Fix tidy error --- src/librustc_trans/debuginfo/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 5341ee6b2d6e8..eea84f6d25dea 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -208,7 +208,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &'a CodegenCx<'a, 'tcx>, llfn: ValueRef, mir: &'a mir::Mir<'tcx>) -> FunctionDebugContext { struct UnusedParamVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a>(TyCtxt<'a, 'gcx, 'tcx>, bool); - impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for UnusedParamVisitor<'a, 'gcx, 'tcx> { + impl<'a, 'gcx: 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for UnusedParamVisitor<'a, 'gcx, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.0 }