Auto merge of #94733 - nnethercote:fix-AdtDef-interning, r=fee1-dead
Improve `AdtDef` interning. This commit makes `AdtDef` use `Interned`. Much of the commit is tedious changes to introduce getter functions. The interesting changes are in `compiler/rustc_middle/src/ty/adt.rs`. r? `@fee1-dead`
This commit is contained in:
commit
012720ffb0
169 changed files with 702 additions and 687 deletions
|
@ -105,13 +105,13 @@ fn const_to_valtree_inner<'tcx>(
|
|||
ty::Array(_, len) => branches(usize::try_from(len.eval_usize(ecx.tcx.tcx, ecx.param_env)).unwrap(), None),
|
||||
|
||||
ty::Adt(def, _) => {
|
||||
if def.variants.is_empty() {
|
||||
if def.variants().is_empty() {
|
||||
bug!("uninhabited types should have errored and never gotten converted to valtree")
|
||||
}
|
||||
|
||||
let variant = ecx.read_discriminant(&place.into()).unwrap().1;
|
||||
|
||||
branches(def.variants[variant].fields.len(), def.is_enum().then_some(variant))
|
||||
branches(def.variant(variant).fields.len(), def.is_enum().then_some(variant))
|
||||
}
|
||||
|
||||
ty::Never
|
||||
|
@ -150,11 +150,11 @@ pub(crate) fn try_destructure_const<'tcx>(
|
|||
// Checks if we have any variants, to avoid downcasting to a non-existing variant (when
|
||||
// there are no variants `read_discriminant` successfully returns a non-existing variant
|
||||
// index).
|
||||
ty::Adt(def, _) if def.variants.is_empty() => throw_ub!(Unreachable),
|
||||
ty::Adt(def, _) if def.variants().is_empty() => throw_ub!(Unreachable),
|
||||
ty::Adt(def, _) => {
|
||||
let variant = ecx.read_discriminant(&op)?.1;
|
||||
let down = ecx.operand_downcast(&op, variant)?;
|
||||
(def.variants[variant].fields.len(), Some(variant), down)
|
||||
(def.variant(variant).fields.len(), Some(variant), down)
|
||||
}
|
||||
ty::Tuple(substs) => (substs.len(), None, op),
|
||||
_ => bug!("cannot destructure constant {:?}", val),
|
||||
|
|
|
@ -174,7 +174,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: CompileTimeMachine<'mir, 'tcx, const_eval::Memory
|
|||
}
|
||||
|
||||
if let Some(def) = mplace.layout.ty.ty_adt_def() {
|
||||
if Some(def.did) == self.ecx.tcx.lang_items().unsafe_cell_type() {
|
||||
if Some(def.did()) == self.ecx.tcx.lang_items().unsafe_cell_type() {
|
||||
// We are crossing over an `UnsafeCell`, we can mutate again. This means that
|
||||
// References we encounter inside here are interned as pointing to mutable
|
||||
// allocations.
|
||||
|
|
|
@ -73,7 +73,9 @@ crate fn eval_nullary_intrinsic<'tcx>(
|
|||
}
|
||||
sym::variant_count => match tp_ty.kind() {
|
||||
// Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
|
||||
ty::Adt(ref adt, _) => ConstValue::from_machine_usize(adt.variants.len() as u64, &tcx),
|
||||
ty::Adt(ref adt, _) => {
|
||||
ConstValue::from_machine_usize(adt.variants().len() as u64, &tcx)
|
||||
}
|
||||
ty::Projection(_)
|
||||
| ty::Opaque(_, _)
|
||||
| ty::Param(_)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_hir::def_id::CrateNum;
|
||||
use rustc_hir::definitions::DisambiguatedDefPathData;
|
||||
use rustc_middle::mir::interpret::{Allocation, ConstAllocation};
|
||||
|
@ -56,7 +57,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
|
|||
}
|
||||
|
||||
// Types with identity (print the module path).
|
||||
ty::Adt(&ty::AdtDef { did: def_id, .. }, substs)
|
||||
ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), substs)
|
||||
| ty::FnDef(def_id, substs)
|
||||
| ty::Opaque(def_id, substs)
|
||||
| ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs })
|
||||
|
|
|
@ -759,7 +759,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
.ty
|
||||
.ty_adt_def()
|
||||
.expect("tagged layout for non adt")
|
||||
.variants
|
||||
.variants()
|
||||
.len();
|
||||
assert!(usize::try_from(variant_index).unwrap() < variants_len);
|
||||
VariantIdx::from_u32(variant_index)
|
||||
|
|
|
@ -267,7 +267,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
match layout.variants {
|
||||
Variants::Single { index } => {
|
||||
// Inside a variant
|
||||
PathElem::Field(def.variants[index].fields[field].name)
|
||||
PathElem::Field(def.variant(index).fields[field].name)
|
||||
}
|
||||
Variants::Multiple { .. } => bug!("we handled variants above"),
|
||||
}
|
||||
|
@ -734,7 +734,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
|||
new_op: &OpTy<'tcx, M::PointerTag>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let name = match old_op.layout.ty.kind() {
|
||||
ty::Adt(adt, _) => PathElem::Variant(adt.variants[variant_id].name),
|
||||
ty::Adt(adt, _) => PathElem::Variant(adt.variant(variant_id).name),
|
||||
// Generators also have variants
|
||||
ty::Generator(..) => PathElem::GeneratorState(variant_id),
|
||||
_ => bug!("Unexpected type with variant: {:?}", old_op.layout.ty),
|
||||
|
@ -771,7 +771,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
|||
// Special check preventing `UnsafeCell` in the inner part of constants
|
||||
if let Some(def) = op.layout.ty.ty_adt_def() {
|
||||
if matches!(self.ctfe_mode, Some(CtfeValidationMode::Const { inner: true, .. }))
|
||||
&& Some(def.did) == self.ecx.tcx.lang_items().unsafe_cell_type()
|
||||
&& Some(def.did()) == self.ecx.tcx.lang_items().unsafe_cell_type()
|
||||
{
|
||||
throw_validation_failure!(self.path, { "`UnsafeCell` in a `const`" });
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ pub trait Qualif {
|
|||
/// Returning `true` for `in_adt_inherently` but `false` for `in_any_value_of_ty` is unsound.
|
||||
fn in_adt_inherently<'tcx>(
|
||||
cx: &ConstCx<'_, 'tcx>,
|
||||
adt: &'tcx AdtDef,
|
||||
adt: AdtDef<'tcx>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> bool;
|
||||
}
|
||||
|
@ -96,12 +96,12 @@ impl Qualif for HasMutInterior {
|
|||
|
||||
fn in_adt_inherently<'tcx>(
|
||||
cx: &ConstCx<'_, 'tcx>,
|
||||
adt: &'tcx AdtDef,
|
||||
adt: AdtDef<'tcx>,
|
||||
_: SubstsRef<'tcx>,
|
||||
) -> bool {
|
||||
// Exactly one type, `UnsafeCell`, has the `HasMutInterior` qualif inherently.
|
||||
// It arises structurally for all other types.
|
||||
Some(adt.did) == cx.tcx.lang_items().unsafe_cell_type()
|
||||
Some(adt.did()) == cx.tcx.lang_items().unsafe_cell_type()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,7 @@ impl Qualif for NeedsDrop {
|
|||
|
||||
fn in_adt_inherently<'tcx>(
|
||||
cx: &ConstCx<'_, 'tcx>,
|
||||
adt: &'tcx AdtDef,
|
||||
adt: AdtDef<'tcx>,
|
||||
_: SubstsRef<'tcx>,
|
||||
) -> bool {
|
||||
adt.has_dtor(cx.tcx)
|
||||
|
@ -205,7 +205,7 @@ impl Qualif for NeedsNonConstDrop {
|
|||
|
||||
fn in_adt_inherently<'tcx>(
|
||||
cx: &ConstCx<'_, 'tcx>,
|
||||
adt: &'tcx AdtDef,
|
||||
adt: AdtDef<'tcx>,
|
||||
_: SubstsRef<'tcx>,
|
||||
) -> bool {
|
||||
adt.has_non_const_dtor(cx.tcx)
|
||||
|
@ -233,7 +233,7 @@ impl Qualif for CustomEq {
|
|||
|
||||
fn in_adt_inherently<'tcx>(
|
||||
cx: &ConstCx<'_, 'tcx>,
|
||||
adt: &'tcx AdtDef,
|
||||
adt: AdtDef<'tcx>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> bool {
|
||||
let ty = cx.tcx.mk_ty(ty::Adt(adt, substs));
|
||||
|
|
|
@ -55,7 +55,7 @@ where
|
|||
ProjectionElem::Field(..) => {
|
||||
let ty = place_base.ty(local_decls, tcx).ty;
|
||||
match ty.kind() {
|
||||
ty::Adt(def, _) => return def.repr.pack,
|
||||
ty::Adt(def, _) => return def.repr().pack,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ pub fn call_kind<'tcx>(
|
|||
.parent(method_did)
|
||||
.filter(|did| tcx.def_kind(*did) == rustc_hir::def::DefKind::Impl)
|
||||
.and_then(|did| match tcx.type_of(did).kind() {
|
||||
ty::Adt(def, ..) => Some(def.did),
|
||||
ty::Adt(def, ..) => Some(def.did()),
|
||||
_ => None,
|
||||
});
|
||||
let is_option_or_result = parent_self_ty.map_or(false, |def_id| {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue