Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/next_solver/interner.rs')
-rw-r--r--crates/hir-ty/src/next_solver/interner.rs944
1 files changed, 427 insertions, 517 deletions
diff --git a/crates/hir-ty/src/next_solver/interner.rs b/crates/hir-ty/src/next_solver/interner.rs
index cfb55e2e00..b3d31dd40b 100644
--- a/crates/hir-ty/src/next_solver/interner.rs
+++ b/crates/hir-ty/src/next_solver/interner.rs
@@ -4,49 +4,53 @@ 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,
- ItemContainerId, StructId, UnionId, VariantId,
+ AdtId, CallableDefId, EnumId, HasModule, ItemContainerId, StructId, TraitId, TypeAliasId,
+ UnionId, VariantId,
attrs::AttrFlags,
- expr_store::{Body, ExpressionStore},
+ expr_store::{ExpressionStore, StoreVisitor},
+ hir::{ClosureKind as HirClosureKind, CoroutineKind as HirCoroutineKind, ExprId, PatId},
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_abi::ExternAbi;
use rustc_hash::FxHashSet;
use rustc_index::bit_set::DenseBitSet;
use rustc_type_ir::{
- AliasTermKind, AliasTy, AliasTyKind, BoundVar, CoroutineWitnessTypes, DebruijnIndex,
- EarlyBinder, FlagComputation, Flags, GenericArgKind, GenericTypeVisitable, ImplPolarity,
- InferTy, Interner, TraitRef, TypeFlags, TypeVisitableExt, Upcast, Variance,
+ AliasTy, BoundVar, CoroutineWitnessTypes, DebruijnIndex, EarlyBinder, FlagComputation, Flags,
+ FnSigKind, GenericArgKind, GenericTypeVisitable, ImplPolarity, InferTy, Interner, TraitRef,
+ TypeFlags, TypeVisitableExt, Upcast, Variance,
elaborate::elaborate,
error::TypeError,
fast_reject,
inherent::{self, Const as _, GenericsOf, IntoKind, SliceLike as _, Span as _, Ty as _},
- lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem},
+ lang_items::{SolverAdtLangItem, SolverProjectionLangItem, SolverTraitLangItem},
solve::{AdtDestructorKind, SizedTraitKind},
};
use crate::{
- FnAbi,
+ InferBodyId, Span,
db::{HirDatabase, InternedClosure, InternedCoroutineId},
lower::GenericPredicates,
method_resolution::TraitImpls,
next_solver::{
- AdtIdWrapper, AnyImplId, BoundConst, CallableIdWrapper, CanonicalVarKind, ClosureIdWrapper,
- Consts, CoroutineClosureIdWrapper, CoroutineIdWrapper, Ctor, FnSig, FxIndexMap,
- GeneralConstIdWrapper, LateParamRegion, OpaqueTypeKey, RegionAssumptions, ScalarInt,
- SimplifiedType, SolverContext, SolverDefIds, TraitIdWrapper, TypeAliasIdWrapper,
- UnevaluatedConst,
+ AdtIdWrapper, AliasTermKind, AliasTyKind, AnyImplId, BoundConst, CallableIdWrapper,
+ CanonicalVarKind, ClosureIdWrapper, Consts, CoroutineClosureIdWrapper, CoroutineIdWrapper,
+ Ctor, FnSig, FreeConstAliasId, FreeTermAliasId, FreeTyAliasId, FxIndexMap,
+ GeneralConstIdWrapper, ImplOrTraitAssocConstId, ImplOrTraitAssocTermId,
+ ImplOrTraitAssocTyId, InherentAssocConstId, InherentAssocTermId, InherentAssocTyId,
+ LateParamRegion, OpaqueTyIdWrapper, OpaqueTypeKey, RegionAssumptions, ScalarInt,
+ SimplifiedType, SolverContext, SolverDefIds, TermId, TraitAssocConstId, TraitAssocTermId,
+ TraitAssocTyId, TraitIdWrapper, TypeAliasIdWrapper, UnevaluatedConst, Unnormalized,
util::{explicit_item_bounds, explicit_item_self_bounds},
},
};
@@ -382,13 +386,9 @@ impl<'db> DbInterner<'db> {
}
}
-// This is intentionally left as `()`
-#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
-pub struct Span(());
-
impl<'db> inherent::Span<DbInterner<'db>> for Span {
fn dummy() -> Self {
- Span(())
+ Span::Dummy
}
}
@@ -422,266 +422,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, StableHash, 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 { .. })
}
- pub fn is_box(&self) -> bool {
- self.inner().flags.is_box
+ #[inline]
+ pub fn is_union(self) -> bool {
+ matches!(self.0, AdtDefInner::Union { .. })
+ }
+
+ #[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();
@@ -700,7 +601,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
@@ -726,15 +627,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(
@@ -749,17 +642,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())
}
})
@@ -778,6 +671,10 @@ impl<'db> inherent::Features<DbInterner<'db>> for Features {
false
}
+ fn generic_const_args(self) -> bool {
+ false
+ }
+
fn feature_bound_holds_in_crate(self, _symbol: Symbol) -> bool {
false
}
@@ -949,11 +846,7 @@ impl_foldable_for_interned_slice!(PatList);
macro_rules! as_lang_item {
(
- $solver_enum:ident, $self:ident, $def_id:expr;
-
- ignore = {
- $( $ignore:ident ),* $(,)?
- }
+ $solver_enum:ident, $self:ident, $def_id:expr, $id_ty:ty;
$( $variant:ident ),* $(,)?
) => {{
@@ -962,11 +855,10 @@ macro_rules! as_lang_item {
if let Some(it) = None::<$solver_enum> {
match it {
$( $solver_enum::$variant => {} )*
- $( $solver_enum::$ignore => {} )*
}
}
match $def_id {
- $( def_id if lang_items.$variant.is_some_and(|it| it == def_id) => Some($solver_enum::$variant), )*
+ $( def_id if let Some(it) = lang_items.$variant && <$id_ty>::from(it) == def_id => Some($solver_enum::$variant), )*
_ => None
}
}};
@@ -976,17 +868,12 @@ macro_rules! is_lang_item {
(
$solver_enum:ident, $self:ident, $def_id:expr, $expected_variant:ident;
- ignore = {
- $( $ignore:ident ),* $(,)?
- }
-
$( $variant:ident ),* $(,)?
) => {{
let lang_items = $self.lang_items();
let def_id = $def_id;
match $expected_variant {
$( $solver_enum::$variant => lang_items.$variant.is_some_and(|it| it == def_id), )*
- $( $solver_enum::$ignore => false, )*
}
}};
}
@@ -1004,6 +891,20 @@ impl<'db> Interner for DbInterner<'db> {
type AdtId = AdtIdWrapper;
type ImplId = AnyImplId;
type UnevaluatedConstId = GeneralConstIdWrapper;
+ type TraitAssocTyId = TraitAssocTyId;
+ type TraitAssocConstId = TraitAssocConstId;
+ type TraitAssocTermId = TraitAssocTermId;
+ type OpaqueTyId = OpaqueTyIdWrapper;
+ type LocalOpaqueTyId = OpaqueTyIdWrapper;
+ type FreeTyAliasId = FreeTyAliasId;
+ type FreeConstAliasId = FreeConstAliasId;
+ type FreeTermAliasId = FreeTermAliasId;
+ type ImplOrTraitAssocTyId = ImplOrTraitAssocTyId;
+ type ImplOrTraitAssocConstId = ImplOrTraitAssocConstId;
+ type ImplOrTraitAssocTermId = ImplOrTraitAssocTermId;
+ type InherentAssocTyId = InherentAssocTyId;
+ type InherentAssocConstId = InherentAssocConstId;
+ type InherentAssocTermId = InherentAssocTermId;
type Span = Span;
type GenericArgs = GenericArgs<'db>;
@@ -1057,7 +958,6 @@ impl<'db> Interner for DbInterner<'db> {
type Pat = Pattern<'db>;
type PatList = PatList<'db>;
type Safety = Safety;
- type Abi = FnAbi;
type Const = Const<'db>;
type ParamConst = ParamConst;
@@ -1078,7 +978,7 @@ impl<'db> Interner for DbInterner<'db> {
type Clause = Clause<'db>;
type Clauses = Clauses<'db>;
- type GenericsOf = Generics;
+ type GenericsOf = Generics<'db>;
type VariancesOf = VariancesOf<'db>;
@@ -1187,7 +1087,9 @@ impl<'db> Interner for DbInterner<'db> {
//
// We currently always use the type from HIR typeck which ignores regions. This
// should be fine.
- SolverDefId::InternedOpaqueTyId(_) => self.type_of_opaque_hir_typeck(def_id),
+ SolverDefId::InternedOpaqueTyId(def_id) => {
+ self.type_of_opaque_hir_typeck(def_id.into())
+ }
SolverDefId::FunctionId(id) => self.db.value_ty(id.into()).unwrap(),
SolverDefId::Ctor(id) => {
let id = match id {
@@ -1204,43 +1106,45 @@ impl<'db> Interner for DbInterner<'db> {
AdtDef::new(def_id.0, self)
}
- fn alias_term_kind(
- self,
- alias: rustc_type_ir::AliasTerm<Self>,
- ) -> rustc_type_ir::AliasTermKind {
- match alias.def_id {
- SolverDefId::InternedOpaqueTyId(_) => AliasTermKind::OpaqueTy,
+ fn alias_term_kind_from_def_id(self, def_id: SolverDefId) -> AliasTermKind<'db> {
+ match def_id {
+ SolverDefId::InternedOpaqueTyId(def_id) => {
+ AliasTermKind::OpaqueTy { def_id: def_id.into() }
+ }
SolverDefId::TypeAliasId(type_alias) => match type_alias.loc(self.db).container {
ItemContainerId::ImplId(impl_)
if ImplSignature::of(self.db, impl_).target_trait.is_none() =>
{
- AliasTermKind::InherentTy
+ AliasTermKind::InherentTy { def_id: type_alias.into() }
}
ItemContainerId::TraitId(_) | ItemContainerId::ImplId(_) => {
- AliasTermKind::ProjectionTy
+ AliasTermKind::ProjectionTy { def_id: type_alias.into() }
}
- _ => AliasTermKind::FreeTy,
+ _ => AliasTermKind::FreeTy { def_id: type_alias.into() },
},
// rustc creates an `AnonConst` for consts, and evaluates them with CTFE (normalizing projections
// via selection, similar to ours `find_matching_impl()`, and not with the trait solver), so mimic it.
- SolverDefId::ConstId(_) | SolverDefId::AnonConstId(_) => {
- AliasTermKind::UnevaluatedConst
+ SolverDefId::ConstId(def_id) => {
+ AliasTermKind::UnevaluatedConst { def_id: GeneralConstIdWrapper(def_id.into()) }
+ }
+ SolverDefId::AnonConstId(def_id) => {
+ AliasTermKind::UnevaluatedConst { def_id: GeneralConstIdWrapper(def_id.into()) }
}
- _ => unimplemented!("Unexpected alias: {:?}", alias.def_id),
+ _ => unimplemented!("Unexpected alias: {:?}", def_id),
}
}
fn trait_ref_and_own_args_for_alias(
self,
- def_id: Self::DefId,
+ def_id: Self::TraitAssocTermId,
args: Self::GenericArgs,
) -> (rustc_type_ir::TraitRef<Self>, Self::GenericArgsSlice) {
- let trait_def_id = self.parent(def_id);
- let trait_generics = self.generics_of(trait_def_id);
- let trait_args =
- GenericArgs::new_from_slice(&args.as_slice()[0..trait_generics.own_params.len()]);
- let alias_args = &args.as_slice()[trait_generics.own_params.len()..];
- (TraitRef::new_from_args(self, trait_def_id.try_into().unwrap(), trait_args), alias_args)
+ let trait_def_id = self.projection_parent(def_id).0;
+ let trait_generics = crate::generics::generics(self.db, trait_def_id.into());
+ let trait_generics_len = trait_generics.len();
+ let trait_args = GenericArgs::new_from_slice(&args.as_slice()[..trait_generics_len]);
+ let alias_args = &args.as_slice()[trait_generics_len..];
+ (TraitRef::new_from_args(self, trait_def_id.into(), trait_args), alias_args)
}
fn check_args_compatible(self, _def_id: Self::DefId, _args: Self::GenericArgs) -> bool {
@@ -1265,37 +1169,43 @@ impl<'db> Interner for DbInterner<'db> {
Tys::new_from_iter(self, args)
}
- fn parent(self, def_id: Self::DefId) -> Self::DefId {
- use hir_def::Lookup;
+ fn projection_parent(self, def_id: Self::TraitAssocTermId) -> Self::TraitId {
+ let container = match def_id.0 {
+ TermId::TypeAliasId(def_id) => def_id.loc(self.db).container,
+ TermId::ConstId(def_id) => def_id.loc(self.db).container,
+ };
+ let ItemContainerId::TraitId(trait_) = container else {
+ panic!("a TraitAssocTermId can only come from a trait")
+ };
+ trait_.into()
+ }
- let container = match def_id {
- SolverDefId::FunctionId(it) => it.lookup(self.db()).container,
- SolverDefId::TypeAliasId(it) => it.lookup(self.db()).container,
- SolverDefId::ConstId(it) => it.lookup(self.db()).container,
- SolverDefId::InternedClosureId(it) => {
- return it.loc(self.db).0.generic_def(self.db()).into();
- }
- SolverDefId::InternedCoroutineId(it) => {
- return it.loc(self.db).0.generic_def(self.db()).into();
- }
- SolverDefId::InternedCoroutineClosureId(it) => {
- return it.loc(self.db).0.generic_def(self.db()).into();
- }
- SolverDefId::StaticId(_)
- | SolverDefId::AdtId(_)
- | SolverDefId::TraitId(_)
- | SolverDefId::ImplId(_)
- | SolverDefId::BuiltinDeriveImplId(_)
- | SolverDefId::EnumVariantId(..)
- | SolverDefId::Ctor(..)
- | SolverDefId::InternedOpaqueTyId(..)
- | SolverDefId::AnonConstId(_) => panic!(),
+ fn impl_or_trait_assoc_term_parent(self, def_id: Self::ImplOrTraitAssocTermId) -> Self::DefId {
+ let container = match def_id.0 {
+ TermId::TypeAliasId(def_id) => def_id.loc(self.db).container,
+ TermId::ConstId(def_id) => def_id.loc(self.db).container,
};
+ match container {
+ ItemContainerId::ImplId(impl_) => impl_.into(),
+ ItemContainerId::TraitId(trait_) => trait_.into(),
+ ItemContainerId::ExternBlockId(_) | ItemContainerId::ModuleId(_) => {
+ panic!("only impl or trait can be the parent of ImplOrTraitAssocTermId")
+ }
+ }
+ }
+ fn inherent_alias_term_parent(self, def_id: Self::InherentAssocTermId) -> Self::ImplId {
+ let container = match def_id.0 {
+ TermId::TypeAliasId(def_id) => def_id.loc(self.db).container,
+ TermId::ConstId(def_id) => def_id.loc(self.db).container,
+ };
match container {
- ItemContainerId::ImplId(it) => it.into(),
- ItemContainerId::TraitId(it) => it.into(),
- ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => panic!(),
+ ItemContainerId::ImplId(impl_) => impl_.into(),
+ ItemContainerId::ExternBlockId(_)
+ | ItemContainerId::ModuleId(_)
+ | ItemContainerId::TraitId(_) => {
+ panic!("only impl can be the parent of InherentAliasTermId")
+ }
}
}
@@ -1303,6 +1213,10 @@ impl<'db> Interner for DbInterner<'db> {
50
}
+ fn is_type_const(self, _def_id: Self::DefId) -> bool {
+ false
+ }
+
fn features(self) -> Features {
Features
}
@@ -1315,28 +1229,35 @@ impl<'db> Interner for DbInterner<'db> {
}
fn coroutine_movability(self, def_id: Self::CoroutineId) -> rustc_ast_ir::Movability {
- // FIXME: Make this a query? I don't believe this can be accessed from bodies other than
- // the current infer query, except with revealed opaques - is it rare enough to not matter?
- let InternedClosure(owner, expr_id) = def_id.0.loc(self.db);
- let store = ExpressionStore::of(self.db, owner);
- let expr = &store[expr_id];
- match *expr {
- hir_def::hir::Expr::Closure { closure_kind, .. } => match closure_kind {
- hir_def::hir::ClosureKind::Coroutine(movability) => match movability {
- hir_def::hir::Movability::Static => rustc_ast_ir::Movability::Static,
- hir_def::hir::Movability::Movable => rustc_ast_ir::Movability::Movable,
- },
- hir_def::hir::ClosureKind::AsyncBlock { .. } => rustc_ast_ir::Movability::Static,
- _ => panic!("unexpected expression for a coroutine: {expr:?}"),
+ match def_id.0.loc(self.db).kind {
+ hir_def::hir::ClosureKind::OldCoroutine(movability) => match movability {
+ hir_def::hir::Movability::Static => rustc_ast_ir::Movability::Static,
+ hir_def::hir::Movability::Movable => rustc_ast_ir::Movability::Movable,
},
- _ => panic!("unexpected expression for a coroutine: {expr:?}"),
+ hir_def::hir::ClosureKind::Coroutine { .. } => rustc_ast_ir::Movability::Static,
+ kind => panic!("unexpected kind for a coroutine: {kind:?}"),
}
}
fn coroutine_for_closure(self, def_id: Self::CoroutineClosureId) -> Self::CoroutineId {
- let InternedClosure(owner, coroutine_closure_expr) = def_id.0.loc(self.db);
+ let InternedClosure { owner, expr: coroutine_closure_expr, kind: coroutine_closure_kind } =
+ def_id.0.loc(self.db);
+ let coroutine_closure_kind = match coroutine_closure_kind {
+ HirClosureKind::CoroutineClosure(it) => it,
+ _ => {
+ panic!("invalid kind closure kind {coroutine_closure_kind:?} for coroutine closure")
+ }
+ };
let coroutine_expr = ExpressionStore::coroutine_for_closure(coroutine_closure_expr);
- InternedCoroutineId::new(self.db, InternedClosure(owner, coroutine_expr)).into()
+ let coroutine_kind = hir_def::hir::ClosureKind::Coroutine {
+ kind: coroutine_closure_kind,
+ source: hir_def::hir::CoroutineSource::Closure,
+ };
+ InternedCoroutineId::new(
+ self.db,
+ InternedClosure { owner, expr: coroutine_expr, kind: coroutine_kind },
+ )
+ .into()
}
fn generics_require_sized_self(self, def_id: Self::DefId) -> bool {
@@ -1348,22 +1269,24 @@ impl<'db> Interner for DbInterner<'db> {
// Search for a predicate like `Self : Sized` amongst the trait bounds.
let predicates = self.predicates_of(def_id);
- elaborate(self, predicates.iter_identity()).any(|pred| match pred.kind().skip_binder() {
- ClauseKind::Trait(ref trait_pred) => {
- trait_pred.def_id() == sized_def_id
- && matches!(
- trait_pred.self_ty().kind(),
- TyKind::Param(ParamTy { index: 0, .. })
- )
+ elaborate(self, predicates.iter_identity().map(Unnormalized::skip_norm_wip)).any(|pred| {
+ match pred.kind().skip_binder() {
+ ClauseKind::Trait(ref trait_pred) => {
+ trait_pred.def_id() == sized_def_id
+ && matches!(
+ trait_pred.self_ty().kind(),
+ TyKind::Param(ParamTy { index: 0, .. })
+ )
+ }
+ ClauseKind::RegionOutlives(_)
+ | ClauseKind::TypeOutlives(_)
+ | ClauseKind::Projection(_)
+ | ClauseKind::ConstArgHasType(_, _)
+ | ClauseKind::WellFormed(_)
+ | ClauseKind::ConstEvaluatable(_)
+ | ClauseKind::HostEffect(..)
+ | ClauseKind::UnstableFeature(_) => false,
}
- ClauseKind::RegionOutlives(_)
- | ClauseKind::TypeOutlives(_)
- | ClauseKind::Projection(_)
- | ClauseKind::ConstArgHasType(_, _)
- | ClauseKind::WellFormed(_)
- | ClauseKind::ConstEvaluatable(_)
- | ClauseKind::HostEffect(..)
- | ClauseKind::UnstableFeature(_) => false,
})
}
@@ -1485,22 +1408,22 @@ impl<'db> Interner for DbInterner<'db> {
false
}
- fn require_lang_item(self, lang_item: SolverLangItem) -> Self::DefId {
+ fn require_projection_lang_item(
+ self,
+ lang_item: SolverProjectionLangItem,
+ ) -> Self::TraitAssocTyId {
let lang_items = self.lang_items();
let lang_item = match lang_item {
- SolverLangItem::AsyncFnKindUpvars => lang_items.AsyncFnKindUpvars,
- SolverLangItem::AsyncFnOnceOutput => lang_items.AsyncFnOnceOutput,
- SolverLangItem::CallOnceFuture => lang_items.CallOnceFuture,
- SolverLangItem::CallRefFuture => lang_items.CallRefFuture,
- SolverLangItem::CoroutineReturn => lang_items.CoroutineReturn,
- SolverLangItem::CoroutineYield => lang_items.CoroutineYield,
- SolverLangItem::FutureOutput => lang_items.FutureOutput,
- SolverLangItem::Metadata => lang_items.Metadata,
- SolverLangItem::DynMetadata => {
- return lang_items.DynMetadata.expect("Lang item required but not found.").into();
- }
- SolverLangItem::FieldBase => lang_items.FieldBase,
- SolverLangItem::FieldType => lang_items.FieldType,
+ SolverProjectionLangItem::AsyncFnKindUpvars => lang_items.AsyncFnKindUpvars,
+ SolverProjectionLangItem::AsyncFnOnceOutput => lang_items.AsyncFnOnceOutput,
+ SolverProjectionLangItem::CallOnceFuture => lang_items.CallOnceFuture,
+ SolverProjectionLangItem::CallRefFuture => lang_items.CallRefFuture,
+ SolverProjectionLangItem::CoroutineReturn => lang_items.CoroutineReturn,
+ SolverProjectionLangItem::CoroutineYield => lang_items.CoroutineYield,
+ SolverProjectionLangItem::FutureOutput => lang_items.FutureOutput,
+ SolverProjectionLangItem::Metadata => lang_items.Metadata,
+ SolverProjectionLangItem::FieldBase => lang_items.FieldBase,
+ SolverProjectionLangItem::FieldType => lang_items.FieldType,
};
lang_item.expect("Lang item required but not found.").into()
}
@@ -1512,9 +1435,6 @@ impl<'db> Interner for DbInterner<'db> {
SolverTraitLangItem::AsyncFnKindHelper => lang_items.AsyncFnKindHelper,
SolverTraitLangItem::AsyncFnMut => lang_items.AsyncFnMut,
SolverTraitLangItem::AsyncFnOnce => lang_items.AsyncFnOnce,
- SolverTraitLangItem::AsyncFnOnceOutput => unimplemented!(
- "This is incorrectly marked as `SolverTraitLangItem`, and is not used by the solver."
- ),
SolverTraitLangItem::AsyncIterator => lang_items.AsyncIterator,
SolverTraitLangItem::Clone => lang_items.Clone,
SolverTraitLangItem::Copy => lang_items.Copy,
@@ -1547,14 +1467,19 @@ impl<'db> Interner for DbInterner<'db> {
fn require_adt_lang_item(self, lang_item: SolverAdtLangItem) -> AdtIdWrapper {
let lang_items = self.lang_items();
let lang_item = match lang_item {
- SolverAdtLangItem::Option => lang_items.Option,
- SolverAdtLangItem::Poll => lang_items.Poll,
+ SolverAdtLangItem::Option => lang_items.Option.map(Into::into),
+ SolverAdtLangItem::Poll => lang_items.Poll.map(Into::into),
+ SolverAdtLangItem::DynMetadata => lang_items.DynMetadata.map(Into::into),
};
- AdtIdWrapper(lang_item.expect("Lang item required but not found.").into())
+ AdtIdWrapper(lang_item.expect("Lang item required but not found."))
}
- fn is_lang_item(self, def_id: Self::DefId, lang_item: SolverLangItem) -> bool {
- self.as_lang_item(def_id)
+ fn is_projection_lang_item(
+ self,
+ def_id: Self::TraitAssocTyId,
+ lang_item: SolverProjectionLangItem,
+ ) -> bool {
+ self.as_projection_lang_item(def_id)
.map_or(false, |l| std::mem::discriminant(&l) == std::mem::discriminant(&lang_item))
}
@@ -1562,15 +1487,6 @@ impl<'db> Interner for DbInterner<'db> {
is_lang_item!(
SolverTraitLangItem, self, def_id.0, lang_item;
- ignore = {
- AsyncFnKindHelper,
- AsyncIterator,
- BikeshedGuaranteedNoDrop,
- FusedIterator,
- Field,
- AsyncFnOnceOutput, // This is incorrectly marked as `SolverTraitLangItem`, and is not used by the solver.
- }
-
Sized,
MetaSized,
PointeeSized,
@@ -1595,6 +1511,11 @@ impl<'db> Interner for DbInterner<'db> {
AsyncFnMut,
AsyncFnOnce,
TrivialClone,
+ AsyncFnKindHelper,
+ AsyncIterator,
+ BikeshedGuaranteedNoDrop,
+ FusedIterator,
+ Field,
)
}
@@ -1604,64 +1525,29 @@ impl<'db> Interner for DbInterner<'db> {
.map_or(false, |l| std::mem::discriminant(&l) == std::mem::discriminant(&lang_item))
}
- fn as_lang_item(self, def_id: Self::DefId) -> Option<SolverLangItem> {
- match def_id {
- SolverDefId::TypeAliasId(id) => {
- as_lang_item!(
- SolverLangItem, self, id;
-
- ignore = {
- AsyncFnKindUpvars,
- DynMetadata,
- FieldBase,
- FieldType,
- }
-
- Metadata,
- CoroutineReturn,
- CoroutineYield,
- FutureOutput,
- CallRefFuture,
- CallOnceFuture,
- AsyncFnOnceOutput,
- )
- }
- SolverDefId::AdtId(AdtId::StructId(id)) => {
- as_lang_item!(
- SolverLangItem, self, id;
-
- ignore = {
- AsyncFnKindUpvars,
- Metadata,
- CoroutineReturn,
- CoroutineYield,
- FutureOutput,
- CallRefFuture,
- CallOnceFuture,
- AsyncFnOnceOutput,
- FieldBase,
- FieldType,
- }
-
- DynMetadata,
- )
- }
- _ => panic!("Unexpected SolverDefId in as_lang_item"),
- }
+ fn as_projection_lang_item(
+ self,
+ def_id: Self::TraitAssocTyId,
+ ) -> Option<SolverProjectionLangItem> {
+ as_lang_item!(
+ SolverProjectionLangItem, self, def_id.0, TypeAliasId;
+
+ Metadata,
+ CoroutineReturn,
+ CoroutineYield,
+ FutureOutput,
+ CallRefFuture,
+ CallOnceFuture,
+ AsyncFnOnceOutput,
+ AsyncFnKindUpvars,
+ FieldBase,
+ FieldType,
+ )
}
fn as_trait_lang_item(self, def_id: Self::TraitId) -> Option<SolverTraitLangItem> {
as_lang_item!(
- SolverTraitLangItem, self, def_id.0;
-
- ignore = {
- AsyncFnKindHelper,
- AsyncIterator,
- BikeshedGuaranteedNoDrop,
- FusedIterator,
- Field,
- AsyncFnOnceOutput, // This is incorrectly marked as `SolverTraitLangItem`, and is not used by the solver.
- }
+ SolverTraitLangItem, self, def_id.0, TraitId;
Sized,
MetaSized,
@@ -1687,20 +1573,21 @@ impl<'db> Interner for DbInterner<'db> {
AsyncFnMut,
AsyncFnOnce,
TrivialClone,
+ AsyncFnKindHelper,
+ AsyncIterator,
+ BikeshedGuaranteedNoDrop,
+ FusedIterator,
+ Field,
)
}
fn as_adt_lang_item(self, def_id: Self::AdtId) -> Option<SolverAdtLangItem> {
- let AdtId::EnumId(def_id) = def_id.0 else {
- panic!("Unexpected SolverDefId in as_adt_lang_item");
- };
as_lang_item!(
- SolverAdtLangItem, self, def_id;
-
- ignore = {}
+ SolverAdtLangItem, self, def_id.0, AdtId;
Option,
Poll,
+ DynMetadata,
)
}
@@ -1869,7 +1756,7 @@ impl<'db> Interner for DbInterner<'db> {
});
}
- fn has_item_definition(self, _def_id: Self::DefId) -> bool {
+ fn has_item_definition(self, _def_id: Self::ImplOrTraitAssocTermId) -> bool {
// FIXME(next-solver): should check if the associated item has a value.
true
}
@@ -1940,41 +1827,28 @@ impl<'db> Interner for DbInterner<'db> {
}
fn is_general_coroutine(self, def_id: Self::CoroutineId) -> bool {
- // FIXME: Make this a query? I don't believe this can be accessed from bodies other than
- // the current infer query, except with revealed opaques - is it rare enough to not matter?
- let InternedClosure(owner, expr_id) = def_id.0.loc(self.db);
- let store = ExpressionStore::of(self.db, owner);
- matches!(
- store[expr_id],
- hir_def::hir::Expr::Closure {
- closure_kind: hir_def::hir::ClosureKind::Coroutine(_),
- ..
- }
- )
+ matches!(def_id.0.loc(self.db).kind, HirClosureKind::OldCoroutine(_))
}
fn coroutine_is_async(self, def_id: Self::CoroutineId) -> bool {
- // FIXME: Make this a query? I don't believe this can be accessed from bodies other than
- // the current infer query, except with revealed opaques - is it rare enough to not matter?
- let InternedClosure(owner, expr_id) = def_id.0.loc(self.db);
- let store = ExpressionStore::of(self.db, owner);
matches!(
- store[expr_id],
- hir_def::hir::Expr::Closure {
- closure_kind: hir_def::hir::ClosureKind::AsyncBlock { .. },
- ..
- }
+ def_id.0.loc(self.db).kind,
+ HirClosureKind::Coroutine { kind: HirCoroutineKind::Async, .. }
)
}
- fn coroutine_is_gen(self, _coroutine_def_id: Self::CoroutineId) -> bool {
- // We don't handle gen coroutines yet.
- false
+ fn coroutine_is_gen(self, def_id: Self::CoroutineId) -> bool {
+ matches!(
+ def_id.0.loc(self.db).kind,
+ HirClosureKind::Coroutine { kind: HirCoroutineKind::Gen, .. }
+ )
}
- fn coroutine_is_async_gen(self, _coroutine_def_id: Self::CoroutineId) -> bool {
- // We don't handle gen coroutines yet.
- false
+ fn coroutine_is_async_gen(self, def_id: Self::CoroutineId) -> bool {
+ matches!(
+ def_id.0.loc(self.db).kind,
+ HirClosureKind::Coroutine { kind: HirCoroutineKind::AsyncGen, .. }
+ )
}
fn unsizing_params_for_adt(self, id: Self::AdtId) -> Self::UnsizingParams {
@@ -1994,16 +1868,21 @@ 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() {
+ for arg in ty.instantiate_identity().skip_norm_wip().walk() {
if let Some(i) = maybe_unsizing_param_idx(arg) {
unsizing_params.insert(i);
}
@@ -2012,7 +1891,7 @@ impl<'db> Interner for DbInterner<'db> {
// Ensure none of the other fields mention the parameters used
// in unsizing.
for field in prefix_fields {
- for arg in field_types[field.0].get().instantiate_identity().walk() {
+ for arg in field_types[field.0].get().instantiate_identity().skip_norm_wip().walk() {
if let Some(i) = maybe_unsizing_param_idx(arg) {
unsizing_params.remove(i);
}
@@ -2066,7 +1945,7 @@ impl<'db> Interner for DbInterner<'db> {
}
fn opaque_types_defined_by(self, def_id: Self::LocalDefId) -> Self::LocalDefIds {
- let Ok(def_id) = DefWithBodyId::try_from(def_id) else {
+ let Ok(def_id) = InferBodyId::try_from(def_id) else {
return SolverDefIds::default();
};
let mut result = Vec::new();
@@ -2075,33 +1954,54 @@ impl<'db> Interner for DbInterner<'db> {
}
fn opaque_types_and_coroutines_defined_by(self, def_id: Self::LocalDefId) -> Self::LocalDefIds {
- let Ok(def_id) = DefWithBodyId::try_from(def_id) else {
+ let db = self.db;
+
+ let Ok(def_id) = InferBodyId::try_from(def_id) else {
return SolverDefIds::default();
};
let mut result = Vec::new();
- crate::opaques::opaque_types_defined_by(self.db, def_id, &mut result);
+ crate::opaques::opaque_types_defined_by(db, def_id, &mut result);
// Collect coroutines.
- let body = Body::of(self.db, def_id);
- body.exprs().for_each(|(expr_id, expr)| {
- if matches!(
- expr,
- hir_def::hir::Expr::Closure {
- closure_kind: hir_def::hir::ClosureKind::AsyncBlock { .. }
- | hir_def::hir::ClosureKind::Coroutine(_),
+ let (store, root_expr) = def_id.store_and_root_expr(db);
+ // We can't just visit all exprs, since this may end up in unrelated anon consts.
+ CoroutinesVisitor { db: self.db, owner: def_id, store, coroutines: &mut result }
+ .on_expr(root_expr);
+
+ return SolverDefIds::new_from_slice(&result);
+
+ struct CoroutinesVisitor<'a> {
+ db: &'a dyn HirDatabase,
+ owner: InferBodyId,
+ store: &'a ExpressionStore,
+ coroutines: &'a mut Vec<SolverDefId>,
+ }
+
+ impl StoreVisitor for CoroutinesVisitor<'_> {
+ fn on_expr(&mut self, expr: ExprId) {
+ if let hir_def::hir::Expr::Closure {
+ closure_kind:
+ kind @ (hir_def::hir::ClosureKind::Coroutine { .. }
+ | hir_def::hir::ClosureKind::OldCoroutine(_)),
..
+ } = self.store[expr]
+ {
+ let coroutine = InternedCoroutineId::new(
+ self.db,
+ InternedClosure { owner: self.owner, expr, kind },
+ );
+ self.coroutines.push(coroutine.into());
}
- ) {
- let coroutine = InternedCoroutineId::new(
- self.db,
- InternedClosure(ExpressionStoreOwnerId::Body(def_id), expr_id),
- );
- result.push(coroutine.into());
- }
- });
- SolverDefIds::new_from_slice(&result)
+ self.store.visit_expr_children(expr, self);
+ }
+ fn on_pat(&mut self, pat: PatId) {
+ self.store.visit_pat_children(pat, self);
+ }
+ // Do not visit anon consts, they're separate bodies.
+ fn on_anon_const_expr(&mut self, _expr: ExprId) {}
+ }
}
fn alias_has_const_conditions(self, _def_id: Self::DefId) -> bool {
@@ -2134,26 +2034,23 @@ impl<'db> Interner for DbInterner<'db> {
fn opt_alias_variances(
self,
- _kind: impl Into<rustc_type_ir::AliasTermKind>,
- _def_id: Self::DefId,
+ _kind: impl Into<AliasTermKind<'db>>,
) -> Option<Self::VariancesOf> {
None
}
- fn type_of_opaque_hir_typeck(self, def_id: Self::LocalDefId) -> EarlyBinder<Self, Self::Ty> {
- match def_id {
- SolverDefId::InternedOpaqueTyId(opaque) => {
- let impl_trait_id = self.db().lookup_intern_impl_trait_id(opaque);
- match impl_trait_id {
- crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => {
- crate::opaques::rpit_hidden_types(self.db, func)[idx].get()
- }
- crate::ImplTraitId::TypeAliasImplTrait(type_alias, idx) => {
- crate::opaques::tait_hidden_types(self.db, type_alias)[idx].get()
- }
- }
+ fn type_of_opaque_hir_typeck(
+ self,
+ opaque: Self::LocalOpaqueTyId,
+ ) -> EarlyBinder<Self, Self::Ty> {
+ let impl_trait_id = opaque.0.loc(self.db);
+ match impl_trait_id {
+ crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => {
+ crate::opaques::rpit_hidden_types(self.db, func)[idx].get()
+ }
+ crate::ImplTraitId::TypeAliasImplTrait(type_alias, idx) => {
+ crate::opaques::tait_hidden_types(self.db, type_alias)[idx].get()
}
- _ => panic!("Unexpected SolverDefId in type_of_opaque_hir_typeck"),
}
}
@@ -2240,16 +2137,20 @@ impl<'db> Interner for DbInterner<'db> {
rustc_type_ir::AnonConstKind::GCE
}
- fn alias_ty_kind_from_def_id(self, def_id: Self::DefId) -> AliasTyKind<DbInterner<'db>> {
+ fn alias_ty_kind_from_def_id(self, def_id: Self::DefId) -> AliasTyKind<'db> {
match def_id {
SolverDefId::TypeAliasId(type_alias) => match type_alias.loc(self.db).container {
ItemContainerId::ExternBlockId(_) | ItemContainerId::ModuleId(_) => {
- AliasTyKind::Free { def_id }
+ AliasTyKind::Free { def_id: type_alias.into() }
+ }
+ ItemContainerId::ImplId(_) => AliasTyKind::Inherent { def_id: type_alias.into() },
+ ItemContainerId::TraitId(_) => {
+ AliasTyKind::Projection { def_id: type_alias.into() }
}
- ItemContainerId::ImplId(_) => AliasTyKind::Inherent { def_id },
- ItemContainerId::TraitId(_) => AliasTyKind::Projection { def_id },
},
- SolverDefId::InternedOpaqueTyId(_) => AliasTyKind::Opaque { def_id },
+ SolverDefId::InternedOpaqueTyId(def_id) => {
+ AliasTyKind::Opaque { def_id: def_id.into() }
+ }
_ => unreachable!(),
}
}
@@ -2339,7 +2240,7 @@ impl<'db> DbInterner<'db> {
output: Ty<'db>,
c_variadic: bool,
safety: Safety,
- abi: FnAbi,
+ abi: ExternAbi,
) -> FnSig<'db>
where
I: IntoIterator<Item = Ty<'db>>,
@@ -2349,9 +2250,7 @@ impl<'db> DbInterner<'db> {
self,
inputs.into_iter().chain(std::iter::once(output)),
),
- c_variadic,
- safety,
- abi,
+ fn_sig_kind: FnSigKind::new(abi, safety, c_variadic),
}
}
@@ -2360,23 +2259,22 @@ impl<'db> DbInterner<'db> {
where
I: IntoIterator<Item = Ty<'db>>,
{
- FnSig {
- inputs_and_output: Tys::new_from_iter(
- self,
- inputs.into_iter().chain(std::iter::once(output)),
- ),
- c_variadic: false,
- safety: Safety::Safe,
- abi: FnAbi::Rust,
- }
+ self.mk_fn_sig(inputs, output, false, Safety::Safe, ExternAbi::Rust)
}
}
fn predicates_of(db: &dyn HirDatabase, def_id: SolverDefId) -> &GenericPredicates {
- if let SolverDefId::BuiltinDeriveImplId(impl_) = def_id {
- crate::builtin_derive::predicates(db, impl_)
- } else {
- GenericPredicates::query(db, def_id.try_into().unwrap())
+ match def_id {
+ SolverDefId::BuiltinDeriveImplId(impl_) => crate::builtin_derive::predicates(db, impl_),
+ SolverDefId::AnonConstId(anon_const) => {
+ let loc = anon_const.loc(db);
+ if loc.allow_using_generic_params {
+ GenericPredicates::query(db, loc.owner.generic_def(db))
+ } else {
+ GenericPredicates::empty()
+ }
+ }
+ _ => GenericPredicates::query(db, def_id.try_into().unwrap()),
}
}
@@ -2428,10 +2326,22 @@ TrivialTypeTraversalImpls! {
CoroutineIdWrapper,
CoroutineClosureIdWrapper,
AdtIdWrapper,
+ TraitAssocTyId,
+ TraitAssocConstId,
+ TraitAssocTermId,
+ ImplOrTraitAssocTyId,
+ ImplOrTraitAssocConstId,
+ ImplOrTraitAssocTermId,
+ FreeTyAliasId,
+ FreeConstAliasId,
+ FreeTermAliasId,
+ InherentAssocTyId,
+ InherentAssocConstId,
+ InherentAssocTermId,
+ OpaqueTyIdWrapper,
AnyImplId,
GeneralConstIdWrapper,
Safety,
- FnAbi,
Span,
ParamConst,
ParamTy,