Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Deduplicate instances #48139

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>) },

Expand Down
7 changes: 6 additions & 1 deletion src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -833,9 +833,14 @@ for ty::TypeVariants<'gcx>
TyChar |
TyStr |
TyError |
TyNever => {
TyNever |
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);
}
Expand Down
4 changes: 3 additions & 1 deletion src/librustc/infer/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,9 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
| ty::TyProjection(..)
| ty::TyForeign(..)
| ty::TyParam(..)
| ty::TyAnon(..) => {
| ty::TyAnon(..)
| ty::TyUnusedParam
| ty::TyLayoutOnlyParam(..) => {
if t.flags.intersects(self.needs_canonical_flags) {
t.super_fold_with(self)
} else {
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/infer/freshen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +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 {:?} in TypeFreshener", t);
}
}
}
}
4 changes: 3 additions & 1 deletion src/librustc/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,9 @@ fn ty_is_local_constructor(ty: Ty, in_crate: InCrate) -> bool {
ty::TyClosure(..) |
ty::TyGenerator(..) |
ty::TyGeneratorWitness(..) |
ty::TyAnon(..) => {
ty::TyAnon(..) |
ty::TyUnusedParam |
ty::TyLayoutOnlyParam(_, _) => {
bug!("ty_is_local invoked on unexpected type: {:?}", ty)
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,10 @@ 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 | ty::TyLayoutOnlyParam(_, _) => {
bug!("unexpected {:?} in fuzzy_match_tys", t);
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/librustc/traits/query/dropck_outlives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,5 +261,9 @@ fn trivial_dropck_outlives<'cx, 'tcx>(tcx: TyCtxt<'cx, '_, 'tcx>, ty: Ty<'tcx>)
| ty::TyAnon(..)
| ty::TyInfer(_)
| ty::TyGenerator(..) => false,

ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => {
bug!("Unexpected {:?} in trivial_dropck_outlives", ty)
}
}
}
8 changes: 7 additions & 1 deletion src/librustc/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2037,7 +2037,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
))
}

ty::TyProjection(_) | ty::TyParam(_) | ty::TyAnon(..) => None,
ty::TyProjection(_) | ty::TyParam(_) | ty::TyUnusedParam |
ty::TyLayoutOnlyParam(_, _) | ty::TyAnon(..) => None,
ty::TyInfer(ty::TyVar(_)) => Ambiguous,

ty::TyInfer(ty::CanonicalTy(_)) |
Expand Down Expand Up @@ -2114,6 +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 {:?} in copy_clone_conditions", self_ty);
}
}
}

Expand Down Expand Up @@ -2150,6 +2154,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
ty::TyForeign(..) |
ty::TyProjection(..) |
ty::TyInfer(ty::CanonicalTy(_)) |
ty::TyUnusedParam |
ty::TyLayoutOnlyParam(_, _) |
ty::TyInfer(ty::TyVar(_)) |
ty::TyInfer(ty::FreshTy(_)) |
ty::TyInfer(ty::FreshIntTy(_)) |
Expand Down
4 changes: 3 additions & 1 deletion src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1780,13 +1780,15 @@ 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() {
let variant = match t.sty {
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);
Expand Down Expand Up @@ -1827,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());
Expand Down
1 change: 1 addition & 0 deletions src/librustc/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
"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(),
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/fast_reject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 | ty::TyLayoutOnlyParam(_, _) => None,
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/librustc/ty/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ impl FlagComputation {
&ty::TyFnPtr(f) => {
self.add_fn_sig(f);
}
&ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => {
bug!("Unexpected {:?} in FlagComputation::for_sty", st);
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/librustc/ty/item_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option<DefId> {
ty::TyProjection(_) |
ty::TyParam(_) |
ty::TyAnon(..) |
ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) |
ty::TyInfer(_) |
ty::TyError |
ty::TyGeneratorWitness(..) |
Expand Down
9 changes: 5 additions & 4 deletions src/librustc/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -1712,7 +1712,8 @@ 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::TyLayoutOnlyParam(_, _) | ty::TyGeneratorWitness(..) |
ty::TyInfer(_) | ty::TyError => {
bug!("LayoutDetails::compute: unexpected type `{}`", ty)
}
})
Expand Down Expand Up @@ -2287,8 +2288,8 @@ impl<'a, 'tcx> TyLayout<'tcx> {
}
}

ty::TyProjection(_) | ty::TyAnon(..) | ty::TyParam(_) |
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)
}
})
Expand Down
6 changes: 6 additions & 0 deletions src/librustc/ty/maps/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
11 changes: 11 additions & 0 deletions src/librustc/ty/maps/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,9 @@ define_maps! { <'tcx>
[] fn wasm_custom_sections: WasmCustomSections(CrateNum) -> Lrc<Vec<DefId>>,
[] fn wasm_import_module_map: WasmImportModuleMap(CrateNum)
-> Lrc<FxHashMap<DefId, String>>,

[] fn collapse_interchangable_instances:
collapse_interchangable_instances_dep_node(ty::Instance<'tcx>) -> ty::Instance<'tcx>,
}

//////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -592,3 +595,11 @@ 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,
}
}
1 change: 1 addition & 0 deletions src/librustc/ty/maps/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down
49 changes: 48 additions & 1 deletion src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -2067,7 +2069,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
}
}

TyInfer(..) => {
TyUnusedParam | ty::TyLayoutOnlyParam(_, _) | TyInfer(..) => {
bug!("unexpected type `{:?}` in sized_constraint_for_ty",
ty)
}
Expand Down Expand Up @@ -2811,3 +2813,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)
}
}
3 changes: 3 additions & 0 deletions src/librustc/ty/outlives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +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");
}
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/librustc/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::TyNever | ty::TyForeign(..) => return self
ty::TyParam(..) | ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) |
ty::TyNever | ty::TyForeign(..) => return self
};

if self.sty == sty {
Expand Down Expand Up @@ -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::TyNever | ty::TyForeign(..) => false,
ty::TyParam(..) | ty::TyUnusedParam | ty::TyLayoutOnlyParam(_, _) |
ty::TyNever | ty::TyForeign(..) => false,
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -164,6 +165,12 @@ pub enum TypeVariants<'tcx> {
/// A type parameter; for example, `T` in `fn f<T>(x: T) {}
TyParam(ParamTy),

/// 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),

Expand Down Expand Up @@ -1633,6 +1640,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
TyTuple(..) |
TyForeign(..) |
TyParam(_) |
TyUnusedParam | ty::TyLayoutOnlyParam(_, _) |
TyInfer(_) |
TyError => {
vec![]
Expand Down
7 changes: 7 additions & 0 deletions src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,9 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W>
TyStr |
TySlice(_) => {}

// This can be generated by collapse_interchangable_instances
TyUnusedParam | ty::TyLayoutOnlyParam(_, _) => self.hash("<unused param>"),

TyError |
TyInfer(_) => bug!("TypeIdHasher: unexpected type {}", ty)
}
Expand Down Expand Up @@ -1122,6 +1125,10 @@ 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 | ty::TyLayoutOnlyParam(_, _) => {
bug!("Unexpected type {:?} in needs_drop_raw", ty);
}
}
}

Expand Down
Loading