Unnamed repository; edit this file 'description' to name the repository.
-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
"#]],
);
}