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