Unnamed repository; edit this file 'description' to name the repository.
Do not intern `AdtDef`
rustc uses this struct to store all information about an ADT, but we have other types and are mainly using it for the solver. So store only the information we need.
Chayim Refael Friedman 3 weeks ago
parent 3d3e23e · commit c018637
-rw-r--r--Cargo.lock1
-rw-r--r--crates/hir-def/src/attrs.rs78
-rw-r--r--crates/hir-def/src/signatures.rs24
-rw-r--r--crates/hir-ty/Cargo.toml1
-rw-r--r--crates/hir-ty/src/diagnostics/expr.rs4
-rw-r--r--crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs12
-rw-r--r--crates/hir-ty/src/display.rs14
-rw-r--r--crates/hir-ty/src/drop.rs2
-rw-r--r--crates/hir-ty/src/infer.rs6
-rw-r--r--crates/hir-ty/src/infer/cast.rs4
-rw-r--r--crates/hir-ty/src/infer/closure/analysis.rs2
-rw-r--r--crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs6
-rw-r--r--crates/hir-ty/src/infer/expr.rs6
-rw-r--r--crates/hir-ty/src/infer/pat.rs4
-rw-r--r--crates/hir-ty/src/inhabitedness.rs7
-rw-r--r--crates/hir-ty/src/layout.rs6
-rw-r--r--crates/hir-ty/src/method_resolution/probe.rs4
-rw-r--r--crates/hir-ty/src/mir/eval.rs16
-rw-r--r--crates/hir-ty/src/mir/eval/shim.rs4
-rw-r--r--crates/hir-ty/src/mir/eval/shim/simd.rs2
-rw-r--r--crates/hir-ty/src/mir/lower.rs4
-rw-r--r--crates/hir-ty/src/next_solver/interner.rs359
-rw-r--r--crates/hir-ty/src/next_solver/ty.rs8
-rw-r--r--crates/hir-ty/src/next_solver/util.rs2
-rw-r--r--crates/hir-ty/src/representability.rs6
-rw-r--r--crates/hir-ty/src/tests/closure_captures.rs4
-rw-r--r--crates/hir-ty/src/traits.rs10
-rw-r--r--crates/hir-ty/src/variance.rs7
-rw-r--r--crates/hir/src/lib.rs14
-rw-r--r--crates/hir/src/source_analyzer.rs6
-rw-r--r--crates/ide-completion/src/tests/flyimport.rs2
31 files changed, 270 insertions, 355 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 768c3a9aa6..0b3fd2b8ea 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -876,6 +876,7 @@ version = "0.0.0"
dependencies = [
"arrayvec",
"base-db",
+ "bitflags 2.9.4",
"cov-mark",
"either",
"ena",
diff --git a/crates/hir-def/src/attrs.rs b/crates/hir-def/src/attrs.rs
index 5cf5a9b6be..5dc410be27 100644
--- a/crates/hir-def/src/attrs.rs
+++ b/crates/hir-def/src/attrs.rs
@@ -724,52 +724,56 @@ impl AttrFlags {
return None;
}
- return repr(db, owner);
+ Self::repr_assume_has(db, owner)
+ }
- #[salsa::tracked]
- fn repr(db: &dyn DefDatabase, owner: AdtId) -> Option<ReprOptions> {
- let mut result = None;
- collect_attrs::<Infallible>(db, owner.into(), |attr| {
- let mut current = None;
- if let ast::Meta::TokenTreeMeta(attr) = &attr
- && let Some(path) = attr.path()
- && let Some(tt) = attr.token_tree()
+ /// Only call this when you've verified the type indeed has a `#[repr]` attribute!
+ ///
+ /// Prefer [`AttrFlags::repr()`] in non-perf-sensitive places as it also has a check that
+ /// that the ADT has repr.
+ #[salsa::tracked]
+ pub fn repr_assume_has(db: &dyn DefDatabase, owner: AdtId) -> Option<ReprOptions> {
+ let mut result = None;
+ collect_attrs::<Infallible>(db, owner.into(), |attr| {
+ let mut current = None;
+ if let ast::Meta::TokenTreeMeta(attr) = &attr
+ && let Some(path) = attr.path()
+ && let Some(tt) = attr.token_tree()
+ {
+ if path.is1("repr")
+ && let Some(repr) = parse_repr_tt(&tt)
{
- if path.is1("repr")
- && let Some(repr) = parse_repr_tt(&tt)
- {
- current = Some(repr);
- } else if path.is1("rustc_scalable_vector")
- && let mut tt = TokenTreeChildren::new(&tt)
- && let Some(NodeOrToken::Token(scalable)) = tt.next()
- && let Some(scalable) = ast::IntNumber::cast(scalable)
- && let Ok(scalable) = scalable.value()
- && let Ok(scalable) = scalable.try_into()
- {
- current = Some(ReprOptions {
- scalable: Some(rustc_abi::ScalableElt::ElementCount(scalable)),
- ..ReprOptions::default()
- });
- }
- } else if let ast::Meta::PathMeta(attr) = &attr
- && attr.path().is1("rustc_scalable_vector")
+ current = Some(repr);
+ } else if path.is1("rustc_scalable_vector")
+ && let mut tt = TokenTreeChildren::new(&tt)
+ && let Some(NodeOrToken::Token(scalable)) = tt.next()
+ && let Some(scalable) = ast::IntNumber::cast(scalable)
+ && let Ok(scalable) = scalable.value()
+ && let Ok(scalable) = scalable.try_into()
{
current = Some(ReprOptions {
- scalable: Some(rustc_abi::ScalableElt::Container),
+ scalable: Some(rustc_abi::ScalableElt::ElementCount(scalable)),
..ReprOptions::default()
});
}
+ } else if let ast::Meta::PathMeta(attr) = &attr
+ && attr.path().is1("rustc_scalable_vector")
+ {
+ current = Some(ReprOptions {
+ scalable: Some(rustc_abi::ScalableElt::Container),
+ ..ReprOptions::default()
+ });
+ }
- if let Some(current) = current {
- match &mut result {
- Some(existing) => merge_repr(existing, current),
- None => result = Some(current),
- }
+ if let Some(current) = current {
+ match &mut result {
+ Some(existing) => merge_repr(existing, current),
+ None => result = Some(current),
}
- ControlFlow::Continue(())
- });
- result
- }
+ }
+ ControlFlow::Continue(())
+ });
+ result
}
/// Call this only if there are legacy const generics, to save memory.
diff --git a/crates/hir-def/src/signatures.rs b/crates/hir-def/src/signatures.rs
index 474b238add..8136e11412 100644
--- a/crates/hir-def/src/signatures.rs
+++ b/crates/hir-def/src/signatures.rs
@@ -128,13 +128,11 @@ impl StructSignature {
source_map,
)
}
-}
-impl StructSignature {
#[inline]
pub fn repr(&self, db: &dyn DefDatabase, id: StructId) -> Option<ReprOptions> {
if self.flags.contains(StructFlags::HAS_REPR) {
- AttrFlags::repr(db, id.into())
+ AttrFlags::repr_assume_has(db, id.into())
} else {
None
}
@@ -202,6 +200,15 @@ impl UnionSignature {
source_map,
)
}
+
+ #[inline]
+ pub fn repr(&self, db: &dyn DefDatabase, id: UnionId) -> Option<ReprOptions> {
+ if self.flags.contains(StructFlags::HAS_REPR) {
+ AttrFlags::repr_assume_has(db, id.into())
+ } else {
+ None
+ }
+ }
}
bitflags! {
@@ -211,6 +218,8 @@ bitflags! {
const HAS_REPR = 1 << 0;
/// Indicates whether the enum has a `#[rustc_has_incoherent_inherent_impls]` attribute.
const RUSTC_HAS_INCOHERENT_INHERENT_IMPLS = 1 << 1;
+ /// Whether this enum has `#[fundamental]`.
+ const FUNDAMENTAL = 1 << 2;
}
}
@@ -243,6 +252,9 @@ impl EnumSignature {
if attrs.contains(AttrFlags::HAS_REPR) {
flags |= EnumFlags::HAS_REPR;
}
+ if attrs.contains(AttrFlags::FUNDAMENTAL) {
+ flags |= EnumFlags::FUNDAMENTAL;
+ }
let InFile { file_id, value: source } = loc.source(db);
let (store, generic_params, source_map) = lower_generic_params(
@@ -276,7 +288,11 @@ impl EnumSignature {
#[inline]
pub fn repr(&self, db: &dyn DefDatabase, id: EnumId) -> Option<ReprOptions> {
- if self.flags.contains(EnumFlags::HAS_REPR) { AttrFlags::repr(db, id.into()) } else { None }
+ if self.flags.contains(EnumFlags::HAS_REPR) {
+ AttrFlags::repr_assume_has(db, id.into())
+ } else {
+ None
+ }
}
}
bitflags::bitflags! {
diff --git a/crates/hir-ty/Cargo.toml b/crates/hir-ty/Cargo.toml
index 18426f3095..e8eda74e40 100644
--- a/crates/hir-ty/Cargo.toml
+++ b/crates/hir-ty/Cargo.toml
@@ -33,6 +33,7 @@ query-group.workspace = true
salsa.workspace = true
salsa-macros.workspace = true
petgraph.workspace = true
+bitflags.workspace = true
ra-ap-rustc_abi.workspace = true
ra-ap-rustc_index.workspace = true
diff --git a/crates/hir-ty/src/diagnostics/expr.rs b/crates/hir-ty/src/diagnostics/expr.rs
index 99dddf0bf4..93772ca452 100644
--- a/crates/hir-ty/src/diagnostics/expr.rs
+++ b/crates/hir-ty/src/diagnostics/expr.rs
@@ -15,7 +15,7 @@ use intern::sym;
use itertools::Itertools;
use rustc_hash::FxHashSet;
use rustc_pattern_analysis::constructor::Constructor;
-use rustc_type_ir::inherent::{AdtDef, IntoKind};
+use rustc_type_ir::inherent::IntoKind;
use syntax::{
AstNode,
ast::{self, UnaryOp},
@@ -311,7 +311,7 @@ impl<'db> ExprValidator<'db> {
value_or_partial.is_none_or(|v| !matches!(v, ValueNs::StaticId(_)))
}
Expr::Field { expr, .. } => match self.infer.expr_ty(*expr).kind() {
- TyKind::Adt(adt, ..) if matches!(adt.def_id().0, AdtId::UnionId(_)) => false,
+ TyKind::Adt(adt, ..) if matches!(adt.def_id(), AdtId::UnionId(_)) => false,
_ => self.is_known_valid_scrutinee(*expr),
},
Expr::Index { base, .. } => self.is_known_valid_scrutinee(*base),
diff --git a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
index 5ed7eb7a66..87ffa32544 100644
--- a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
+++ b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
@@ -11,7 +11,7 @@ use rustc_pattern_analysis::{
constructor::{Constructor, ConstructorSet, VariantVisibility},
usefulness::{PlaceValidity, UsefulnessReport, compute_match_usefulness},
};
-use rustc_type_ir::inherent::{AdtDef, IntoKind};
+use rustc_type_ir::inherent::IntoKind;
use smallvec::{SmallVec, smallvec};
use stdx::never;
@@ -197,7 +197,7 @@ impl<'a, 'db> MatchCheckCtx<'a, 'db> {
arity = substs.len();
}
TyKind::Adt(adt_def, _) => {
- let adt = adt_def.def_id().0;
+ let adt = adt_def.def_id();
ctor = match pat.kind.as_ref() {
PatKind::Leaf { .. } if matches!(adt, hir_def::AdtId::UnionId(_)) => {
UnionField
@@ -265,7 +265,7 @@ impl<'a, 'db> MatchCheckCtx<'a, 'db> {
},
TyKind::Adt(adt, substs) => {
let variant =
- Self::variant_id_for_adt(self.db, pat.ctor(), adt.def_id().0).unwrap();
+ Self::variant_id_for_adt(self.db, pat.ctor(), adt.def_id()).unwrap();
let subpatterns = self
.list_variant_fields(*pat.ty(), variant)
.zip(subpatterns)
@@ -325,7 +325,7 @@ impl<'a, 'db> PatCx for MatchCheckCtx<'a, 'db> {
TyKind::Tuple(tys) => tys.len(),
TyKind::Adt(adt_def, ..) => {
let variant =
- Self::variant_id_for_adt(self.db, ctor, adt_def.def_id().0).unwrap();
+ Self::variant_id_for_adt(self.db, ctor, adt_def.def_id()).unwrap();
variant.fields(self.db).fields().len()
}
_ => {
@@ -359,7 +359,7 @@ impl<'a, 'db> PatCx for MatchCheckCtx<'a, 'db> {
}
TyKind::Ref(_, rty, _) => single(rty),
TyKind::Adt(adt_def, ..) => {
- let adt = adt_def.def_id().0;
+ let adt = adt_def.def_id();
let variant = Self::variant_id_for_adt(self.db, ctor, adt).unwrap();
let visibilities =
@@ -428,7 +428,7 @@ impl<'a, 'db> PatCx for MatchCheckCtx<'a, 'db> {
TyKind::Int(..) | TyKind::Uint(..) => unhandled(),
TyKind::Array(..) | TyKind::Slice(..) => unhandled(),
TyKind::Adt(adt_def, subst) => {
- let adt = adt_def.def_id().0;
+ let adt = adt_def.def_id();
match adt {
hir_def::AdtId::EnumId(enum_id) => {
let enum_data = enum_id.enum_variants(cx.db);
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index ca3723f8ef..6bc55bc0e4 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -43,7 +43,7 @@ use rustc_ast_ir::FloatTy;
use rustc_hash::FxHashSet;
use rustc_type_ir::{
AliasTyKind, BoundVarIndexKind, CoroutineArgsParts, RegionKind, Upcast,
- inherent::{AdtDef, GenericArgs as _, IntoKind, Term as _, Ty as _, Tys as _},
+ inherent::{GenericArgs as _, IntoKind, Term as _, Ty as _, Tys as _},
};
use smallvec::SmallVec;
use span::Edition;
@@ -78,7 +78,7 @@ fn async_gen_item_ty_from_yield_ty<'db>(
let TyKind::Adt(poll_def, poll_args) = yield_ty.kind() else {
return None;
};
- if poll_def.inner().id != poll_id {
+ if poll_def.def_id() != poll_id {
return None;
}
let [poll_inner] = poll_args.as_slice() else {
@@ -89,7 +89,7 @@ fn async_gen_item_ty_from_yield_ty<'db>(
let TyKind::Adt(option_def, option_args) = poll_inner.kind() else {
return None;
};
- if option_def.inner().id != option_id {
+ if option_def.def_id() != option_id {
return None;
}
let [item] = option_args.as_slice() else {
@@ -890,7 +890,7 @@ fn render_const_scalar_inner<'db>(
f.write_str("&")?;
render_const_scalar(f, bytes, memory_map, t)
}
- TyKind::Adt(adt, _) if b.len() == 2 * size_of::<usize>() => match adt.def_id().0 {
+ TyKind::Adt(adt, _) if b.len() == 2 * size_of::<usize>() => match adt.def_id() {
hir_def::AdtId::StructId(s) => {
let data = StructSignature::of(f.db, s);
write!(f, "&{}", data.name.display(f.db, f.edition()))?;
@@ -944,7 +944,7 @@ fn render_const_scalar_inner<'db>(
f.write_str(")")
}
TyKind::Adt(def, args) => {
- let def = def.def_id().0;
+ let def = def.def_id();
let Ok(layout) = f.db.layout_of_adt(def, args.store(), param_env.store()) else {
return f.write_str("<layout-error>");
};
@@ -1420,7 +1420,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
}
}
TyKind::Adt(def, parameters) => {
- let def_id = def.def_id().0;
+ let def_id = def.def_id();
f.start_location_link(def_id.into());
match f.display_kind {
DisplayKind::Diagnostics | DisplayKind::Test => {
@@ -1458,7 +1458,7 @@ impl<'db> HirDisplay<'db> for Ty<'db> {
}
f.end_location_link();
- hir_fmt_generics(f, parameters.as_slice(), Some(def.def_id().0.into()), None)?;
+ hir_fmt_generics(f, parameters.as_slice(), Some(def.def_id().into()), None)?;
}
TyKind::Alias(alias_ty @ AliasTy { kind: AliasTyKind::Projection { .. }, .. }) => {
write_projection(f, &alias_ty, trait_bounds_need_parens)?
diff --git a/crates/hir-ty/src/drop.rs b/crates/hir-ty/src/drop.rs
index 0d25d7dbd1..07c705ee2f 100644
--- a/crates/hir-ty/src/drop.rs
+++ b/crates/hir-ty/src/drop.rs
@@ -70,7 +70,7 @@ fn has_drop_glue_impl<'db>(
let db = infcx.interner.db;
match ty.kind() {
TyKind::Adt(adt_def, subst) => {
- let adt_id = adt_def.def_id().0;
+ let adt_id = adt_def.def_id();
if adt_def.destructor(infcx.interner).is_some() {
return DropGlue::HasDropGlue;
}
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index 5cccba1584..333219c5af 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -55,7 +55,7 @@ use rustc_ast_ir::Mutability;
use rustc_hash::{FxHashMap, FxHashSet};
use rustc_type_ir::{
AliasTyKind, TypeFoldable,
- inherent::{AdtDef, Const as _, IntoKind, Ty as _},
+ inherent::{Const as _, IntoKind, Ty as _},
};
use smallvec::SmallVec;
use span::Edition;
@@ -1875,7 +1875,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
return self.err_ty();
}
match ty.kind() {
- TyKind::Adt(adt_def, substs) => match adt_def.def_id().0 {
+ TyKind::Adt(adt_def, substs) => match adt_def.def_id() {
AdtId::StructId(struct_id) => {
match self
.db
@@ -2197,7 +2197,7 @@ impl<'body, 'db> InferenceContext<'body, 'db> {
// If we can resolve to an enum variant, it takes priority over associated type
// of the same name.
if let TyKind::Adt(adt_def, _) = ty.kind()
- && let AdtId::EnumId(id) = adt_def.def_id().0
+ && let AdtId::EnumId(id) = adt_def.def_id()
{
let enum_data = id.enum_variants(self.db);
if let Some(variant) = enum_data.variant(current_segment.name) {
diff --git a/crates/hir-ty/src/infer/cast.rs b/crates/hir-ty/src/infer/cast.rs
index d23a32d81b..daf954c217 100644
--- a/crates/hir-ty/src/infer/cast.rs
+++ b/crates/hir-ty/src/infer/cast.rs
@@ -10,7 +10,7 @@ use rustc_hash::FxHashSet;
use rustc_type_ir::{
InferTy, TypeVisitableExt, UintTy, elaborate,
error::TypeError,
- inherent::{AdtDef, BoundExistentialPredicates as _, IntoKind, Ty as _},
+ inherent::{BoundExistentialPredicates as _, IntoKind, Ty as _},
};
use stdx::never;
@@ -529,7 +529,7 @@ fn pointer_kind<'db>(
TyKind::Slice(_) | TyKind::Str => Ok(Some(PointerKind::Length)),
TyKind::Dynamic(bounds, _) => Ok(Some(PointerKind::VTable(bounds))),
TyKind::Adt(adt_def, subst) => {
- let id = adt_def.def_id().0;
+ let id = adt_def.def_id();
let AdtId::StructId(id) = id else {
never!("`{:?}` should be sized but is not?", ty);
return Err(());
diff --git a/crates/hir-ty/src/infer/closure/analysis.rs b/crates/hir-ty/src/infer/closure/analysis.rs
index 79bdc6cea1..eb4eb8cce3 100644
--- a/crates/hir-ty/src/infer/closure/analysis.rs
+++ b/crates/hir-ty/src/infer/closure/analysis.rs
@@ -1132,7 +1132,7 @@ fn restrict_repr_packed_field_ref_capture(
// Return true for fields of packed structs.
match p.kind {
ProjectionKind::Field { .. } => match ty.kind() {
- TyKind::Adt(def, _) if def.repr().packed() => {
+ TyKind::Adt(def, _) if def.is_packed() => {
// We stop here regardless of field alignment. Field alignment can change as
// types change, including the types of private fields in other crates, and that
// shouldn't affect how we compute our captures.
diff --git a/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs b/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs
index 16b84217b8..b234e69197 100644
--- a/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs
+++ b/crates/hir-ty/src/infer/closure/analysis/expr_use_visitor.rs
@@ -17,7 +17,7 @@ use hir_def::{
use rustc_ast_ir::{try_visit, visit::VisitorResult};
use rustc_type_ir::{
FallibleTypeFolder, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor,
- inherent::{AdtDef, IntoKind, Ty as _},
+ inherent::{IntoKind, Ty as _},
};
use smallvec::{SmallVec, smallvec};
use syntax::ast::{BinaryOp, UnaryOp};
@@ -799,7 +799,7 @@ impl<'a, 'b, 'db, D: Delegate<'db>> ExprUseVisitor<'a, 'b, 'db, D> {
// expression that will actually be used
match self.cx.structurally_resolve_type(with_expr.into(), with_place.place.ty()).kind() {
TyKind::Adt(adt, args) if adt.is_struct() => {
- let AdtId::StructId(adt) = adt.def_id().0 else { unreachable!() };
+ let AdtId::StructId(adt) = adt.def_id() else { unreachable!() };
let adt_fields = VariantId::from(adt).fields(self.cx.db).fields();
let adt_field_types = self.cx.db.field_types(adt.into());
// Consume those fields of the with expression that are needed.
@@ -1701,7 +1701,7 @@ impl<'db, D: Delegate<'db>> ExprUseVisitor<'_, '_, 'db, D> {
// to assume that more cases will be added to the variant in the future. This mean
// that we should handle non-exhaustive SingleVariant the same way we would handle
// a MultiVariant.
- match def.def_id().0 {
+ match def.def_id() {
AdtId::StructId(_) | AdtId::UnionId(_) => false,
AdtId::EnumId(did) => {
let has_foreign_non_exhaustive = || {
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index 0e3716eaa6..782c6be7c3 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -20,7 +20,7 @@ use rustc_ast_ir::Mutability;
use rustc_hash::FxHashMap;
use rustc_type_ir::{
InferTy, Interner,
- inherent::{AdtDef, GenericArgs as _, IntoKind, Ty as _},
+ inherent::{GenericArgs as _, IntoKind, Ty as _},
};
use stdx::never;
use syntax::ast::RangeOp;
@@ -1039,7 +1039,7 @@ impl<'db> InferenceContext<'_, 'db> {
never!("non-ADT passed to check_struct_expr_fields");
return;
};
- let adt_id = adt.def_id().0;
+ let adt_id = adt.def_id();
let variant_fields = variant.fields(self.db);
let variant_field_tys = self.db.field_types(variant);
@@ -1623,7 +1623,7 @@ impl<'db> InferenceContext<'_, 'db> {
})
});
}
- TyKind::Adt(adt, parameters) => match adt.def_id().0 {
+ TyKind::Adt(adt, parameters) => match adt.def_id() {
hir_def::AdtId::StructId(s) => {
let local_id = s.fields(self.db).field(name)?;
let field = FieldId { parent: s.into(), local_id };
diff --git a/crates/hir-ty/src/infer/pat.rs b/crates/hir-ty/src/infer/pat.rs
index ac209adef8..a7b82dad4f 100644
--- a/crates/hir-ty/src/infer/pat.rs
+++ b/crates/hir-ty/src/infer/pat.rs
@@ -20,7 +20,7 @@ use rustc_ast_ir::Mutability;
use rustc_hash::FxHashMap;
use rustc_type_ir::{
TypeVisitableExt as _,
- inherent::{AdtDef as _, IntoKind as _, Ty as _},
+ inherent::{IntoKind as _, Ty as _},
};
use span::Edition;
use tracing::{debug, instrument, trace};
@@ -725,7 +725,7 @@ impl<'a, 'db> InferenceContext<'a, 'db> {
&& let TyKind::Adt(scrutinee_adt, _) = expected.kind()
// Don't peel if the pattern type already matches the scrutinee. E.g., stop here if
// matching on a `Cow<'a, T>` scrutinee with a `Cow::Owned(_)` pattern.
- && until_adt != Some(scrutinee_adt.def_id().0)
+ && until_adt != Some(scrutinee_adt.def_id())
// At this point, the pattern isn't able to match `expected` without peeling. Check
// that it implements `Deref` before assuming it's a smart pointer, to get a normal
// type error instead of a missing impl error if not. This only checks for `Deref`,
diff --git a/crates/hir-ty/src/inhabitedness.rs b/crates/hir-ty/src/inhabitedness.rs
index 74d66123ea..41470c54e5 100644
--- a/crates/hir-ty/src/inhabitedness.rs
+++ b/crates/hir-ty/src/inhabitedness.rs
@@ -5,10 +5,7 @@ use hir_def::{
AdtId, EnumVariantId, ModuleId, VariantId, signatures::VariantFields, visibility::Visibility,
};
use rustc_hash::FxHashSet;
-use rustc_type_ir::{
- TypeSuperVisitable, TypeVisitable, TypeVisitor,
- inherent::{AdtDef, IntoKind},
-};
+use rustc_type_ir::{TypeSuperVisitable, TypeVisitable, TypeVisitor, inherent::IntoKind};
use crate::{
consteval::try_const_usize,
@@ -85,7 +82,7 @@ impl<'db> TypeVisitor<DbInterner<'db>> for UninhabitedFrom<'_, 'db> {
}
let r = match ty.kind() {
- TyKind::Adt(adt, subst) => self.visit_adt(adt.def_id().0, subst),
+ TyKind::Adt(adt, subst) => self.visit_adt(adt.def_id(), subst),
TyKind::Never => BREAK_VISIBLY_UNINHABITED,
TyKind::Tuple(..) => ty.super_visit_with(self),
TyKind::Array(item_ty, len) => match try_const_usize(self.infcx.interner.db, len) {
diff --git a/crates/hir-ty/src/layout.rs b/crates/hir-ty/src/layout.rs
index 798c62c192..d2759ddeeb 100644
--- a/crates/hir-ty/src/layout.rs
+++ b/crates/hir-ty/src/layout.rs
@@ -177,7 +177,7 @@ pub fn layout_of_ty_query(
.unwrap_or(ty.as_ref());
let result = match ty.kind() {
TyKind::Adt(def, args) => {
- match def.inner().id {
+ match def.def_id() {
hir_def::AdtId::StructId(s) => {
let repr = AttrFlags::repr(db, s.into()).unwrap_or_default();
if repr.simd() {
@@ -193,7 +193,7 @@ pub fn layout_of_ty_query(
}
_ => {}
}
- return db.layout_of_adt(def.inner().id, args.store(), trait_env);
+ return db.layout_of_adt(def.def_id(), args.store(), trait_env);
}
TyKind::Bool => Layout::scalar(
dl,
@@ -374,7 +374,7 @@ pub(crate) fn layout_of_ty_cycle_result(
fn struct_tail_erasing_lifetimes<'a>(db: &'a dyn HirDatabase, pointee: Ty<'a>) -> Ty<'a> {
match pointee.kind() {
TyKind::Adt(def, args) => {
- let struct_id = match def.inner().id {
+ let struct_id = match def.def_id() {
AdtId::StructId(id) => id,
_ => return pointee,
};
diff --git a/crates/hir-ty/src/method_resolution/probe.rs b/crates/hir-ty/src/method_resolution/probe.rs
index 8a28b16724..6eeec6cb41 100644
--- a/crates/hir-ty/src/method_resolution/probe.rs
+++ b/crates/hir-ty/src/method_resolution/probe.rs
@@ -15,7 +15,7 @@ use rustc_type_ir::{
InferTy, TypeVisitableExt, Upcast, Variance,
elaborate::{self, supertrait_def_ids},
fast_reject::{DeepRejectCtxt, TreatParams, simplify_type},
- inherent::{AdtDef as _, BoundExistentialPredicates as _, IntoKind, Ty as _},
+ inherent::{BoundExistentialPredicates as _, IntoKind, Ty as _},
};
use smallvec::{SmallVec, smallvec};
use tracing::{debug, instrument};
@@ -937,7 +937,7 @@ impl<'a, 'db, Choice: ProbeChoice<'db>> ProbeContext<'a, 'db, Choice> {
}
}
TyKind::Adt(def, _) => {
- let def_id = def.def_id().0;
+ let def_id = def.def_id();
self.assemble_inherent_impl_candidates_for_type(
&SimplifiedType::Adt(def_id.into()),
receiver_steps,
diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs
index 80e429c4c8..87d64e567e 100644
--- a/crates/hir-ty/src/mir/eval.rs
+++ b/crates/hir-ty/src/mir/eval.rs
@@ -30,7 +30,7 @@ use rustc_ast_ir::Mutability;
use rustc_hash::{FxHashMap, FxHashSet};
use rustc_type_ir::{
AliasTyKind,
- inherent::{AdtDef, GenericArgs as _, IntoKind, Region as _, SliceLike, Ty as _},
+ inherent::{GenericArgs as _, IntoKind, Region as _, SliceLike, Ty as _},
};
use span::FileId;
use stdx::never;
@@ -1651,7 +1651,7 @@ impl<'db> Evaluator<'db> {
let TyKind::Adt(adt_def, _) = ty.kind() else {
return Ok(0);
};
- let AdtId::EnumId(e) = adt_def.def_id().0 else {
+ let AdtId::EnumId(e) = adt_def.def_id() else {
return Ok(0);
};
match &layout.variants {
@@ -1701,7 +1701,7 @@ impl<'db> Evaluator<'db> {
return Ok(it);
}
if let TyKind::Adt(adt_ef, subst) = kind
- && let AdtId::StructId(struct_id) = adt_ef.def_id().0
+ && let AdtId::StructId(struct_id) = adt_ef.def_id()
{
let field_types = self.db.field_types(struct_id.into());
if let Some(ty) =
@@ -1768,8 +1768,8 @@ impl<'db> Evaluator<'db> {
}
TyKind::Adt(adt_def, target_subst) => match &current_ty.kind() {
TyKind::Adt(current_adt_def, current_subst) => {
- let id = adt_def.def_id().0;
- let current_id = current_adt_def.def_id().0;
+ let id = adt_def.def_id();
+ let current_id = current_adt_def.def_id();
if id != current_id {
not_supported!("unsizing struct with different type");
}
@@ -2409,7 +2409,7 @@ impl<'db> Evaluator<'db> {
)?;
}
}
- TyKind::Adt(adt, subst) => match adt.def_id().0 {
+ TyKind::Adt(adt, subst) => match adt.def_id() {
AdtId::StructId(s) => {
let data = s.fields(this.db);
let layout = this.layout(ty)?;
@@ -2527,7 +2527,7 @@ impl<'db> Evaluator<'db> {
let new_id = self.vtable_map.id(ty);
self.write_memory(addr, &new_id.to_le_bytes())?;
}
- TyKind::Adt(id, args) => match id.def_id().0 {
+ TyKind::Adt(id, args) => match id.def_id() {
AdtId::StructId(s) => {
for (i, (_, ty)) in self.db.field_types(s.into()).iter().enumerate() {
let offset = layout.fields.offset(i).bytes_usize();
@@ -3046,7 +3046,7 @@ impl<'db> Evaluator<'db> {
}
match ty.kind() {
TyKind::Adt(adt_def, subst) => {
- let id = adt_def.def_id().0;
+ let id = adt_def.def_id();
match id {
AdtId::StructId(s) => {
let data = StructSignature::of(self.db, s);
diff --git a/crates/hir-ty/src/mir/eval/shim.rs b/crates/hir-ty/src/mir/eval/shim.rs
index 9586d38abc..4154760f6e 100644
--- a/crates/hir-ty/src/mir/eval/shim.rs
+++ b/crates/hir-ty/src/mir/eval/shim.rs
@@ -6,7 +6,7 @@ use std::cmp::{self, Ordering};
use hir_def::{attrs::AttrFlags, signatures::FunctionSignature};
use hir_expand::name::Name;
use intern::sym;
-use rustc_type_ir::inherent::{AdtDef, GenericArgs as _, IntoKind, SliceLike, Ty as _};
+use rustc_type_ir::inherent::{GenericArgs as _, IntoKind, SliceLike, Ty as _};
use stdx::never;
use crate::{
@@ -1360,7 +1360,7 @@ impl<'db> Evaluator<'db> {
"dyn concrete type",
)?,
TyKind::Adt(adt_def, subst) => {
- let id = adt_def.def_id().0;
+ let id = adt_def.def_id();
let layout = self.layout_adt(id, subst)?;
let id = match id {
AdtId::StructId(s) => s,
diff --git a/crates/hir-ty/src/mir/eval/shim/simd.rs b/crates/hir-ty/src/mir/eval/shim/simd.rs
index e0b3e571b8..6e20562b4e 100644
--- a/crates/hir-ty/src/mir/eval/shim/simd.rs
+++ b/crates/hir-ty/src/mir/eval/shim/simd.rs
@@ -13,7 +13,7 @@ impl<'db> Evaluator<'db> {
let len = match subst.as_slice().get(1).and_then(|it| it.konst()) {
Some(len) => len,
_ => {
- if let AdtId::StructId(id) = adt_def.def_id().0 {
+ if let AdtId::StructId(id) = adt_def.def_id() {
let struct_data = id.fields(self.db);
let fields = struct_data.fields();
let Some((first_field, _)) = fields.iter().next() else {
diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs
index 7dcc00858e..d16e1b0d59 100644
--- a/crates/hir-ty/src/mir/lower.rs
+++ b/crates/hir-ty/src/mir/lower.rs
@@ -22,7 +22,7 @@ use itertools::{EitherOrBoth, Itertools};
use la_arena::ArenaMap;
use rustc_apfloat::Float;
use rustc_hash::FxHashMap;
-use rustc_type_ir::inherent::{AdtDef, Const as _, GenericArgs as _, IntoKind, Ty as _};
+use rustc_type_ir::inherent::{Const as _, GenericArgs as _, IntoKind, Ty as _};
use span::{Edition, FileId};
use syntax::TextRange;
use triomphe::Arc;
@@ -2097,7 +2097,7 @@ fn convert_closure_capture_projections(
}
TyKind::Adt(adt_def, _) => {
let local_field_id = LocalFieldId::from_raw(RawIdx::from_u32(field_idx));
- let field = match adt_def.def_id().0 {
+ let field = match adt_def.def_id() {
AdtId::StructId(id) => {
FieldId { parent: id.into(), local_id: local_field_id }
}
diff --git a/crates/hir-ty/src/next_solver/interner.rs b/crates/hir-ty/src/next_solver/interner.rs
index b8b8d15347..fc83ebc625 100644
--- a/crates/hir-ty/src/next_solver/interner.rs
+++ b/crates/hir-ty/src/next_solver/interner.rs
@@ -4,25 +4,24 @@ use std::{fmt, ops::ControlFlow};
use intern::{Interned, InternedRef, InternedSliceRef, impl_internable};
use macros::GenericTypeVisitable;
+use rustc_abi::ReprOptions;
use rustc_ast_ir::{FloatTy, IntTy, UintTy};
pub use tls_cache::clear_tls_solver_cache;
pub use tls_db::{attach_db, attach_db_allow_change, with_attached_db};
use base_db::Crate;
use hir_def::{
- AdtId, CallableDefId, DefWithBodyId, EnumVariantId, ExpressionStoreOwnerId, HasModule,
+ AdtId, CallableDefId, DefWithBodyId, EnumId, ExpressionStoreOwnerId, HasModule,
ItemContainerId, StructId, UnionId, VariantId,
attrs::AttrFlags,
expr_store::{Body, ExpressionStore},
hir::{ClosureKind as HirClosureKind, CoroutineKind as HirCoroutineKind},
lang_item::LangItems,
signatures::{
- EnumSignature, FieldData, FnFlags, FunctionSignature, ImplFlags, ImplSignature,
+ EnumFlags, EnumSignature, FnFlags, FunctionSignature, ImplFlags, ImplSignature,
StructFlags, StructSignature, TraitFlags, TraitSignature, UnionSignature,
},
};
-use la_arena::Idx;
-use rustc_abi::{ReprFlags, ReprOptions};
use rustc_hash::FxHashSet;
use rustc_index::bit_set::DenseBitSet;
use rustc_type_ir::{
@@ -419,266 +418,167 @@ pub struct AllocId;
interned_slice!(VariancesOfStorage, VariancesOf, StoredVariancesOf, variances, Variance, Variance);
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct VariantIdx(usize);
-
-// FIXME: could/should store actual data?
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum VariantDef {
- Struct(StructId),
- Union(UnionId),
- Enum(EnumVariantId),
-}
-
-impl VariantDef {
- pub fn id(&self) -> VariantId {
- match self {
- VariantDef::Struct(struct_id) => VariantId::StructId(*struct_id),
- VariantDef::Union(union_id) => VariantId::UnionId(*union_id),
- VariantDef::Enum(enum_variant_id) => VariantId::EnumVariantId(*enum_variant_id),
- }
- }
-
- pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Idx<FieldData>, FieldData)> {
- let id: VariantId = match self {
- VariantDef::Struct(it) => (*it).into(),
- VariantDef::Union(it) => (*it).into(),
- VariantDef::Enum(it) => (*it).into(),
- };
- id.fields(db).fields().iter().map(|(id, data)| (id, data.clone())).collect()
+bitflags::bitflags! {
+ #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+ struct AdtFlags: u8 {
+ const IS_FUNDAMENTAL = 1 << 0;
+ const IS_PACKED = 1 << 1;
+ const HAS_REPR = 1 << 2;
+ const IS_PHANTOM_DATA = 1 << 3;
+ const IS_MANUALLY_DROP = 1 << 4;
+ const IS_BOX = 1 << 5;
}
}
-/*
-/// Definition of a variant -- a struct's fields or an enum variant.
-#[derive(Debug, HashStable, TyEncodable, TyDecodable)]
-pub struct VariantDef {
- /// `DefId` that identifies the variant itself.
- /// If this variant belongs to a struct or union, then this is a copy of its `DefId`.
- pub def_id: DefId,
- /// `DefId` that identifies the variant's constructor.
- /// If this variant is a struct variant, then this is `None`.
- pub ctor: Option<(CtorKind, DefId)>,
- /// Variant or struct name, maybe empty for anonymous adt (struct or union).
- pub name: Symbol,
- /// Discriminant of this variant.
- pub discr: VariantDiscr,
- /// Fields of this variant.
- pub fields: IndexVec<FieldIdx, FieldDef>,
- /// The error guarantees from parser, if any.
- tainted: Option<ErrorGuaranteed>,
- /// Flags of the variant (e.g. is field list non-exhaustive)?
- flags: VariantFlags,
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+enum AdtDefInner {
+ Struct { id: StructId, flags: AdtFlags },
+ Union { id: UnionId, flags: AdtFlags },
+ Enum { id: EnumId, flags: AdtFlags },
}
-*/
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct AdtFlags {
- is_enum: bool,
- is_union: bool,
- is_struct: bool,
- is_phantom_data: bool,
- is_fundamental: bool,
- is_box: bool,
- is_manually_drop: bool,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct AdtDefInner {
- pub id: AdtId,
- variants: Vec<(VariantIdx, VariantDef)>,
- flags: AdtFlags,
- repr: ReprOptions,
-}
-
-// We're gonna cheat a little bit and implement `Hash` on only the `DefId` and
-// accept there might be collisions for def ids from different crates (or across
-// different tests, oh my).
-impl std::hash::Hash for AdtDefInner {
- #[inline]
- fn hash<H: std::hash::Hasher>(&self, s: &mut H) {
- self.id.hash(s)
- }
-}
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+pub struct AdtDef(AdtDefInner);
-#[salsa::interned(no_lifetime, constructor = new_)]
-pub struct AdtDef {
- #[returns(ref)]
- data_: AdtDefInner,
-}
+const _: () = assert!(size_of::<AdtDef>() == 12);
impl AdtDef {
pub fn new<'db>(def_id: AdtId, interner: DbInterner<'db>) -> Self {
let db = interner.db();
- let (flags, variants, repr) = match def_id {
- AdtId::StructId(struct_id) => {
- let data = StructSignature::of(db, struct_id);
-
- let flags = AdtFlags {
- is_enum: false,
- is_union: false,
- is_struct: true,
- is_phantom_data: data.flags.contains(StructFlags::IS_PHANTOM_DATA),
- is_fundamental: data.flags.contains(StructFlags::FUNDAMENTAL),
- is_box: data.flags.contains(StructFlags::IS_BOX),
- is_manually_drop: data.flags.contains(StructFlags::IS_MANUALLY_DROP),
- };
-
- let variants = vec![(VariantIdx(0), VariantDef::Struct(struct_id))];
-
- let data_repr = data.repr(db, struct_id);
- let mut repr_flags = ReprFlags::empty();
- if flags.is_box {
- repr_flags.insert(ReprFlags::IS_LINEAR);
+ let inner = match def_id {
+ AdtId::StructId(id) => {
+ let data = StructSignature::of(db, id);
+ let mut flags = AdtFlags::empty();
+ if data.flags.contains(StructFlags::FUNDAMENTAL) {
+ flags.insert(AdtFlags::IS_FUNDAMENTAL);
}
- if data_repr.is_some_and(|r| r.c()) {
- repr_flags.insert(ReprFlags::IS_C);
+ if data.flags.contains(StructFlags::IS_PHANTOM_DATA) {
+ flags.insert(AdtFlags::IS_PHANTOM_DATA);
}
- if data_repr.is_some_and(|r| r.simd()) {
- repr_flags.insert(ReprFlags::IS_SIMD);
+ if data.flags.contains(StructFlags::IS_MANUALLY_DROP) {
+ flags.insert(AdtFlags::IS_MANUALLY_DROP);
}
- let repr = ReprOptions {
- align: data_repr.and_then(|r| r.align),
- pack: data_repr.and_then(|r| r.pack),
- int: data_repr.and_then(|r| r.int),
- flags: repr_flags,
- ..ReprOptions::default()
- };
-
- (flags, variants, repr)
- }
- AdtId::UnionId(union_id) => {
- let flags = AdtFlags {
- is_enum: false,
- is_union: true,
- is_struct: false,
- is_phantom_data: false,
- is_fundamental: false,
- is_box: false,
- is_manually_drop: false,
- };
-
- let variants = vec![(VariantIdx(0), VariantDef::Union(union_id))];
-
- let data_repr = AttrFlags::repr(db, union_id.into());
- let mut repr_flags = ReprFlags::empty();
- if flags.is_box {
- repr_flags.insert(ReprFlags::IS_LINEAR);
+ if data.flags.contains(StructFlags::IS_BOX) {
+ flags.insert(AdtFlags::IS_BOX);
}
- if data_repr.is_some_and(|r| r.c()) {
- repr_flags.insert(ReprFlags::IS_C);
+ if data.flags.contains(StructFlags::HAS_REPR) {
+ flags.insert(AdtFlags::HAS_REPR);
+ if data.repr(db, id).is_some_and(|repr| repr.packed()) {
+ flags.insert(AdtFlags::IS_PACKED);
+ }
}
- if data_repr.is_some_and(|r| r.simd()) {
- repr_flags.insert(ReprFlags::IS_SIMD);
+ AdtDefInner::Struct { id, flags }
+ }
+ AdtId::UnionId(id) => {
+ let data = UnionSignature::of(db, id);
+ let mut flags = AdtFlags::empty();
+ if data.flags.contains(StructFlags::FUNDAMENTAL) {
+ flags.insert(AdtFlags::IS_FUNDAMENTAL);
}
- let repr = ReprOptions {
- align: data_repr.and_then(|r| r.align),
- pack: data_repr.and_then(|r| r.pack),
- int: data_repr.and_then(|r| r.int),
- flags: repr_flags,
- ..ReprOptions::default()
- };
-
- (flags, variants, repr)
- }
- AdtId::EnumId(enum_id) => {
- let flags = AdtFlags {
- is_enum: true,
- is_union: false,
- is_struct: false,
- is_phantom_data: false,
- is_fundamental: false,
- is_box: false,
- is_manually_drop: false,
- };
-
- let variants = enum_id
- .enum_variants(db)
- .variants
- .iter()
- .enumerate()
- .map(|(idx, v)| (VariantIdx(idx), v))
- .map(|(idx, v)| (idx, VariantDef::Enum(v.0)))
- .collect();
-
- let data_repr = AttrFlags::repr(db, enum_id.into());
-
- let mut repr_flags = ReprFlags::empty();
- if flags.is_box {
- repr_flags.insert(ReprFlags::IS_LINEAR);
+ if data.flags.contains(StructFlags::HAS_REPR) {
+ flags.insert(AdtFlags::HAS_REPR);
+ if data.repr(db, id).is_some_and(|repr| repr.packed()) {
+ flags.insert(AdtFlags::IS_PACKED);
+ }
}
- if data_repr.is_some_and(|r| r.c()) {
- repr_flags.insert(ReprFlags::IS_C);
+ AdtDefInner::Union { id, flags }
+ }
+ AdtId::EnumId(id) => {
+ let data = EnumSignature::of(db, id);
+ let mut flags = AdtFlags::empty();
+ if data.flags.contains(EnumFlags::FUNDAMENTAL) {
+ flags.insert(AdtFlags::IS_FUNDAMENTAL);
}
- if data_repr.is_some_and(|r| r.simd()) {
- repr_flags.insert(ReprFlags::IS_SIMD);
+ if data.flags.contains(EnumFlags::HAS_REPR) {
+ flags.insert(AdtFlags::HAS_REPR);
+ if data.repr(db, id).is_some_and(|repr| repr.packed()) {
+ flags.insert(AdtFlags::IS_PACKED);
+ }
}
-
- let repr = ReprOptions {
- align: data_repr.and_then(|r| r.align),
- pack: data_repr.and_then(|r| r.pack),
- int: data_repr.and_then(|r| r.int),
- flags: repr_flags,
- ..ReprOptions::default()
- };
-
- (flags, variants, repr)
+ AdtDefInner::Enum { id, flags }
}
};
+ AdtDef(inner)
+ }
- AdtDef::new_(db, AdtDefInner { id: def_id, variants, flags, repr })
+ #[inline]
+ pub fn def_id(self) -> AdtId {
+ match self.0 {
+ AdtDefInner::Struct { id, .. } => AdtId::StructId(id),
+ AdtDefInner::Union { id, .. } => AdtId::UnionId(id),
+ AdtDefInner::Enum { id, .. } => AdtId::EnumId(id),
+ }
}
- pub fn inner(&self) -> &AdtDefInner {
- crate::with_attached_db(|db| {
- let inner = self.data_(db);
- // SAFETY: ¯\_(ツ)_/¯
- unsafe { std::mem::transmute(inner) }
- })
+ #[inline]
+ fn flags(self) -> AdtFlags {
+ match self.0 {
+ AdtDefInner::Struct { flags, .. }
+ | AdtDefInner::Union { flags, .. }
+ | AdtDefInner::Enum { flags, .. } => flags,
+ }
}
- pub fn is_enum(&self) -> bool {
- self.inner().flags.is_enum
+ #[inline]
+ pub fn is_struct(self) -> bool {
+ matches!(self.0, AdtDefInner::Struct { .. })
+ }
+
+ #[inline]
+ pub fn is_union(self) -> bool {
+ matches!(self.0, AdtDefInner::Union { .. })
}
- pub fn is_box(&self) -> bool {
- self.inner().flags.is_box
+ #[inline]
+ pub fn is_enum(self) -> bool {
+ matches!(self.0, AdtDefInner::Enum { .. })
}
#[inline]
- pub fn repr(self) -> ReprOptions {
- self.inner().repr
+ pub fn is_box(self) -> bool {
+ matches!(self.0, AdtDefInner::Struct { flags, .. } if flags.contains(AdtFlags::IS_BOX))
}
- /// Asserts this is a struct or union and returns its unique variant.
- pub fn non_enum_variant(self) -> VariantDef {
- assert!(self.inner().flags.is_struct || self.inner().flags.is_union);
- self.inner().variants[0].1.clone()
+ #[inline]
+ pub fn repr(self, db: &dyn HirDatabase) -> ReprOptions {
+ if self.flags().contains(AdtFlags::HAS_REPR) {
+ AttrFlags::repr_assume_has(db, self.def_id()).unwrap_or_default()
+ } else {
+ ReprOptions::default()
+ }
}
}
impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef {
fn def_id(self) -> AdtIdWrapper {
- self.inner().id.into()
+ self.def_id().into()
}
fn is_struct(self) -> bool {
- self.inner().flags.is_struct
+ self.is_struct()
}
fn is_phantom_data(self) -> bool {
- self.inner().flags.is_phantom_data
+ matches!(self.0, AdtDefInner::Struct { flags, .. } if flags.contains(AdtFlags::IS_PHANTOM_DATA))
+ }
+
+ fn is_manually_drop(self) -> bool {
+ matches!(self.0, AdtDefInner::Struct { flags, .. } if flags.contains(AdtFlags::IS_MANUALLY_DROP))
+ }
+
+ fn is_packed(self) -> bool {
+ self.flags().contains(AdtFlags::IS_PACKED)
}
fn is_fundamental(self) -> bool {
- self.inner().flags.is_fundamental
+ self.flags().contains(AdtFlags::IS_FUNDAMENTAL)
}
fn struct_tail_ty(
self,
interner: DbInterner<'db>,
) -> Option<EarlyBinder<DbInterner<'db>, Ty<'db>>> {
- let hir_def::AdtId::StructId(struct_id) = self.inner().id else {
+ let hir_def::AdtId::StructId(struct_id) = self.def_id() else {
return None;
};
let id: VariantId = struct_id.into();
@@ -697,7 +597,7 @@ impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef {
db.field_types(id).iter().map(|(_, ty)| ty.get().skip_binder()).collect::<Vec<_>>()
};
let field_tys = |_id: VariantId| vec![];
- let tys: Vec<_> = match self.inner().id {
+ let tys: Vec<_> = match self.def_id() {
hir_def::AdtId::StructId(id) => field_tys(id.into()),
hir_def::AdtId::UnionId(id) => field_tys(id.into()),
hir_def::AdtId::EnumId(id) => id
@@ -723,15 +623,7 @@ impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef {
}
fn destructor(self, interner: DbInterner<'db>) -> Option<AdtDestructorKind> {
- crate::drop::destructor(interner.db, self.def_id().0).map(|_| AdtDestructorKind::NotConst)
- }
-
- fn is_manually_drop(self) -> bool {
- self.inner().flags.is_manually_drop
- }
-
- fn is_packed(self) -> bool {
- self.repr().packed()
+ crate::drop::destructor(interner.db, self.def_id()).map(|_| AdtDestructorKind::NotConst)
}
fn field_representing_type_info(
@@ -746,17 +638,17 @@ impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef {
impl fmt::Debug for AdtDef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- crate::with_attached_db(|db| match self.inner().id {
- AdtId::StructId(struct_id) => {
- let data = StructSignature::of(db, struct_id);
+ crate::with_attached_db(|db| match self.0 {
+ AdtDefInner::Struct { id, .. } => {
+ let data = StructSignature::of(db, id);
f.write_str(data.name.as_str())
}
- AdtId::UnionId(union_id) => {
- let data = UnionSignature::of(db, union_id);
+ AdtDefInner::Union { id, .. } => {
+ let data = UnionSignature::of(db, id);
f.write_str(data.name.as_str())
}
- AdtId::EnumId(enum_id) => {
- let data = EnumSignature::of(db, enum_id);
+ AdtDefInner::Enum { id, .. } => {
+ let data = EnumSignature::of(db, id);
f.write_str(data.name.as_str())
}
})
@@ -1985,13 +1877,18 @@ impl<'db> Interner for DbInterner<'db> {
};
// The last field of the structure has to exist and contain type/const parameters.
- let variant = def.non_enum_variant();
+ let variant = match def.def_id() {
+ AdtId::StructId(id) => VariantId::from(id),
+ AdtId::UnionId(id) => id.into(),
+ AdtId::EnumId(_) => panic!("expected a struct or a union"),
+ };
let fields = variant.fields(self.db());
- let Some((tail_field, prefix_fields)) = fields.split_last() else {
+ let mut prefix_fields = fields.fields().iter();
+ let Some(tail_field) = prefix_fields.next_back() else {
return UnsizingParams(DenseBitSet::new_empty(num_params));
};
- let field_types = self.db().field_types(variant.id());
+ let field_types = self.db().field_types(variant);
let mut unsizing_params = DenseBitSet::new_empty(num_params);
let ty = field_types[tail_field.0].get();
for arg in ty.instantiate_identity().walk() {
diff --git a/crates/hir-ty/src/next_solver/ty.rs b/crates/hir-ty/src/next_solver/ty.rs
index 22595214b4..8a3866d5ac 100644
--- a/crates/hir-ty/src/next_solver/ty.rs
+++ b/crates/hir-ty/src/next_solver/ty.rs
@@ -504,7 +504,7 @@ impl<'db> Ty<'db> {
#[inline]
pub fn as_adt(self) -> Option<(AdtId, GenericArgs<'db>)> {
match self.kind() {
- TyKind::Adt(adt_def, args) => Some((adt_def.def_id().0, args)),
+ TyKind::Adt(adt_def, args) => Some((adt_def.def_id(), args)),
_ => None,
}
}
@@ -1346,9 +1346,11 @@ impl<'db> rustc_type_ir::inherent::Ty<DbInterner<'db>> for Ty<'db> {
false
}
- fn discriminant_ty(self, interner: DbInterner<'db>) -> <DbInterner<'db> as Interner>::Ty {
+ fn discriminant_ty(self, interner: DbInterner<'db>) -> Ty<'db> {
match self.kind() {
- TyKind::Adt(adt, _) if adt.is_enum() => adt.repr().discr_type().to_ty(interner),
+ TyKind::Adt(adt, _) if adt.is_enum() => {
+ adt.repr(interner.db).discr_type().to_ty(interner)
+ }
TyKind::Coroutine(_, args) => args.as_coroutine().discr_ty(interner),
TyKind::Param(_) | TyKind::Alias(..) | TyKind::Infer(InferTy::TyVar(_)) => {
diff --git a/crates/hir-ty/src/next_solver/util.rs b/crates/hir-ty/src/next_solver/util.rs
index 858233cb2c..3c5126cc4a 100644
--- a/crates/hir-ty/src/next_solver/util.rs
+++ b/crates/hir-ty/src/next_solver/util.rs
@@ -423,7 +423,7 @@ pub fn sizedness_constraint_for_ty<'db>(
.and_then(|ty| sizedness_constraint_for_ty(interner, sizedness, ty)),
Adt(adt, args) => {
- if crate::representability::representability(interner.db, adt.def_id().0)
+ if crate::representability::representability(interner.db, adt.def_id())
== Representability::Infinite
{
return None;
diff --git a/crates/hir-ty/src/representability.rs b/crates/hir-ty/src/representability.rs
index bae204c4ef..6c8e890be5 100644
--- a/crates/hir-ty/src/representability.rs
+++ b/crates/hir-ty/src/representability.rs
@@ -1,7 +1,7 @@
//! Detecting whether a type is infinitely-sized.
use hir_def::{AdtId, VariantId, hir::generics::GenericParams};
-use rustc_type_ir::inherent::{AdtDef, IntoKind};
+use rustc_type_ir::inherent::IntoKind;
use crate::{
db::HirDatabase,
@@ -54,7 +54,7 @@ fn variant_representability(db: &dyn HirDatabase, id: VariantId) -> Representabi
fn representability_ty<'db>(db: &'db dyn HirDatabase, ty: Ty<'db>) -> Representability {
match ty.kind() {
- TyKind::Adt(adt_id, args) => representability_adt_ty(db, adt_id.def_id().0, args),
+ TyKind::Adt(adt_id, args) => representability_adt_ty(db, adt_id.def_id(), args),
// FIXME(#11924) allow zero-length arrays?
TyKind::Array(ty, _) => representability_ty(db, ty),
TyKind::Tuple(tys) => {
@@ -112,7 +112,7 @@ fn params_in_repr(db: &dyn HirDatabase, def_id: AdtId) -> Box<[bool]> {
fn params_in_repr_ty<'db>(db: &'db dyn HirDatabase, ty: Ty<'db>, params_in_repr: &mut [bool]) {
match ty.kind() {
TyKind::Adt(adt, args) => {
- let inner_params_in_repr = self::params_in_repr(db, adt.def_id().0);
+ let inner_params_in_repr = self::params_in_repr(db, adt.def_id());
for (i, arg) in args.iter().enumerate() {
if let GenericArgKind::Type(ty) = arg.kind()
&& inner_params_in_repr[i]
diff --git a/crates/hir-ty/src/tests/closure_captures.rs b/crates/hir-ty/src/tests/closure_captures.rs
index 5324d8c605..b01f44acbc 100644
--- a/crates/hir-ty/src/tests/closure_captures.rs
+++ b/crates/hir-ty/src/tests/closure_captures.rs
@@ -6,7 +6,7 @@ use hir_def::{
};
use hir_expand::{HirFileId, files::InFileWrapper};
use itertools::Itertools;
-use rustc_type_ir::inherent::{AdtDef as _, IntoKind};
+use rustc_type_ir::inherent::IntoKind;
use span::{Edition, TextRange};
use stdx::{format_to, never};
use syntax::{AstNode, AstPtr};
@@ -42,7 +42,7 @@ fn display_place(db: &TestDB, store: &ExpressionStore, place: &Place, local: Bin
match ty.kind() {
TyKind::Tuple(_) => format_to!(result, ".{field_idx}"),
TyKind::Adt(adt_def, _) => {
- let variant = match adt_def.def_id().0 {
+ let variant = match adt_def.def_id() {
AdtId::StructId(id) => VariantId::from(id),
AdtId::UnionId(id) => id.into(),
AdtId::EnumId(id) => {
diff --git a/crates/hir-ty/src/traits.rs b/crates/hir-ty/src/traits.rs
index ad668f2eee..14611d80af 100644
--- a/crates/hir-ty/src/traits.rs
+++ b/crates/hir-ty/src/traits.rs
@@ -17,7 +17,7 @@ use hir_expand::name::Name;
use intern::sym;
use rustc_type_ir::{
TypingMode,
- inherent::{AdtDef, BoundExistentialPredicates, IntoKind},
+ inherent::{BoundExistentialPredicates, IntoKind},
};
use crate::{
@@ -171,7 +171,7 @@ pub fn is_inherent_impl_coherent(db: &dyn HirDatabase, def_map: &DefMap, impl_id
| TyKind::Uint(_)
| TyKind::Float(_) => def_map.is_rustc_coherence_is_core(),
- TyKind::Adt(adt_def, _) => adt_def.def_id().0.module(db).krate(db) == def_map.krate(),
+ TyKind::Adt(adt_def, _) => adt_def.def_id().module(db).krate(db) == def_map.krate(),
TyKind::Dynamic(it, _) => it
.principal_def_id()
.is_some_and(|trait_id| trait_id.0.module(db).krate(db) == def_map.krate()),
@@ -194,7 +194,7 @@ pub fn is_inherent_impl_coherent(db: &dyn HirDatabase, def_map: &DefMap, impl_id
| TyKind::Uint(_)
| TyKind::Float(_) => true,
- TyKind::Adt(adt_def, _) => match adt_def.def_id().0 {
+ TyKind::Adt(adt_def, _) => match adt_def.def_id() {
hir_def::AdtId::StructId(id) => StructSignature::of(db, id)
.flags
.contains(StructFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS),
@@ -259,7 +259,7 @@ pub fn check_orphan_rules<'db>(db: &'db dyn HirDatabase, impl_: ImplId) -> bool
match ty.kind() {
TyKind::Ref(_, referenced, _) => ty = referenced,
TyKind::Adt(adt_def, subs) => {
- let AdtId::StructId(s) = adt_def.def_id().0 else {
+ let AdtId::StructId(s) = adt_def.def_id() else {
break ty;
};
let struct_signature = StructSignature::of(db, s);
@@ -282,7 +282,7 @@ pub fn check_orphan_rules<'db>(db: &'db dyn HirDatabase, impl_: ImplId) -> bool
// FIXME: param coverage
// - No uncovered type parameters `P1..=Pn` may appear in `T0..Ti`` (excluding `Ti`)
let is_not_orphan = trait_ref.args.types().any(|ty| match unwrap_fundamental(ty).kind() {
- TyKind::Adt(adt_def, _) => is_local(adt_def.def_id().0.module(db).krate(db)),
+ TyKind::Adt(adt_def, _) => is_local(adt_def.def_id().module(db).krate(db)),
TyKind::Error(_) => true,
TyKind::Dynamic(it, _) => {
it.principal_def_id().is_some_and(|trait_id| is_local(trait_id.0.module(db).krate(db)))
diff --git a/crates/hir-ty/src/variance.rs b/crates/hir-ty/src/variance.rs
index a88457e3c7..a89a938639 100644
--- a/crates/hir-ty/src/variance.rs
+++ b/crates/hir-ty/src/variance.rs
@@ -18,10 +18,7 @@ use hir_def::{
signatures::{StructFlags, StructSignature},
};
use rustc_ast_ir::Mutability;
-use rustc_type_ir::{
- Variance,
- inherent::{AdtDef, IntoKind},
-};
+use rustc_type_ir::{Variance, inherent::IntoKind};
use stdx::never;
use crate::{
@@ -214,7 +211,7 @@ impl<'db> Context<'db> {
}
}
TyKind::Adt(def, args) => {
- self.add_constraints_from_args(def.def_id().0.into(), args, variance);
+ self.add_constraints_from_args(def.def_id().into(), args, variance);
}
TyKind::Alias(alias) => {
// FIXME: Probably not correct wrt. opaques.
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 60de634996..9b36f8ab81 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -105,7 +105,7 @@ use rustc_hash::FxHashSet;
use rustc_type_ir::{
AliasTyKind, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable,
TypeVisitor, fast_reject,
- inherent::{AdtDef, GenericArgs as _, IntoKind, SliceLike, Term as _, Ty as _},
+ inherent::{GenericArgs as _, IntoKind, SliceLike, Term as _, Ty as _},
};
use span::{AstIdNode, Edition, FileId};
use stdx::{format_to, impl_from, never};
@@ -5313,7 +5313,7 @@ impl<'db> ClosureCapture<'db> {
match ty.kind() {
TyKind::Tuple(_) => format_to!(result, "_{field_idx}"),
TyKind::Adt(adt_def, _) => {
- let variant = match adt_def.def_id().0 {
+ let variant = match adt_def.def_id() {
AdtId::StructId(id) => VariantId::from(id),
AdtId::UnionId(id) => id.into(),
AdtId::EnumId(id) => {
@@ -5347,7 +5347,7 @@ impl<'db> ClosureCapture<'db> {
match ty.kind() {
TyKind::Tuple(_) => format_to!(result, ".{field_idx}"),
TyKind::Adt(adt_def, _) => {
- let variant = match adt_def.def_id().0 {
+ let variant = match adt_def.def_id() {
AdtId::StructId(id) => VariantId::from(id),
AdtId::UnionId(id) => id.into(),
AdtId::EnumId(id) => {
@@ -5593,7 +5593,7 @@ impl<'db> Type<'db> {
// For non-phantom_data adts we check variants/fields as well as generic parameters
TyKind::Adt(adt_def, args)
- if !is_phantom_data(self.interner.db(), adt_def.def_id().0) =>
+ if !is_phantom_data(self.interner.db(), adt_def.def_id()) =>
{
let _variant_id_to_fields = |id: VariantId| {
let variant_data = &id.fields(self.interner.db());
@@ -5613,7 +5613,7 @@ impl<'db> Type<'db> {
};
let variant_id_to_fields = |_: VariantId| vec![];
- let variants: Vec<Vec<Ty<'db>>> = match adt_def.def_id().0 {
+ let variants: Vec<Vec<Ty<'db>>> = match adt_def.def_id() {
AdtId::StructId(id) => {
vec![variant_id_to_fields(id.into())]
}
@@ -5891,7 +5891,7 @@ impl<'db> Type<'db> {
pub fn is_packed(&self, db: &'db dyn HirDatabase) -> bool {
let adt_id = match self.ty.kind() {
- TyKind::Adt(adt_def, ..) => adt_def.def_id().0,
+ TyKind::Adt(adt_def, ..) => adt_def.def_id(),
_ => return false,
};
@@ -5930,7 +5930,7 @@ impl<'db> Type<'db> {
let interner = DbInterner::new_no_crate(db);
let (variant_id, substs) = match self.ty.kind() {
TyKind::Adt(adt_def, substs) => {
- let id = match adt_def.def_id().0 {
+ let id = match adt_def.def_id() {
AdtId::StructId(id) => id.into(),
AdtId::UnionId(id) => id.into(),
AdtId::EnumId(_) => return Vec::new(),
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index e5d674cb75..1aec56a0e0 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -47,7 +47,7 @@ use itertools::Itertools;
use rustc_hash::FxHashSet;
use rustc_type_ir::{
AliasTyKind,
- inherent::{AdtDef, IntoKind, Ty as _},
+ inherent::{IntoKind, Ty as _},
};
use smallvec::SmallVec;
use stdx::never;
@@ -956,7 +956,7 @@ impl<'db> SourceAnalyzer<'db> {
handle_variants(VariantId::from(variant_id), subst, &mut container)?
}
Either::Right(container_ty) => match container_ty.kind() {
- TyKind::Adt(adt_def, subst) => match adt_def.def_id().0 {
+ TyKind::Adt(adt_def, subst) => match adt_def.def_id() {
AdtId::StructId(id) => {
handle_variants(id.into(), subst, &mut container)?
}
@@ -1286,7 +1286,7 @@ impl<'db> SourceAnalyzer<'db> {
let env = self.trait_environment(db);
let (subst, expected_resolution) = match ty.kind() {
TyKind::Adt(adt_def, subst) => {
- let adt_id = adt_def.def_id().0;
+ let adt_id = adt_def.def_id();
(
GenericSubstitution::new(adt_id.into(), subst, env),
PathResolution::Def(ModuleDef::Adt(adt_id.into())),
diff --git a/crates/ide-completion/src/tests/flyimport.rs b/crates/ide-completion/src/tests/flyimport.rs
index 60ae077d01..896b132e15 100644
--- a/crates/ide-completion/src/tests/flyimport.rs
+++ b/crates/ide-completion/src/tests/flyimport.rs
@@ -781,9 +781,9 @@ fn main() {
}
"#,
expect![[r#"
+ me random_method(…) (use dep::test_mod::TestTrait) fn(&self) DEPRECATED
ct SPECIAL_CONST (use dep::test_mod::TestTrait) u8 DEPRECATED
fn weird_function() (use dep::test_mod::TestTrait) fn() DEPRECATED
- me random_method(…) (use dep::test_mod::TestTrait) fn(&self) DEPRECATED
"#]],
);
}