Enum variants are not generic def ids

This commit is contained in:
Lukas Wirth 2024-06-23 15:22:42 +02:00
parent 3432ef4414
commit 3168ab5b99
22 changed files with 188 additions and 178 deletions

View file

@ -252,8 +252,9 @@ impl TyBuilder<()> {
/// This method prepopulates the builder with placeholder substitution of `parent`, so you
/// should only push exactly 3 `GenericArg`s before building.
pub fn subst_for_coroutine(db: &dyn HirDatabase, parent: DefWithBodyId) -> TyBuilder<()> {
let parent_subst =
parent.as_generic_def_id().map(|p| generics(db.upcast(), p).placeholder_subst(db));
let parent_subst = parent
.as_generic_def_id(db.upcast())
.map(|p| generics(db.upcast(), p).placeholder_subst(db));
// These represent resume type, yield type, and return type of coroutine.
let params = std::iter::repeat(ParamKind::Type).take(3).collect();
TyBuilder::new((), params, parent_subst)
@ -266,7 +267,7 @@ impl TyBuilder<()> {
) -> Substitution {
let sig_ty = sig_ty.cast(Interner);
let self_subst = iter::once(&sig_ty);
let Some(parent) = parent.as_generic_def_id() else {
let Some(parent) = parent.as_generic_def_id(db.upcast()) else {
return Substitution::from_iter(Interner, self_subst);
};
Substitution::from_iter(

View file

@ -13,7 +13,8 @@ use hir_def::{
data::adt::StructFlags,
hir::Movability,
lang_item::{LangItem, LangItemTarget},
AssocItemId, BlockId, GenericDefId, HasModule, ItemContainerId, Lookup, TypeAliasId, VariantId,
AssocItemId, BlockId, CallableDefId, GenericDefId, HasModule, ItemContainerId, Lookup,
TypeAliasId, VariantId,
};
use hir_expand::name::name;
@ -28,9 +29,9 @@ use crate::{
to_assoc_type_id, to_chalk_trait_id,
traits::ChalkContext,
utils::ClosureSubst,
wrap_empty_binders, AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId,
Interner, ProjectionTy, ProjectionTyExt, QuantifiedWhereClause, Substitution, TraitRef,
TraitRefExt, Ty, TyBuilder, TyExt, TyKind, WhereClause,
wrap_empty_binders, AliasEq, AliasTy, BoundVar, DebruijnIndex, FnDefId, Interner, ProjectionTy,
ProjectionTyExt, QuantifiedWhereClause, Substitution, TraitRef, TraitRefExt, Ty, TyBuilder,
TyExt, TyKind, WhereClause,
};
pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>;
@ -102,7 +103,7 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
&self,
fn_def_id: chalk_ir::FnDefId<Interner>,
) -> Arc<rust_ir::FnDefDatum<Interner>> {
self.db.fn_def_datum(self.krate, fn_def_id)
self.db.fn_def_datum(fn_def_id)
}
fn impls_for_trait(
@ -912,16 +913,13 @@ fn type_alias_associated_ty_value(
Arc::new(value)
}
pub(crate) fn fn_def_datum_query(
db: &dyn HirDatabase,
_krate: CrateId,
fn_def_id: FnDefId,
) -> Arc<FnDefDatum> {
pub(crate) fn fn_def_datum_query(db: &dyn HirDatabase, fn_def_id: FnDefId) -> Arc<FnDefDatum> {
let callable_def: CallableDefId = from_chalk(db, fn_def_id);
let generic_params = generics(db.upcast(), callable_def.into());
let generic_def = GenericDefId::from(db.upcast(), callable_def);
let generic_params = generics(db.upcast(), generic_def);
let (sig, binders) = db.callable_item_signature(callable_def).into_value_and_skipped_binders();
let bound_vars = generic_params.bound_vars_subst(db, DebruijnIndex::INNERMOST);
let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars);
let where_clauses = convert_where_clauses(db, generic_def, &bound_vars);
let bound = rust_ir::FnDefDatumBound {
// Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway
inputs_and_output: chalk_ir::Binders::empty(
@ -948,7 +946,7 @@ pub(crate) fn fn_def_datum_query(
pub(crate) fn fn_def_variance_query(db: &dyn HirDatabase, fn_def_id: FnDefId) -> Variances {
let callable_def: CallableDefId = from_chalk(db, fn_def_id);
let generic_params = generics(db.upcast(), callable_def.into());
let generic_params = generics(db.upcast(), GenericDefId::from(db.upcast(), callable_def));
Variances::from_iter(
Interner,
std::iter::repeat(chalk_ir::Variance::Invariant).take(generic_params.len()),

View file

@ -188,9 +188,10 @@ impl TyExt for Ty {
fn as_generic_def(&self, db: &dyn HirDatabase) -> Option<GenericDefId> {
match *self.kind(Interner) {
TyKind::Adt(AdtId(adt), ..) => Some(adt.into()),
TyKind::FnDef(callable, ..) => {
Some(db.lookup_intern_callable_def(callable.into()).into())
}
TyKind::FnDef(callable, ..) => Some(GenericDefId::from(
db.upcast(),
db.lookup_intern_callable_def(callable.into()),
)),
TyKind::AssociatedType(type_alias, ..) => Some(from_assoc_type_id(type_alias).into()),
TyKind::Foreign(type_alias, ..) => Some(from_foreign_def_id(type_alias).into()),
_ => None,

View file

@ -9,8 +9,8 @@ use base_db::{
CrateId, Upcast,
};
use hir_def::{
db::DefDatabase, hir::ExprId, layout::TargetDataLayout, AdtId, BlockId, ConstParamId,
DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId, GenericDefId, ImplId,
db::DefDatabase, hir::ExprId, layout::TargetDataLayout, AdtId, BlockId, CallableDefId,
ConstParamId, DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId, GenericDefId, ImplId,
LifetimeParamId, LocalFieldId, StaticId, TypeAliasId, TypeOrConstParamId, VariantId,
};
use la_arena::ArenaMap;
@ -24,9 +24,8 @@ use crate::{
lower::{GenericDefaults, GenericPredicates},
method_resolution::{InherentImpls, TraitImpls, TyFingerprint},
mir::{BorrowckResult, MirBody, MirLowerError},
Binders, CallableDefId, ClosureId, Const, FnDefId, ImplTraitId, ImplTraits, InferenceResult,
Interner, PolyFnSig, QuantifiedWhereClause, Substitution, TraitEnvironment, TraitRef, Ty,
TyDefId, ValueTyDefId,
Binders, ClosureId, Const, FnDefId, ImplTraitId, ImplTraits, InferenceResult, Interner,
PolyFnSig, Substitution, TraitEnvironment, TraitRef, Ty, TyDefId, ValueTyDefId,
};
use hir_expand::name::Name;
@ -145,7 +144,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
def: GenericDefId,
param_id: TypeOrConstParamId,
assoc_name: Option<Name>,
) -> Arc<[Binders<QuantifiedWhereClause>]>;
) -> GenericPredicates;
#[salsa::invoke(crate::lower::generic_predicates_query)]
fn generic_predicates(&self, def: GenericDefId) -> GenericPredicates;
@ -232,7 +231,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
) -> sync::Arc<chalk_db::ImplDatum>;
#[salsa::invoke(chalk_db::fn_def_datum_query)]
fn fn_def_datum(&self, krate: CrateId, fn_def_id: FnDefId) -> sync::Arc<chalk_db::FnDefDatum>;
fn fn_def_datum(&self, fn_def_id: FnDefId) -> sync::Arc<chalk_db::FnDefDatum>;
#[salsa::invoke(chalk_db::fn_def_variance_query)]
fn fn_def_variance(&self, fn_def_id: FnDefId) -> chalk_db::Variances;

View file

@ -21,8 +21,8 @@ use hir_def::{
path::{Path, PathKind},
type_ref::{TraitBoundModifier, TypeBound, TypeRef},
visibility::Visibility,
HasModule, ImportPathConfig, ItemContainerId, LocalFieldId, Lookup, ModuleDefId, ModuleId,
TraitId,
GenericDefId, HasModule, ImportPathConfig, ItemContainerId, LocalFieldId, Lookup, ModuleDefId,
ModuleId, TraitId,
};
use hir_expand::name::Name;
use intern::{Internable, Interned};
@ -988,7 +988,8 @@ impl HirDisplay for Ty {
f.end_location_link();
if parameters.len(Interner) > 0 {
let generics = generics(db.upcast(), def.into());
let generic_def_id = GenericDefId::from(db.upcast(), def);
let generics = generics(db.upcast(), generic_def_id);
let (parent_len, self_param, type_, const_, impl_, lifetime) =
generics.provenance_split();
let parameters = parameters.as_slice(Interner);
@ -1002,8 +1003,9 @@ impl HirDisplay for Ty {
debug_assert_eq!(parent_params.len(), parent_len);
let parent_params =
generic_args_sans_defaults(f, Some(def.into()), parent_params);
let fn_params = generic_args_sans_defaults(f, Some(def.into()), fn_params);
generic_args_sans_defaults(f, Some(generic_def_id), parent_params);
let fn_params =
generic_args_sans_defaults(f, Some(generic_def_id), fn_params);
write!(f, "<")?;
hir_fmt_generic_arguments(f, parent_params, None)?;

View file

@ -216,7 +216,6 @@ fn parent_generic_def(db: &dyn DefDatabase, def: GenericDefId) -> Option<Generic
GenericDefId::FunctionId(it) => it.lookup(db).container,
GenericDefId::TypeAliasId(it) => it.lookup(db).container,
GenericDefId::ConstId(it) => it.lookup(db).container,
GenericDefId::EnumVariantId(it) => return Some(it.lookup(db).parent.into()),
GenericDefId::AdtId(_)
| GenericDefId::TraitId(_)
| GenericDefId::ImplId(_)

View file

@ -13,7 +13,7 @@ use hir_def::{
},
lang_item::{LangItem, LangItemTarget},
path::{GenericArgs, Path},
BlockId, FieldId, GenericParamId, ItemContainerId, Lookup, TupleFieldId, TupleId,
BlockId, FieldId, GenericDefId, GenericParamId, ItemContainerId, Lookup, TupleFieldId, TupleId,
};
use hir_expand::name::{name, Name};
use stdx::always;
@ -1895,7 +1895,8 @@ impl InferenceContext<'_> {
let callable_ty = self.resolve_ty_shallow(callable_ty);
if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind(Interner) {
let def: CallableDefId = from_chalk(self.db, *fn_def);
let generic_predicates = self.db.generic_predicates(def.into());
let generic_predicates =
self.db.generic_predicates(GenericDefId::from(self.db.upcast(), def));
for predicate in generic_predicates.iter() {
let (predicate, binders) = predicate
.clone()

View file

@ -41,14 +41,7 @@ impl InferenceContext<'_> {
fn resolve_value_path(&mut self, path: &Path, id: ExprOrPatId) -> Option<ValuePathResolution> {
let (value, self_subst) = self.resolve_value_path_inner(path, id)?;
let value_def = match value {
ValueNs::LocalBinding(pat) => match self.result.type_of_binding.get(pat) {
Some(ty) => return Some(ValuePathResolution::NonGeneric(ty.clone())),
None => {
never!("uninferred pattern?");
return None;
}
},
let value_def: ValueTyDefId = match value {
ValueNs::FunctionId(it) => it.into(),
ValueNs::ConstId(it) => it.into(),
ValueNs::StaticId(it) => it.into(),
@ -62,48 +55,79 @@ impl InferenceContext<'_> {
it.into()
}
ValueNs::LocalBinding(pat) => {
return match self.result.type_of_binding.get(pat) {
Some(ty) => Some(ValuePathResolution::NonGeneric(ty.clone())),
None => {
never!("uninferred pattern?");
None
}
}
}
ValueNs::ImplSelf(impl_id) => {
let generics = crate::generics::generics(self.db.upcast(), impl_id.into());
let substs = generics.placeholder_subst(self.db);
let ty = self.db.impl_self_ty(impl_id).substitute(Interner, &substs);
if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() {
return Some(ValuePathResolution::GenericDef(
return if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() {
Some(ValuePathResolution::GenericDef(
struct_id.into(),
struct_id.into(),
substs.clone(),
));
))
} else {
// FIXME: report error, invalid Self reference
return None;
}
None
};
}
ValueNs::GenericParam(it) => {
return Some(ValuePathResolution::NonGeneric(self.db.const_param_ty(it)))
}
};
let generic_def_id = value_def.to_generic_def_id(self.db);
let Some(generic_def) = generic_def_id else {
// `value_def` is the kind of item that can never be generic (i.e. statics, at least
// currently). We can just skip the binders to get its type.
let (ty, binders) = self.db.value_ty(value_def)?.into_value_and_skipped_binders();
stdx::always!(binders.is_empty(Interner), "non-empty binders for non-generic def",);
return Some(ValuePathResolution::NonGeneric(ty));
};
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
let substs = ctx.substs_from_path(path, value_def, true);
let substs = substs.as_slice(Interner);
if let ValueNs::EnumVariantId(_) = value {
let mut it = self_subst
.as_ref()
.map_or(&[][..], |s| s.as_slice(Interner))
.iter()
.chain(substs)
.cloned();
let builder = TyBuilder::subst_for_def(self.db, generic_def, None);
let substs = builder
.fill(|x| {
it.next().unwrap_or_else(|| match x {
ParamKind::Type => {
self.result.standard_types.unknown.clone().cast(Interner)
}
ParamKind::Const(ty) => consteval::unknown_const_as_generic(ty.clone()),
ParamKind::Lifetime => error_lifetime().cast(Interner),
})
})
.build();
return Some(ValuePathResolution::GenericDef(value_def, generic_def, substs));
}
let parent_substs = self_subst.or_else(|| {
let generics = generics(self.db.upcast(), value_def.to_generic_def_id()?);
let generics = generics(self.db.upcast(), generic_def_id?);
let parent_params_len = generics.parent_generics()?.len();
let parent_args = &substs[substs.len() - parent_params_len..];
Some(Substitution::from_iter(Interner, parent_args))
});
let parent_substs_len = parent_substs.as_ref().map_or(0, |s| s.len(Interner));
let mut it = substs.iter().take(substs.len() - parent_substs_len).cloned();
let Some(generic_def) = value_def.to_generic_def_id() else {
// `value_def` is the kind of item that can never be generic (i.e. statics, at least
// currently). We can just skip the binders to get its type.
let (ty, binders) = self.db.value_ty(value_def)?.into_value_and_skipped_binders();
stdx::always!(
parent_substs.is_none() && binders.is_empty(Interner),
"non-empty binders for non-generic def",
);
return Some(ValuePathResolution::NonGeneric(ty));
};
let builder = TyBuilder::subst_for_def(self.db, generic_def, parent_substs);
let substs = builder
.fill(|x| {

View file

@ -60,7 +60,7 @@ use chalk_ir::{
NoSolution,
};
use either::Either;
use hir_def::{hir::ExprId, type_ref::Rawness, GeneralConstId, TypeOrConstParamId};
use hir_def::{hir::ExprId, type_ref::Rawness, CallableDefId, GeneralConstId, TypeOrConstParamId};
use hir_expand::name;
use la_arena::{Arena, Idx};
use mir::{MirEvalError, VTableMap};
@ -84,8 +84,8 @@ pub use infer::{
};
pub use interner::Interner;
pub use lower::{
associated_type_shorthand_candidates, CallableDefId, ImplTraitLoweringMode, ParamLoweringMode,
TyDefId, TyLoweringContext, ValueTyDefId,
associated_type_shorthand_candidates, ImplTraitLoweringMode, ParamLoweringMode, TyDefId,
TyLoweringContext, ValueTyDefId,
};
pub use mapping::{
from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, from_placeholder_idx,

View file

@ -11,10 +11,7 @@ use std::{
ops::{self, Not as _},
};
use base_db::{
salsa::{Cycle, InternValueTrivial},
CrateId,
};
use base_db::{salsa::Cycle, CrateId};
use chalk_ir::{
cast::Cast,
fold::{Shift, TypeFoldable},
@ -38,10 +35,10 @@ use hir_def::{
type_ref::{
ConstRef, LifetimeRef, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef,
},
AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, FunctionId,
GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstLoc, ItemContainerId, LocalFieldId,
Lookup, ModuleDefId, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId,
UnionId, VariantId,
AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId,
FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstLoc, ItemContainerId,
LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId,
TypeOwnerId, UnionId, VariantId,
};
use hir_expand::{name::Name, ExpandResult};
use intern::Interned;
@ -1535,7 +1532,7 @@ pub(crate) fn generic_predicates_for_param_query(
def: GenericDefId,
param_id: TypeOrConstParamId,
assoc_name: Option<Name>,
) -> Arc<[Binders<QuantifiedWhereClause>]> {
) -> GenericPredicates {
let resolver = def.resolver(db.upcast());
let ctx = if let GenericDefId::FunctionId(_) = def {
TyLoweringContext::new(db, &resolver, def.into())
@ -1611,7 +1608,7 @@ pub(crate) fn generic_predicates_for_param_query(
);
};
}
predicates.into()
GenericPredicates(predicates.is_empty().not().then(|| predicates.into()))
}
pub(crate) fn generic_predicates_for_param_recover(
@ -1620,15 +1617,15 @@ pub(crate) fn generic_predicates_for_param_recover(
_def: &GenericDefId,
_param_id: &TypeOrConstParamId,
_assoc_name: &Option<Name>,
) -> Arc<[Binders<QuantifiedWhereClause>]> {
Arc::from_iter(None)
) -> GenericPredicates {
GenericPredicates(None)
}
pub(crate) fn trait_environment_for_body_query(
db: &dyn HirDatabase,
def: DefWithBodyId,
) -> Arc<TraitEnvironment> {
let Some(def) = def.as_generic_def_id() else {
let Some(def) = def.as_generic_def_id(db.upcast()) else {
let krate = def.module(db.upcast()).krate();
return TraitEnvironment::empty(krate);
};
@ -1995,47 +1992,6 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum CallableDefId {
FunctionId(FunctionId),
StructId(StructId),
EnumVariantId(EnumVariantId),
}
impl InternValueTrivial for CallableDefId {}
impl_from!(FunctionId, StructId, EnumVariantId for CallableDefId);
impl From<CallableDefId> for ModuleDefId {
fn from(def: CallableDefId) -> ModuleDefId {
match def {
CallableDefId::FunctionId(f) => ModuleDefId::FunctionId(f),
CallableDefId::StructId(s) => ModuleDefId::AdtId(AdtId::StructId(s)),
CallableDefId::EnumVariantId(e) => ModuleDefId::EnumVariantId(e),
}
}
}
impl CallableDefId {
pub fn krate(self, db: &dyn HirDatabase) -> CrateId {
let db = db.upcast();
match self {
CallableDefId::FunctionId(f) => f.krate(db),
CallableDefId::StructId(s) => s.krate(db),
CallableDefId::EnumVariantId(e) => e.krate(db),
}
}
}
impl From<CallableDefId> for GenericDefId {
fn from(def: CallableDefId) -> GenericDefId {
match def {
CallableDefId::FunctionId(f) => f.into(),
CallableDefId::StructId(s) => s.into(),
CallableDefId::EnumVariantId(e) => e.into(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum TyDefId {
BuiltinType(BuiltinType),
@ -2056,12 +2012,12 @@ pub enum ValueTyDefId {
impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for ValueTyDefId);
impl ValueTyDefId {
pub(crate) fn to_generic_def_id(self) -> Option<GenericDefId> {
pub(crate) fn to_generic_def_id(self, db: &dyn HirDatabase) -> Option<GenericDefId> {
match self {
Self::FunctionId(id) => Some(id.into()),
Self::StructId(id) => Some(id.into()),
Self::UnionId(id) => Some(id.into()),
Self::EnumVariantId(var) => Some(var.into()),
Self::EnumVariantId(var) => Some(var.lookup(db.upcast()).parent.into()),
Self::ConstId(id) => Some(id.into()),
Self::StaticId(_) => None,
}

View file

@ -483,7 +483,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
Ok(Some(current))
}
ValueNs::GenericParam(p) => {
let Some(def) = self.owner.as_generic_def_id() else {
let Some(def) = self.owner.as_generic_def_id(self.db.upcast()) else {
not_supported!("owner without generic def id");
};
let gen = generics(self.db.upcast(), def);
@ -1330,7 +1330,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
}
fn placeholder_subst(&mut self) -> Substitution {
match self.owner.as_generic_def_id() {
match self.owner.as_generic_def_id(self.db.upcast()) {
Some(it) => TyBuilder::placeholder_subst(self.db, it),
None => Substitution::empty(Interner),
}

View file

@ -302,7 +302,7 @@ pub fn monomorphized_mir_body_query(
subst: Substitution,
trait_env: Arc<crate::TraitEnvironment>,
) -> Result<Arc<MirBody>, MirLowerError> {
let generics = owner.as_generic_def_id().map(|g_def| generics(db.upcast(), g_def));
let generics = owner.as_generic_def_id(db.upcast()).map(|g_def| generics(db.upcast(), g_def));
let filler = &mut Filler { db, subst: &subst, trait_env, generics, owner };
let body = db.mir_body(owner)?;
let mut body = (*body).clone();
@ -327,7 +327,7 @@ pub fn monomorphized_mir_body_for_closure_query(
trait_env: Arc<crate::TraitEnvironment>,
) -> Result<Arc<MirBody>, MirLowerError> {
let InternedClosure(owner, _) = db.lookup_intern_closure(closure.into());
let generics = owner.as_generic_def_id().map(|g_def| generics(db.upcast(), g_def));
let generics = owner.as_generic_def_id(db.upcast()).map(|g_def| generics(db.upcast(), g_def));
let filler = &mut Filler { db, subst: &subst, trait_env, generics, owner };
let body = db.mir_body_for_closure(closure)?;
let mut body = (*body).clone();
@ -343,7 +343,7 @@ pub fn monomorphize_mir_body_bad(
trait_env: Arc<crate::TraitEnvironment>,
) -> Result<MirBody, MirLowerError> {
let owner = body.owner;
let generics = owner.as_generic_def_id().map(|g_def| generics(db.upcast(), g_def));
let generics = owner.as_generic_def_id(db.upcast()).map(|g_def| generics(db.upcast(), g_def));
let filler = &mut Filler { db, subst: &subst, trait_env, generics, owner };
filler.fill_body(&mut body)?;
Ok(body)