mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 20:42:04 +00:00
Enum variants are not generic def ids
This commit is contained in:
parent
3432ef4414
commit
3168ab5b99
22 changed files with 188 additions and 178 deletions
|
@ -582,13 +582,11 @@ impl GenericParams {
|
||||||
GenericDefId::TraitAliasId(id) => id_to_generics(db, id, enabled_params),
|
GenericDefId::TraitAliasId(id) => id_to_generics(db, id, enabled_params),
|
||||||
GenericDefId::TypeAliasId(id) => id_to_generics(db, id, enabled_params),
|
GenericDefId::TypeAliasId(id) => id_to_generics(db, id, enabled_params),
|
||||||
GenericDefId::ImplId(id) => id_to_generics(db, id, enabled_params),
|
GenericDefId::ImplId(id) => id_to_generics(db, id, enabled_params),
|
||||||
GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {
|
GenericDefId::ConstId(_) => Interned::new(GenericParams {
|
||||||
Interned::new(GenericParams {
|
type_or_consts: Default::default(),
|
||||||
type_or_consts: Default::default(),
|
lifetimes: Default::default(),
|
||||||
lifetimes: Default::default(),
|
where_predicates: Default::default(),
|
||||||
where_predicates: Default::default(),
|
}),
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -689,7 +689,7 @@ pub enum TypeOwnerId {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeOwnerId {
|
impl TypeOwnerId {
|
||||||
fn as_generic_def_id(self) -> Option<GenericDefId> {
|
fn as_generic_def_id(self, db: &dyn DefDatabase) -> Option<GenericDefId> {
|
||||||
Some(match self {
|
Some(match self {
|
||||||
TypeOwnerId::FunctionId(it) => GenericDefId::FunctionId(it),
|
TypeOwnerId::FunctionId(it) => GenericDefId::FunctionId(it),
|
||||||
TypeOwnerId::ConstId(it) => GenericDefId::ConstId(it),
|
TypeOwnerId::ConstId(it) => GenericDefId::ConstId(it),
|
||||||
|
@ -698,7 +698,9 @@ impl TypeOwnerId {
|
||||||
TypeOwnerId::TraitAliasId(it) => GenericDefId::TraitAliasId(it),
|
TypeOwnerId::TraitAliasId(it) => GenericDefId::TraitAliasId(it),
|
||||||
TypeOwnerId::TypeAliasId(it) => GenericDefId::TypeAliasId(it),
|
TypeOwnerId::TypeAliasId(it) => GenericDefId::TypeAliasId(it),
|
||||||
TypeOwnerId::ImplId(it) => GenericDefId::ImplId(it),
|
TypeOwnerId::ImplId(it) => GenericDefId::ImplId(it),
|
||||||
TypeOwnerId::EnumVariantId(it) => GenericDefId::EnumVariantId(it),
|
TypeOwnerId::EnumVariantId(it) => {
|
||||||
|
GenericDefId::AdtId(AdtId::EnumId(it.lookup(db).parent))
|
||||||
|
}
|
||||||
TypeOwnerId::InTypeConstId(_) | TypeOwnerId::StaticId(_) => return None,
|
TypeOwnerId::InTypeConstId(_) | TypeOwnerId::StaticId(_) => return None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -740,7 +742,6 @@ impl From<GenericDefId> for TypeOwnerId {
|
||||||
GenericDefId::TraitAliasId(it) => it.into(),
|
GenericDefId::TraitAliasId(it) => it.into(),
|
||||||
GenericDefId::TypeAliasId(it) => it.into(),
|
GenericDefId::TypeAliasId(it) => it.into(),
|
||||||
GenericDefId::ImplId(it) => it.into(),
|
GenericDefId::ImplId(it) => it.into(),
|
||||||
GenericDefId::EnumVariantId(it) => it.into(),
|
|
||||||
GenericDefId::ConstId(it) => it.into(),
|
GenericDefId::ConstId(it) => it.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -849,8 +850,8 @@ impl GeneralConstId {
|
||||||
pub fn generic_def(self, db: &dyn DefDatabase) -> Option<GenericDefId> {
|
pub fn generic_def(self, db: &dyn DefDatabase) -> Option<GenericDefId> {
|
||||||
match self {
|
match self {
|
||||||
GeneralConstId::ConstId(it) => Some(it.into()),
|
GeneralConstId::ConstId(it) => Some(it.into()),
|
||||||
GeneralConstId::ConstBlockId(it) => it.lookup(db).parent.as_generic_def_id(),
|
GeneralConstId::ConstBlockId(it) => it.lookup(db).parent.as_generic_def_id(db),
|
||||||
GeneralConstId::InTypeConstId(it) => it.lookup(db).owner.as_generic_def_id(),
|
GeneralConstId::InTypeConstId(it) => it.lookup(db).owner.as_generic_def_id(db),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -888,12 +889,12 @@ impl From<EnumVariantId> for DefWithBodyId {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DefWithBodyId {
|
impl DefWithBodyId {
|
||||||
pub fn as_generic_def_id(self) -> Option<GenericDefId> {
|
pub fn as_generic_def_id(self, db: &dyn DefDatabase) -> Option<GenericDefId> {
|
||||||
match self {
|
match self {
|
||||||
DefWithBodyId::FunctionId(f) => Some(f.into()),
|
DefWithBodyId::FunctionId(f) => Some(f.into()),
|
||||||
DefWithBodyId::StaticId(_) => None,
|
DefWithBodyId::StaticId(_) => None,
|
||||||
DefWithBodyId::ConstId(c) => Some(c.into()),
|
DefWithBodyId::ConstId(c) => Some(c.into()),
|
||||||
DefWithBodyId::VariantId(c) => Some(c.into()),
|
DefWithBodyId::VariantId(c) => Some(c.lookup(db).parent.into()),
|
||||||
// FIXME: stable rust doesn't allow generics in constants, but we should
|
// FIXME: stable rust doesn't allow generics in constants, but we should
|
||||||
// use `TypeOwnerId::as_generic_def_id` when it does.
|
// use `TypeOwnerId::as_generic_def_id` when it does.
|
||||||
DefWithBodyId::InTypeConstId(_) => None,
|
DefWithBodyId::InTypeConstId(_) => None,
|
||||||
|
@ -921,10 +922,6 @@ pub enum GenericDefId {
|
||||||
TraitAliasId(TraitAliasId),
|
TraitAliasId(TraitAliasId),
|
||||||
TypeAliasId(TypeAliasId),
|
TypeAliasId(TypeAliasId),
|
||||||
ImplId(ImplId),
|
ImplId(ImplId),
|
||||||
// enum variants cannot have generics themselves, but their parent enums
|
|
||||||
// can, and this makes some code easier to write
|
|
||||||
// FIXME: Try to remove this as that will reduce the amount of query slots generated per enum?
|
|
||||||
EnumVariantId(EnumVariantId),
|
|
||||||
// consts can have type parameters from their parents (i.e. associated consts of traits)
|
// consts can have type parameters from their parents (i.e. associated consts of traits)
|
||||||
ConstId(ConstId),
|
ConstId(ConstId),
|
||||||
}
|
}
|
||||||
|
@ -935,7 +932,6 @@ impl_from!(
|
||||||
TraitAliasId,
|
TraitAliasId,
|
||||||
TypeAliasId,
|
TypeAliasId,
|
||||||
ImplId,
|
ImplId,
|
||||||
EnumVariantId,
|
|
||||||
ConstId
|
ConstId
|
||||||
for GenericDefId
|
for GenericDefId
|
||||||
);
|
);
|
||||||
|
@ -967,7 +963,6 @@ impl GenericDefId {
|
||||||
GenericDefId::TraitAliasId(it) => file_id_and_params_of_item_loc(db, it),
|
GenericDefId::TraitAliasId(it) => file_id_and_params_of_item_loc(db, it),
|
||||||
GenericDefId::ImplId(it) => file_id_and_params_of_item_loc(db, it),
|
GenericDefId::ImplId(it) => file_id_and_params_of_item_loc(db, it),
|
||||||
GenericDefId::ConstId(it) => (it.lookup(db).id.file_id(), None),
|
GenericDefId::ConstId(it) => (it.lookup(db).id.file_id(), None),
|
||||||
GenericDefId::EnumVariantId(it) => (it.lookup(db).id.file_id(), None),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -994,6 +989,46 @@ impl From<AssocItemId> for GenericDefId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[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 DefDatabase) -> CrateId {
|
||||||
|
match self {
|
||||||
|
CallableDefId::FunctionId(f) => f.krate(db),
|
||||||
|
CallableDefId::StructId(s) => s.krate(db),
|
||||||
|
CallableDefId::EnumVariantId(e) => e.krate(db),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GenericDefId {
|
||||||
|
pub fn from(db: &dyn DefDatabase, def: CallableDefId) -> GenericDefId {
|
||||||
|
match def {
|
||||||
|
CallableDefId::FunctionId(f) => f.into(),
|
||||||
|
CallableDefId::StructId(s) => s.into(),
|
||||||
|
CallableDefId::EnumVariantId(e) => e.lookup(db).parent.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum AttrDefId {
|
pub enum AttrDefId {
|
||||||
ModuleId(ModuleId),
|
ModuleId(ModuleId),
|
||||||
|
@ -1310,7 +1345,6 @@ impl HasModule for GenericDefId {
|
||||||
GenericDefId::TraitAliasId(it) => it.module(db),
|
GenericDefId::TraitAliasId(it) => it.module(db),
|
||||||
GenericDefId::TypeAliasId(it) => it.module(db),
|
GenericDefId::TypeAliasId(it) => it.module(db),
|
||||||
GenericDefId::ImplId(it) => it.module(db),
|
GenericDefId::ImplId(it) => it.module(db),
|
||||||
GenericDefId::EnumVariantId(it) => it.module(db),
|
|
||||||
GenericDefId::ConstId(it) => it.module(db),
|
GenericDefId::ConstId(it) => it.module(db),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1164,7 +1164,6 @@ impl HasResolver for GenericDefId {
|
||||||
GenericDefId::TraitAliasId(inner) => inner.resolver(db),
|
GenericDefId::TraitAliasId(inner) => inner.resolver(db),
|
||||||
GenericDefId::TypeAliasId(inner) => inner.resolver(db),
|
GenericDefId::TypeAliasId(inner) => inner.resolver(db),
|
||||||
GenericDefId::ImplId(inner) => inner.resolver(db),
|
GenericDefId::ImplId(inner) => inner.resolver(db),
|
||||||
GenericDefId::EnumVariantId(inner) => inner.resolver(db),
|
|
||||||
GenericDefId::ConstId(inner) => inner.resolver(db),
|
GenericDefId::ConstId(inner) => inner.resolver(db),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,8 +252,9 @@ impl TyBuilder<()> {
|
||||||
/// This method prepopulates the builder with placeholder substitution of `parent`, so you
|
/// This method prepopulates the builder with placeholder substitution of `parent`, so you
|
||||||
/// should only push exactly 3 `GenericArg`s before building.
|
/// should only push exactly 3 `GenericArg`s before building.
|
||||||
pub fn subst_for_coroutine(db: &dyn HirDatabase, parent: DefWithBodyId) -> TyBuilder<()> {
|
pub fn subst_for_coroutine(db: &dyn HirDatabase, parent: DefWithBodyId) -> TyBuilder<()> {
|
||||||
let parent_subst =
|
let parent_subst = parent
|
||||||
parent.as_generic_def_id().map(|p| generics(db.upcast(), p).placeholder_subst(db));
|
.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.
|
// These represent resume type, yield type, and return type of coroutine.
|
||||||
let params = std::iter::repeat(ParamKind::Type).take(3).collect();
|
let params = std::iter::repeat(ParamKind::Type).take(3).collect();
|
||||||
TyBuilder::new((), params, parent_subst)
|
TyBuilder::new((), params, parent_subst)
|
||||||
|
@ -266,7 +267,7 @@ impl TyBuilder<()> {
|
||||||
) -> Substitution {
|
) -> Substitution {
|
||||||
let sig_ty = sig_ty.cast(Interner);
|
let sig_ty = sig_ty.cast(Interner);
|
||||||
let self_subst = iter::once(&sig_ty);
|
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);
|
return Substitution::from_iter(Interner, self_subst);
|
||||||
};
|
};
|
||||||
Substitution::from_iter(
|
Substitution::from_iter(
|
||||||
|
|
|
@ -13,7 +13,8 @@ use hir_def::{
|
||||||
data::adt::StructFlags,
|
data::adt::StructFlags,
|
||||||
hir::Movability,
|
hir::Movability,
|
||||||
lang_item::{LangItem, LangItemTarget},
|
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;
|
use hir_expand::name::name;
|
||||||
|
|
||||||
|
@ -28,9 +29,9 @@ use crate::{
|
||||||
to_assoc_type_id, to_chalk_trait_id,
|
to_assoc_type_id, to_chalk_trait_id,
|
||||||
traits::ChalkContext,
|
traits::ChalkContext,
|
||||||
utils::ClosureSubst,
|
utils::ClosureSubst,
|
||||||
wrap_empty_binders, AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId,
|
wrap_empty_binders, AliasEq, AliasTy, BoundVar, DebruijnIndex, FnDefId, Interner, ProjectionTy,
|
||||||
Interner, ProjectionTy, ProjectionTyExt, QuantifiedWhereClause, Substitution, TraitRef,
|
ProjectionTyExt, QuantifiedWhereClause, Substitution, TraitRef, TraitRefExt, Ty, TyBuilder,
|
||||||
TraitRefExt, Ty, TyBuilder, TyExt, TyKind, WhereClause,
|
TyExt, TyKind, WhereClause,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>;
|
pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>;
|
||||||
|
@ -102,7 +103,7 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
|
||||||
&self,
|
&self,
|
||||||
fn_def_id: chalk_ir::FnDefId<Interner>,
|
fn_def_id: chalk_ir::FnDefId<Interner>,
|
||||||
) -> Arc<rust_ir::FnDefDatum<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(
|
fn impls_for_trait(
|
||||||
|
@ -912,16 +913,13 @@ fn type_alias_associated_ty_value(
|
||||||
Arc::new(value)
|
Arc::new(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fn_def_datum_query(
|
pub(crate) fn fn_def_datum_query(db: &dyn HirDatabase, fn_def_id: FnDefId) -> Arc<FnDefDatum> {
|
||||||
db: &dyn HirDatabase,
|
|
||||||
_krate: CrateId,
|
|
||||||
fn_def_id: FnDefId,
|
|
||||||
) -> Arc<FnDefDatum> {
|
|
||||||
let callable_def: CallableDefId = from_chalk(db, fn_def_id);
|
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 (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 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 {
|
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
|
// 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(
|
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 {
|
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 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(
|
Variances::from_iter(
|
||||||
Interner,
|
Interner,
|
||||||
std::iter::repeat(chalk_ir::Variance::Invariant).take(generic_params.len()),
|
std::iter::repeat(chalk_ir::Variance::Invariant).take(generic_params.len()),
|
||||||
|
|
|
@ -188,9 +188,10 @@ impl TyExt for Ty {
|
||||||
fn as_generic_def(&self, db: &dyn HirDatabase) -> Option<GenericDefId> {
|
fn as_generic_def(&self, db: &dyn HirDatabase) -> Option<GenericDefId> {
|
||||||
match *self.kind(Interner) {
|
match *self.kind(Interner) {
|
||||||
TyKind::Adt(AdtId(adt), ..) => Some(adt.into()),
|
TyKind::Adt(AdtId(adt), ..) => Some(adt.into()),
|
||||||
TyKind::FnDef(callable, ..) => {
|
TyKind::FnDef(callable, ..) => Some(GenericDefId::from(
|
||||||
Some(db.lookup_intern_callable_def(callable.into()).into())
|
db.upcast(),
|
||||||
}
|
db.lookup_intern_callable_def(callable.into()),
|
||||||
|
)),
|
||||||
TyKind::AssociatedType(type_alias, ..) => Some(from_assoc_type_id(type_alias).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()),
|
TyKind::Foreign(type_alias, ..) => Some(from_foreign_def_id(type_alias).into()),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|
|
@ -9,8 +9,8 @@ use base_db::{
|
||||||
CrateId, Upcast,
|
CrateId, Upcast,
|
||||||
};
|
};
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
db::DefDatabase, hir::ExprId, layout::TargetDataLayout, AdtId, BlockId, ConstParamId,
|
db::DefDatabase, hir::ExprId, layout::TargetDataLayout, AdtId, BlockId, CallableDefId,
|
||||||
DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId, GenericDefId, ImplId,
|
ConstParamId, DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId, GenericDefId, ImplId,
|
||||||
LifetimeParamId, LocalFieldId, StaticId, TypeAliasId, TypeOrConstParamId, VariantId,
|
LifetimeParamId, LocalFieldId, StaticId, TypeAliasId, TypeOrConstParamId, VariantId,
|
||||||
};
|
};
|
||||||
use la_arena::ArenaMap;
|
use la_arena::ArenaMap;
|
||||||
|
@ -24,9 +24,8 @@ use crate::{
|
||||||
lower::{GenericDefaults, GenericPredicates},
|
lower::{GenericDefaults, GenericPredicates},
|
||||||
method_resolution::{InherentImpls, TraitImpls, TyFingerprint},
|
method_resolution::{InherentImpls, TraitImpls, TyFingerprint},
|
||||||
mir::{BorrowckResult, MirBody, MirLowerError},
|
mir::{BorrowckResult, MirBody, MirLowerError},
|
||||||
Binders, CallableDefId, ClosureId, Const, FnDefId, ImplTraitId, ImplTraits, InferenceResult,
|
Binders, ClosureId, Const, FnDefId, ImplTraitId, ImplTraits, InferenceResult, Interner,
|
||||||
Interner, PolyFnSig, QuantifiedWhereClause, Substitution, TraitEnvironment, TraitRef, Ty,
|
PolyFnSig, Substitution, TraitEnvironment, TraitRef, Ty, TyDefId, ValueTyDefId,
|
||||||
TyDefId, ValueTyDefId,
|
|
||||||
};
|
};
|
||||||
use hir_expand::name::Name;
|
use hir_expand::name::Name;
|
||||||
|
|
||||||
|
@ -145,7 +144,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
|
||||||
def: GenericDefId,
|
def: GenericDefId,
|
||||||
param_id: TypeOrConstParamId,
|
param_id: TypeOrConstParamId,
|
||||||
assoc_name: Option<Name>,
|
assoc_name: Option<Name>,
|
||||||
) -> Arc<[Binders<QuantifiedWhereClause>]>;
|
) -> GenericPredicates;
|
||||||
|
|
||||||
#[salsa::invoke(crate::lower::generic_predicates_query)]
|
#[salsa::invoke(crate::lower::generic_predicates_query)]
|
||||||
fn generic_predicates(&self, def: GenericDefId) -> GenericPredicates;
|
fn generic_predicates(&self, def: GenericDefId) -> GenericPredicates;
|
||||||
|
@ -232,7 +231,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
|
||||||
) -> sync::Arc<chalk_db::ImplDatum>;
|
) -> sync::Arc<chalk_db::ImplDatum>;
|
||||||
|
|
||||||
#[salsa::invoke(chalk_db::fn_def_datum_query)]
|
#[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)]
|
#[salsa::invoke(chalk_db::fn_def_variance_query)]
|
||||||
fn fn_def_variance(&self, fn_def_id: FnDefId) -> chalk_db::Variances;
|
fn fn_def_variance(&self, fn_def_id: FnDefId) -> chalk_db::Variances;
|
||||||
|
|
|
@ -21,8 +21,8 @@ use hir_def::{
|
||||||
path::{Path, PathKind},
|
path::{Path, PathKind},
|
||||||
type_ref::{TraitBoundModifier, TypeBound, TypeRef},
|
type_ref::{TraitBoundModifier, TypeBound, TypeRef},
|
||||||
visibility::Visibility,
|
visibility::Visibility,
|
||||||
HasModule, ImportPathConfig, ItemContainerId, LocalFieldId, Lookup, ModuleDefId, ModuleId,
|
GenericDefId, HasModule, ImportPathConfig, ItemContainerId, LocalFieldId, Lookup, ModuleDefId,
|
||||||
TraitId,
|
ModuleId, TraitId,
|
||||||
};
|
};
|
||||||
use hir_expand::name::Name;
|
use hir_expand::name::Name;
|
||||||
use intern::{Internable, Interned};
|
use intern::{Internable, Interned};
|
||||||
|
@ -988,7 +988,8 @@ impl HirDisplay for Ty {
|
||||||
f.end_location_link();
|
f.end_location_link();
|
||||||
|
|
||||||
if parameters.len(Interner) > 0 {
|
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) =
|
let (parent_len, self_param, type_, const_, impl_, lifetime) =
|
||||||
generics.provenance_split();
|
generics.provenance_split();
|
||||||
let parameters = parameters.as_slice(Interner);
|
let parameters = parameters.as_slice(Interner);
|
||||||
|
@ -1002,8 +1003,9 @@ impl HirDisplay for Ty {
|
||||||
debug_assert_eq!(parent_params.len(), parent_len);
|
debug_assert_eq!(parent_params.len(), parent_len);
|
||||||
|
|
||||||
let parent_params =
|
let parent_params =
|
||||||
generic_args_sans_defaults(f, Some(def.into()), parent_params);
|
generic_args_sans_defaults(f, Some(generic_def_id), parent_params);
|
||||||
let fn_params = generic_args_sans_defaults(f, Some(def.into()), fn_params);
|
let fn_params =
|
||||||
|
generic_args_sans_defaults(f, Some(generic_def_id), fn_params);
|
||||||
|
|
||||||
write!(f, "<")?;
|
write!(f, "<")?;
|
||||||
hir_fmt_generic_arguments(f, parent_params, None)?;
|
hir_fmt_generic_arguments(f, parent_params, None)?;
|
||||||
|
|
|
@ -216,7 +216,6 @@ fn parent_generic_def(db: &dyn DefDatabase, def: GenericDefId) -> Option<Generic
|
||||||
GenericDefId::FunctionId(it) => it.lookup(db).container,
|
GenericDefId::FunctionId(it) => it.lookup(db).container,
|
||||||
GenericDefId::TypeAliasId(it) => it.lookup(db).container,
|
GenericDefId::TypeAliasId(it) => it.lookup(db).container,
|
||||||
GenericDefId::ConstId(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::AdtId(_)
|
||||||
| GenericDefId::TraitId(_)
|
| GenericDefId::TraitId(_)
|
||||||
| GenericDefId::ImplId(_)
|
| GenericDefId::ImplId(_)
|
||||||
|
|
|
@ -13,7 +13,7 @@ use hir_def::{
|
||||||
},
|
},
|
||||||
lang_item::{LangItem, LangItemTarget},
|
lang_item::{LangItem, LangItemTarget},
|
||||||
path::{GenericArgs, Path},
|
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 hir_expand::name::{name, Name};
|
||||||
use stdx::always;
|
use stdx::always;
|
||||||
|
@ -1895,7 +1895,8 @@ impl InferenceContext<'_> {
|
||||||
let callable_ty = self.resolve_ty_shallow(callable_ty);
|
let callable_ty = self.resolve_ty_shallow(callable_ty);
|
||||||
if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind(Interner) {
|
if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind(Interner) {
|
||||||
let def: CallableDefId = from_chalk(self.db, *fn_def);
|
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() {
|
for predicate in generic_predicates.iter() {
|
||||||
let (predicate, binders) = predicate
|
let (predicate, binders) = predicate
|
||||||
.clone()
|
.clone()
|
||||||
|
|
|
@ -41,14 +41,7 @@ impl InferenceContext<'_> {
|
||||||
fn resolve_value_path(&mut self, path: &Path, id: ExprOrPatId) -> Option<ValuePathResolution> {
|
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, self_subst) = self.resolve_value_path_inner(path, id)?;
|
||||||
|
|
||||||
let value_def = match value {
|
let value_def: ValueTyDefId = 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;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ValueNs::FunctionId(it) => it.into(),
|
ValueNs::FunctionId(it) => it.into(),
|
||||||
ValueNs::ConstId(it) => it.into(),
|
ValueNs::ConstId(it) => it.into(),
|
||||||
ValueNs::StaticId(it) => it.into(),
|
ValueNs::StaticId(it) => it.into(),
|
||||||
|
@ -62,48 +55,79 @@ impl InferenceContext<'_> {
|
||||||
|
|
||||||
it.into()
|
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) => {
|
ValueNs::ImplSelf(impl_id) => {
|
||||||
let generics = crate::generics::generics(self.db.upcast(), impl_id.into());
|
let generics = crate::generics::generics(self.db.upcast(), impl_id.into());
|
||||||
let substs = generics.placeholder_subst(self.db);
|
let substs = generics.placeholder_subst(self.db);
|
||||||
let ty = self.db.impl_self_ty(impl_id).substitute(Interner, &substs);
|
let ty = self.db.impl_self_ty(impl_id).substitute(Interner, &substs);
|
||||||
if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() {
|
return if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() {
|
||||||
return Some(ValuePathResolution::GenericDef(
|
Some(ValuePathResolution::GenericDef(
|
||||||
struct_id.into(),
|
struct_id.into(),
|
||||||
struct_id.into(),
|
struct_id.into(),
|
||||||
substs.clone(),
|
substs.clone(),
|
||||||
));
|
))
|
||||||
} else {
|
} else {
|
||||||
// FIXME: report error, invalid Self reference
|
// FIXME: report error, invalid Self reference
|
||||||
return None;
|
None
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
ValueNs::GenericParam(it) => {
|
ValueNs::GenericParam(it) => {
|
||||||
return Some(ValuePathResolution::NonGeneric(self.db.const_param_ty(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 ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
|
||||||
let substs = ctx.substs_from_path(path, value_def, true);
|
let substs = ctx.substs_from_path(path, value_def, true);
|
||||||
let substs = substs.as_slice(Interner);
|
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 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_params_len = generics.parent_generics()?.len();
|
||||||
let parent_args = &substs[substs.len() - parent_params_len..];
|
let parent_args = &substs[substs.len() - parent_params_len..];
|
||||||
Some(Substitution::from_iter(Interner, parent_args))
|
Some(Substitution::from_iter(Interner, parent_args))
|
||||||
});
|
});
|
||||||
let parent_substs_len = parent_substs.as_ref().map_or(0, |s| s.len(Interner));
|
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 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 builder = TyBuilder::subst_for_def(self.db, generic_def, parent_substs);
|
||||||
let substs = builder
|
let substs = builder
|
||||||
.fill(|x| {
|
.fill(|x| {
|
||||||
|
|
|
@ -60,7 +60,7 @@ use chalk_ir::{
|
||||||
NoSolution,
|
NoSolution,
|
||||||
};
|
};
|
||||||
use either::Either;
|
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 hir_expand::name;
|
||||||
use la_arena::{Arena, Idx};
|
use la_arena::{Arena, Idx};
|
||||||
use mir::{MirEvalError, VTableMap};
|
use mir::{MirEvalError, VTableMap};
|
||||||
|
@ -84,8 +84,8 @@ pub use infer::{
|
||||||
};
|
};
|
||||||
pub use interner::Interner;
|
pub use interner::Interner;
|
||||||
pub use lower::{
|
pub use lower::{
|
||||||
associated_type_shorthand_candidates, CallableDefId, ImplTraitLoweringMode, ParamLoweringMode,
|
associated_type_shorthand_candidates, ImplTraitLoweringMode, ParamLoweringMode, TyDefId,
|
||||||
TyDefId, TyLoweringContext, ValueTyDefId,
|
TyLoweringContext, ValueTyDefId,
|
||||||
};
|
};
|
||||||
pub use mapping::{
|
pub use mapping::{
|
||||||
from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, from_placeholder_idx,
|
from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id, from_placeholder_idx,
|
||||||
|
|
|
@ -11,10 +11,7 @@ use std::{
|
||||||
ops::{self, Not as _},
|
ops::{self, Not as _},
|
||||||
};
|
};
|
||||||
|
|
||||||
use base_db::{
|
use base_db::{salsa::Cycle, CrateId};
|
||||||
salsa::{Cycle, InternValueTrivial},
|
|
||||||
CrateId,
|
|
||||||
};
|
|
||||||
use chalk_ir::{
|
use chalk_ir::{
|
||||||
cast::Cast,
|
cast::Cast,
|
||||||
fold::{Shift, TypeFoldable},
|
fold::{Shift, TypeFoldable},
|
||||||
|
@ -38,10 +35,10 @@ use hir_def::{
|
||||||
type_ref::{
|
type_ref::{
|
||||||
ConstRef, LifetimeRef, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef,
|
ConstRef, LifetimeRef, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef,
|
||||||
},
|
},
|
||||||
AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, FunctionId,
|
AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId,
|
||||||
GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstLoc, ItemContainerId, LocalFieldId,
|
FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstLoc, ItemContainerId,
|
||||||
Lookup, ModuleDefId, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId,
|
LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId,
|
||||||
UnionId, VariantId,
|
TypeOwnerId, UnionId, VariantId,
|
||||||
};
|
};
|
||||||
use hir_expand::{name::Name, ExpandResult};
|
use hir_expand::{name::Name, ExpandResult};
|
||||||
use intern::Interned;
|
use intern::Interned;
|
||||||
|
@ -1535,7 +1532,7 @@ pub(crate) fn generic_predicates_for_param_query(
|
||||||
def: GenericDefId,
|
def: GenericDefId,
|
||||||
param_id: TypeOrConstParamId,
|
param_id: TypeOrConstParamId,
|
||||||
assoc_name: Option<Name>,
|
assoc_name: Option<Name>,
|
||||||
) -> Arc<[Binders<QuantifiedWhereClause>]> {
|
) -> GenericPredicates {
|
||||||
let resolver = def.resolver(db.upcast());
|
let resolver = def.resolver(db.upcast());
|
||||||
let ctx = if let GenericDefId::FunctionId(_) = def {
|
let ctx = if let GenericDefId::FunctionId(_) = def {
|
||||||
TyLoweringContext::new(db, &resolver, def.into())
|
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(
|
pub(crate) fn generic_predicates_for_param_recover(
|
||||||
|
@ -1620,15 +1617,15 @@ pub(crate) fn generic_predicates_for_param_recover(
|
||||||
_def: &GenericDefId,
|
_def: &GenericDefId,
|
||||||
_param_id: &TypeOrConstParamId,
|
_param_id: &TypeOrConstParamId,
|
||||||
_assoc_name: &Option<Name>,
|
_assoc_name: &Option<Name>,
|
||||||
) -> Arc<[Binders<QuantifiedWhereClause>]> {
|
) -> GenericPredicates {
|
||||||
Arc::from_iter(None)
|
GenericPredicates(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn trait_environment_for_body_query(
|
pub(crate) fn trait_environment_for_body_query(
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
def: DefWithBodyId,
|
def: DefWithBodyId,
|
||||||
) -> Arc<TraitEnvironment> {
|
) -> 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();
|
let krate = def.module(db.upcast()).krate();
|
||||||
return TraitEnvironment::empty(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)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub enum TyDefId {
|
pub enum TyDefId {
|
||||||
BuiltinType(BuiltinType),
|
BuiltinType(BuiltinType),
|
||||||
|
@ -2056,12 +2012,12 @@ pub enum ValueTyDefId {
|
||||||
impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for ValueTyDefId);
|
impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for ValueTyDefId);
|
||||||
|
|
||||||
impl 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 {
|
match self {
|
||||||
Self::FunctionId(id) => Some(id.into()),
|
Self::FunctionId(id) => Some(id.into()),
|
||||||
Self::StructId(id) => Some(id.into()),
|
Self::StructId(id) => Some(id.into()),
|
||||||
Self::UnionId(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::ConstId(id) => Some(id.into()),
|
||||||
Self::StaticId(_) => None,
|
Self::StaticId(_) => None,
|
||||||
}
|
}
|
||||||
|
|
|
@ -483,7 +483,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
||||||
Ok(Some(current))
|
Ok(Some(current))
|
||||||
}
|
}
|
||||||
ValueNs::GenericParam(p) => {
|
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");
|
not_supported!("owner without generic def id");
|
||||||
};
|
};
|
||||||
let gen = generics(self.db.upcast(), def);
|
let gen = generics(self.db.upcast(), def);
|
||||||
|
@ -1330,7 +1330,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn placeholder_subst(&mut self) -> Substitution {
|
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),
|
Some(it) => TyBuilder::placeholder_subst(self.db, it),
|
||||||
None => Substitution::empty(Interner),
|
None => Substitution::empty(Interner),
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,7 +302,7 @@ pub fn monomorphized_mir_body_query(
|
||||||
subst: Substitution,
|
subst: Substitution,
|
||||||
trait_env: Arc<crate::TraitEnvironment>,
|
trait_env: Arc<crate::TraitEnvironment>,
|
||||||
) -> Result<Arc<MirBody>, MirLowerError> {
|
) -> 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 filler = &mut Filler { db, subst: &subst, trait_env, generics, owner };
|
||||||
let body = db.mir_body(owner)?;
|
let body = db.mir_body(owner)?;
|
||||||
let mut body = (*body).clone();
|
let mut body = (*body).clone();
|
||||||
|
@ -327,7 +327,7 @@ pub fn monomorphized_mir_body_for_closure_query(
|
||||||
trait_env: Arc<crate::TraitEnvironment>,
|
trait_env: Arc<crate::TraitEnvironment>,
|
||||||
) -> Result<Arc<MirBody>, MirLowerError> {
|
) -> Result<Arc<MirBody>, MirLowerError> {
|
||||||
let InternedClosure(owner, _) = db.lookup_intern_closure(closure.into());
|
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 filler = &mut Filler { db, subst: &subst, trait_env, generics, owner };
|
||||||
let body = db.mir_body_for_closure(closure)?;
|
let body = db.mir_body_for_closure(closure)?;
|
||||||
let mut body = (*body).clone();
|
let mut body = (*body).clone();
|
||||||
|
@ -343,7 +343,7 @@ pub fn monomorphize_mir_body_bad(
|
||||||
trait_env: Arc<crate::TraitEnvironment>,
|
trait_env: Arc<crate::TraitEnvironment>,
|
||||||
) -> Result<MirBody, MirLowerError> {
|
) -> Result<MirBody, MirLowerError> {
|
||||||
let owner = body.owner;
|
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 };
|
let filler = &mut Filler { db, subst: &subst, trait_env, generics, owner };
|
||||||
filler.fill_body(&mut body)?;
|
filler.fill_body(&mut body)?;
|
||||||
Ok(body)
|
Ok(body)
|
||||||
|
|
|
@ -182,7 +182,6 @@ impl From<GenericDef> for GenericDefId {
|
||||||
GenericDef::TraitAlias(it) => GenericDefId::TraitAliasId(it.id),
|
GenericDef::TraitAlias(it) => GenericDefId::TraitAliasId(it.id),
|
||||||
GenericDef::TypeAlias(it) => GenericDefId::TypeAliasId(it.id),
|
GenericDef::TypeAlias(it) => GenericDefId::TypeAliasId(it.id),
|
||||||
GenericDef::Impl(it) => GenericDefId::ImplId(it.id),
|
GenericDef::Impl(it) => GenericDefId::ImplId(it.id),
|
||||||
GenericDef::Variant(it) => GenericDefId::EnumVariantId(it.into()),
|
|
||||||
GenericDef::Const(it) => GenericDefId::ConstId(it.id),
|
GenericDef::Const(it) => GenericDefId::ConstId(it.id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,7 +196,6 @@ impl From<GenericDefId> for GenericDef {
|
||||||
GenericDefId::TraitAliasId(it) => GenericDef::TraitAlias(it.into()),
|
GenericDefId::TraitAliasId(it) => GenericDef::TraitAlias(it.into()),
|
||||||
GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()),
|
GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()),
|
||||||
GenericDefId::ImplId(it) => GenericDef::Impl(it.into()),
|
GenericDefId::ImplId(it) => GenericDef::Impl(it.into()),
|
||||||
GenericDefId::EnumVariantId(it) => GenericDef::Variant(it.into()),
|
|
||||||
GenericDefId::ConstId(it) => GenericDef::Const(it.into()),
|
GenericDefId::ConstId(it) => GenericDef::Const(it.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,10 @@ use either::Either;
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
nameres::{ModuleOrigin, ModuleSource},
|
nameres::{ModuleOrigin, ModuleSource},
|
||||||
src::{HasChildSource, HasSource as _},
|
src::{HasChildSource, HasSource as _},
|
||||||
Lookup, MacroId, VariantId,
|
CallableDefId, Lookup, MacroId, VariantId,
|
||||||
};
|
};
|
||||||
use hir_expand::{HirFileId, InFile};
|
use hir_expand::{HirFileId, InFile};
|
||||||
use hir_ty::{db::InternedClosure, CallableDefId};
|
use hir_ty::db::InternedClosure;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use tt::TextRange;
|
use tt::TextRange;
|
||||||
|
|
||||||
|
|
|
@ -52,11 +52,11 @@ use hir_def::{
|
||||||
path::ImportAlias,
|
path::ImportAlias,
|
||||||
per_ns::PerNs,
|
per_ns::PerNs,
|
||||||
resolver::{HasResolver, Resolver},
|
resolver::{HasResolver, Resolver},
|
||||||
AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId,
|
AssocItemId, AssocItemLoc, AttrDefId, CallableDefId, ConstId, ConstParamId, CrateRootModuleId,
|
||||||
EnumId, EnumVariantId, ExternCrateId, FunctionId, GenericDefId, GenericParamId, HasModule,
|
DefWithBodyId, EnumId, EnumVariantId, ExternCrateId, FunctionId, GenericDefId, GenericParamId,
|
||||||
ImplId, InTypeConstId, ItemContainerId, LifetimeParamId, LocalFieldId, Lookup, MacroExpander,
|
HasModule, ImplId, InTypeConstId, ItemContainerId, LifetimeParamId, LocalFieldId, Lookup,
|
||||||
ModuleId, StaticId, StructId, TraitAliasId, TraitId, TupleId, TypeAliasId, TypeOrConstParamId,
|
MacroExpander, ModuleId, StaticId, StructId, TraitAliasId, TraitId, TupleId, TypeAliasId,
|
||||||
TypeParamId, UnionId,
|
TypeOrConstParamId, TypeParamId, UnionId,
|
||||||
};
|
};
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
attrs::collect_attrs, name::name, proc_macro::ProcMacroKind, AstId, MacroCallKind, ValueResult,
|
attrs::collect_attrs, name::name, proc_macro::ProcMacroKind, AstId, MacroCallKind, ValueResult,
|
||||||
|
@ -71,7 +71,7 @@ use hir_ty::{
|
||||||
mir::{interpret_mir, MutBorrowKind},
|
mir::{interpret_mir, MutBorrowKind},
|
||||||
primitive::UintTy,
|
primitive::UintTy,
|
||||||
traits::FnTrait,
|
traits::FnTrait,
|
||||||
AliasTy, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, ClosureId, GenericArg,
|
AliasTy, CallableSig, Canonical, CanonicalVarKinds, Cast, ClosureId, GenericArg,
|
||||||
GenericArgData, Interner, ParamKind, QuantifiedWhereClause, Scalar, Substitution,
|
GenericArgData, Interner, ParamKind, QuantifiedWhereClause, Scalar, Substitution,
|
||||||
TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind, ValueTyDefId,
|
TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind, ValueTyDefId,
|
||||||
WhereClause,
|
WhereClause,
|
||||||
|
@ -1144,7 +1144,7 @@ impl Field {
|
||||||
let generic_def_id: GenericDefId = match self.parent {
|
let generic_def_id: GenericDefId = match self.parent {
|
||||||
VariantDef::Struct(it) => it.id.into(),
|
VariantDef::Struct(it) => it.id.into(),
|
||||||
VariantDef::Union(it) => it.id.into(),
|
VariantDef::Union(it) => it.id.into(),
|
||||||
VariantDef::Variant(it) => it.id.into(),
|
VariantDef::Variant(it) => it.id.lookup(db.upcast()).parent.into(),
|
||||||
};
|
};
|
||||||
let substs = TyBuilder::placeholder_subst(db, generic_def_id);
|
let substs = TyBuilder::placeholder_subst(db, generic_def_id);
|
||||||
let ty = db.field_types(var_id)[self.id].clone().substitute(Interner, &substs);
|
let ty = db.field_types(var_id)[self.id].clone().substitute(Interner, &substs);
|
||||||
|
@ -1177,7 +1177,9 @@ impl Field {
|
||||||
db.layout_of_ty(
|
db.layout_of_ty(
|
||||||
self.ty(db).ty,
|
self.ty(db).ty,
|
||||||
db.trait_environment(match hir_def::VariantId::from(self.parent) {
|
db.trait_environment(match hir_def::VariantId::from(self.parent) {
|
||||||
hir_def::VariantId::EnumVariantId(id) => GenericDefId::EnumVariantId(id),
|
hir_def::VariantId::EnumVariantId(id) => {
|
||||||
|
GenericDefId::AdtId(id.lookup(db.upcast()).parent.into())
|
||||||
|
}
|
||||||
hir_def::VariantId::StructId(id) => GenericDefId::AdtId(id.into()),
|
hir_def::VariantId::StructId(id) => GenericDefId::AdtId(id.into()),
|
||||||
hir_def::VariantId::UnionId(id) => GenericDefId::AdtId(id.into()),
|
hir_def::VariantId::UnionId(id) => GenericDefId::AdtId(id.into()),
|
||||||
}),
|
}),
|
||||||
|
@ -2501,7 +2503,7 @@ impl Trait {
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
count_required_only: bool,
|
count_required_only: bool,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
db.generic_params(GenericDefId::from(self.id))
|
db.generic_params(self.id.into())
|
||||||
.type_or_consts
|
.type_or_consts
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(_, ty)| !matches!(ty, TypeOrConstParamData::TypeParamData(ty) if ty.provenance != TypeParamProvenance::TypeParamList))
|
.filter(|(_, ty)| !matches!(ty, TypeOrConstParamData::TypeParamData(ty) if ty.provenance != TypeParamProvenance::TypeParamList))
|
||||||
|
@ -3107,9 +3109,6 @@ pub enum GenericDef {
|
||||||
TraitAlias(TraitAlias),
|
TraitAlias(TraitAlias),
|
||||||
TypeAlias(TypeAlias),
|
TypeAlias(TypeAlias),
|
||||||
Impl(Impl),
|
Impl(Impl),
|
||||||
// enum variants cannot have generics themselves, but their parent enums
|
|
||||||
// can, and this makes some code easier to write
|
|
||||||
Variant(Variant),
|
|
||||||
// consts can have type parameters from their parents (i.e. associated consts of traits)
|
// consts can have type parameters from their parents (i.e. associated consts of traits)
|
||||||
Const(Const),
|
Const(Const),
|
||||||
}
|
}
|
||||||
|
@ -3120,7 +3119,6 @@ impl_from!(
|
||||||
TraitAlias,
|
TraitAlias,
|
||||||
TypeAlias,
|
TypeAlias,
|
||||||
Impl,
|
Impl,
|
||||||
Variant,
|
|
||||||
Const
|
Const
|
||||||
for GenericDef
|
for GenericDef
|
||||||
);
|
);
|
||||||
|
@ -4052,7 +4050,9 @@ impl Type {
|
||||||
ValueTyDefId::FunctionId(it) => GenericDefId::FunctionId(it),
|
ValueTyDefId::FunctionId(it) => GenericDefId::FunctionId(it),
|
||||||
ValueTyDefId::StructId(it) => GenericDefId::AdtId(AdtId::StructId(it)),
|
ValueTyDefId::StructId(it) => GenericDefId::AdtId(AdtId::StructId(it)),
|
||||||
ValueTyDefId::UnionId(it) => GenericDefId::AdtId(AdtId::UnionId(it)),
|
ValueTyDefId::UnionId(it) => GenericDefId::AdtId(AdtId::UnionId(it)),
|
||||||
ValueTyDefId::EnumVariantId(it) => GenericDefId::EnumVariantId(it),
|
ValueTyDefId::EnumVariantId(it) => {
|
||||||
|
GenericDefId::AdtId(AdtId::EnumId(it.lookup(db.upcast()).parent))
|
||||||
|
}
|
||||||
ValueTyDefId::StaticId(_) => return Type::new(db, def, ty.skip_binders().clone()),
|
ValueTyDefId::StaticId(_) => return Type::new(db, def, ty.skip_binders().clone()),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -209,7 +209,7 @@ impl Expr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expr::Variant { variant, generics, params } => {
|
Expr::Variant { variant, generics, params } => {
|
||||||
let generics = non_default_generics(db, (*variant).into(), generics);
|
let generics = non_default_generics(db, variant.parent_enum(db).into(), generics);
|
||||||
let generics_str = match generics.is_empty() {
|
let generics_str = match generics.is_empty() {
|
||||||
true => String::new(),
|
true => String::new(),
|
||||||
false => {
|
false => {
|
||||||
|
|
|
@ -79,8 +79,9 @@ pub fn generic_def_for_node(
|
||||||
sema: &Semantics<'_, RootDatabase>,
|
sema: &Semantics<'_, RootDatabase>,
|
||||||
generic_arg_list: &ast::GenericArgList,
|
generic_arg_list: &ast::GenericArgList,
|
||||||
token: &SyntaxToken,
|
token: &SyntaxToken,
|
||||||
) -> Option<(hir::GenericDef, usize, bool)> {
|
) -> Option<(hir::GenericDef, usize, bool, Option<hir::Variant>)> {
|
||||||
let parent = generic_arg_list.syntax().parent()?;
|
let parent = generic_arg_list.syntax().parent()?;
|
||||||
|
let mut variant = None;
|
||||||
let def = match_ast! {
|
let def = match_ast! {
|
||||||
match parent {
|
match parent {
|
||||||
ast::PathSegment(ps) => {
|
ast::PathSegment(ps) => {
|
||||||
|
@ -91,7 +92,10 @@ pub fn generic_def_for_node(
|
||||||
hir::PathResolution::Def(hir::ModuleDef::Trait(it)) => it.into(),
|
hir::PathResolution::Def(hir::ModuleDef::Trait(it)) => it.into(),
|
||||||
hir::PathResolution::Def(hir::ModuleDef::TraitAlias(it)) => it.into(),
|
hir::PathResolution::Def(hir::ModuleDef::TraitAlias(it)) => it.into(),
|
||||||
hir::PathResolution::Def(hir::ModuleDef::TypeAlias(it)) => it.into(),
|
hir::PathResolution::Def(hir::ModuleDef::TypeAlias(it)) => it.into(),
|
||||||
hir::PathResolution::Def(hir::ModuleDef::Variant(it)) => it.into(),
|
hir::PathResolution::Def(hir::ModuleDef::Variant(it)) => {
|
||||||
|
variant = Some(it);
|
||||||
|
it.parent_enum(sema.db).into()
|
||||||
|
},
|
||||||
hir::PathResolution::Def(hir::ModuleDef::BuiltinType(_))
|
hir::PathResolution::Def(hir::ModuleDef::BuiltinType(_))
|
||||||
| hir::PathResolution::Def(hir::ModuleDef::Const(_))
|
| hir::PathResolution::Def(hir::ModuleDef::Const(_))
|
||||||
| hir::PathResolution::Def(hir::ModuleDef::Macro(_))
|
| hir::PathResolution::Def(hir::ModuleDef::Macro(_))
|
||||||
|
@ -134,5 +138,5 @@ pub fn generic_def_for_node(
|
||||||
.next()
|
.next()
|
||||||
.map_or(false, |arg| !matches!(arg, ast::GenericArg::LifetimeArg(_)));
|
.map_or(false, |arg| !matches!(arg, ast::GenericArg::LifetimeArg(_)));
|
||||||
|
|
||||||
Some((def, active_param, first_arg_is_non_lifetime))
|
Some((def, active_param, first_arg_is_non_lifetime, variant))
|
||||||
}
|
}
|
||||||
|
|
|
@ -320,7 +320,6 @@ impl Definition {
|
||||||
hir::GenericDef::TraitAlias(it) => it.source(db).map(|src| src.syntax().cloned()),
|
hir::GenericDef::TraitAlias(it) => it.source(db).map(|src| src.syntax().cloned()),
|
||||||
hir::GenericDef::TypeAlias(it) => it.source(db).map(|src| src.syntax().cloned()),
|
hir::GenericDef::TypeAlias(it) => it.source(db).map(|src| src.syntax().cloned()),
|
||||||
hir::GenericDef::Impl(it) => it.source(db).map(|src| src.syntax().cloned()),
|
hir::GenericDef::Impl(it) => it.source(db).map(|src| src.syntax().cloned()),
|
||||||
hir::GenericDef::Variant(it) => it.source(db).map(|src| src.syntax().cloned()),
|
|
||||||
hir::GenericDef::Const(it) => it.source(db).map(|src| src.syntax().cloned()),
|
hir::GenericDef::Const(it) => it.source(db).map(|src| src.syntax().cloned()),
|
||||||
};
|
};
|
||||||
return match def {
|
return match def {
|
||||||
|
|
|
@ -272,7 +272,7 @@ fn signature_help_for_generics(
|
||||||
arg_list: ast::GenericArgList,
|
arg_list: ast::GenericArgList,
|
||||||
token: SyntaxToken,
|
token: SyntaxToken,
|
||||||
) -> Option<SignatureHelp> {
|
) -> Option<SignatureHelp> {
|
||||||
let (mut generics_def, mut active_parameter, first_arg_is_non_lifetime) =
|
let (generics_def, mut active_parameter, first_arg_is_non_lifetime, variant) =
|
||||||
generic_def_for_node(sema, &arg_list, &token)?;
|
generic_def_for_node(sema, &arg_list, &token)?;
|
||||||
let mut res = SignatureHelp {
|
let mut res = SignatureHelp {
|
||||||
doc: None,
|
doc: None,
|
||||||
|
@ -290,6 +290,12 @@ fn signature_help_for_generics(
|
||||||
hir::GenericDef::Adt(hir::Adt::Enum(it)) => {
|
hir::GenericDef::Adt(hir::Adt::Enum(it)) => {
|
||||||
res.doc = it.docs(db);
|
res.doc = it.docs(db);
|
||||||
format_to!(res.signature, "enum {}", it.name(db).display(db));
|
format_to!(res.signature, "enum {}", it.name(db).display(db));
|
||||||
|
if let Some(variant) = variant {
|
||||||
|
// In paths, generics of an enum can be specified *after* one of its variants.
|
||||||
|
// eg. `None::<u8>`
|
||||||
|
// We'll use the signature of the enum, but include the docs of the variant.
|
||||||
|
res.doc = variant.docs(db);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
hir::GenericDef::Adt(hir::Adt::Struct(it)) => {
|
hir::GenericDef::Adt(hir::Adt::Struct(it)) => {
|
||||||
res.doc = it.docs(db);
|
res.doc = it.docs(db);
|
||||||
|
@ -311,15 +317,6 @@ fn signature_help_for_generics(
|
||||||
res.doc = it.docs(db);
|
res.doc = it.docs(db);
|
||||||
format_to!(res.signature, "type {}", it.name(db).display(db));
|
format_to!(res.signature, "type {}", it.name(db).display(db));
|
||||||
}
|
}
|
||||||
hir::GenericDef::Variant(it) => {
|
|
||||||
// In paths, generics of an enum can be specified *after* one of its variants.
|
|
||||||
// eg. `None::<u8>`
|
|
||||||
// We'll use the signature of the enum, but include the docs of the variant.
|
|
||||||
res.doc = it.docs(db);
|
|
||||||
let enum_ = it.parent_enum(db);
|
|
||||||
format_to!(res.signature, "enum {}", enum_.name(db).display(db));
|
|
||||||
generics_def = enum_.into();
|
|
||||||
}
|
|
||||||
// These don't have generic args that can be specified
|
// These don't have generic args that can be specified
|
||||||
hir::GenericDef::Impl(_) | hir::GenericDef::Const(_) => return None,
|
hir::GenericDef::Impl(_) | hir::GenericDef::Const(_) => return None,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue