mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 21:43:37 +00:00
Use TraitId in TraitRef
This commit is contained in:
parent
6560e4ff2e
commit
72d8e7e69a
6 changed files with 68 additions and 68 deletions
|
@ -741,7 +741,7 @@ impl Trait {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef {
|
pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef {
|
||||||
TraitRef::for_trait(db, self)
|
TraitRef::for_trait(db, self.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_auto(self, db: &impl DefDatabase) -> bool {
|
pub fn is_auto(self, db: &impl DefDatabase) -> bool {
|
||||||
|
|
|
@ -26,7 +26,7 @@ use ra_db::{impl_intern_key, salsa};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, FloatTy, IntTy, Mutability,
|
db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, FloatTy, IntTy, Mutability,
|
||||||
Name, Trait, Uncertain,
|
Name, Uncertain,
|
||||||
};
|
};
|
||||||
use display::{HirDisplay, HirFormatter};
|
use display::{HirDisplay, HirFormatter};
|
||||||
|
|
||||||
|
@ -445,7 +445,7 @@ impl Deref for Substs {
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
pub struct TraitRef {
|
pub struct TraitRef {
|
||||||
/// FIXME name?
|
/// FIXME name?
|
||||||
pub trait_: Trait,
|
pub trait_: TraitId,
|
||||||
pub substs: Substs,
|
pub substs: Substs,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,7 +676,7 @@ impl Ty {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If this is an `impl Trait` or `dyn Trait`, returns that trait.
|
/// If this is an `impl Trait` or `dyn Trait`, returns that trait.
|
||||||
pub fn inherent_trait(&self) -> Option<Trait> {
|
pub fn inherent_trait(&self) -> Option<TraitId> {
|
||||||
match self {
|
match self {
|
||||||
Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
|
Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
|
||||||
predicates.iter().find_map(|pred| match pred {
|
predicates.iter().find_map(|pred| match pred {
|
||||||
|
@ -988,7 +988,10 @@ impl HirDisplay for Ty {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}",
|
"{}",
|
||||||
trait_ref.trait_.name(f.db).unwrap_or_else(Name::missing)
|
f.db.trait_data(trait_ref.trait_)
|
||||||
|
.name
|
||||||
|
.clone()
|
||||||
|
.unwrap_or_else(Name::missing)
|
||||||
)?;
|
)?;
|
||||||
if trait_ref.substs.len() > 1 {
|
if trait_ref.substs.len() > 1 {
|
||||||
write!(f, "<")?;
|
write!(f, "<")?;
|
||||||
|
@ -1049,7 +1052,7 @@ impl TraitRef {
|
||||||
} else {
|
} else {
|
||||||
write!(f, ": ")?;
|
write!(f, ": ")?;
|
||||||
}
|
}
|
||||||
write!(f, "{}", self.trait_.name(f.db).unwrap_or_else(Name::missing))?;
|
write!(f, "{}", f.db.trait_data(self.trait_).name.clone().unwrap_or_else(Name::missing))?;
|
||||||
if self.substs.len() > 1 {
|
if self.substs.len() > 1 {
|
||||||
write!(f, "<")?;
|
write!(f, "<")?;
|
||||||
f.write_joined(&self.substs[1..], ", ")?;
|
f.write_joined(&self.substs[1..], ", ")?;
|
||||||
|
|
|
@ -143,7 +143,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
id: ExprOrPatId,
|
id: ExprOrPatId,
|
||||||
) -> Option<(ValueNs, Option<Substs>)> {
|
) -> Option<(ValueNs, Option<Substs>)> {
|
||||||
let trait_ = trait_ref.trait_;
|
let trait_ = trait_ref.trait_;
|
||||||
let item = trait_.items(self.db).iter().copied().find_map(|item| match item {
|
let item =
|
||||||
|
self.db.trait_data(trait_).items.iter().map(|(_name, id)| (*id).into()).find_map(
|
||||||
|
|item| match item {
|
||||||
AssocItem::Function(func) => {
|
AssocItem::Function(func) => {
|
||||||
if segment.name == func.name(self.db) {
|
if segment.name == func.name(self.db) {
|
||||||
Some(AssocItem::Function(func))
|
Some(AssocItem::Function(func))
|
||||||
|
@ -160,7 +162,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AssocItem::TypeAlias(_) => None,
|
AssocItem::TypeAlias(_) => None,
|
||||||
})?;
|
},
|
||||||
|
)?;
|
||||||
let def = match item {
|
let def = match item {
|
||||||
AssocItem::Function(f) => ValueNs::FunctionId(f.id),
|
AssocItem::Function(f) => ValueNs::FunctionId(f.id),
|
||||||
AssocItem::Const(c) => ValueNs::ConstId(c.id),
|
AssocItem::Const(c) => ValueNs::ConstId(c.id),
|
||||||
|
@ -212,7 +215,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
.fill_with_params()
|
.fill_with_params()
|
||||||
.build();
|
.build();
|
||||||
self.obligations.push(super::Obligation::Trait(TraitRef {
|
self.obligations.push(super::Obligation::Trait(TraitRef {
|
||||||
trait_: t,
|
trait_: t.id,
|
||||||
substs: trait_substs,
|
substs: trait_substs,
|
||||||
}));
|
}));
|
||||||
Some(substs)
|
Some(substs)
|
||||||
|
|
|
@ -15,7 +15,7 @@ use hir_def::{
|
||||||
resolver::{HasResolver, Resolver, TypeNs},
|
resolver::{HasResolver, Resolver, TypeNs},
|
||||||
type_ref::{TypeBound, TypeRef},
|
type_ref::{TypeBound, TypeRef},
|
||||||
AdtId, AstItemDef, EnumVariantId, FunctionId, GenericDefId, HasModule, LocalStructFieldId,
|
AdtId, AstItemDef, EnumVariantId, FunctionId, GenericDefId, HasModule, LocalStructFieldId,
|
||||||
Lookup, StructId, VariantId,
|
Lookup, StructId, TraitId, VariantId,
|
||||||
};
|
};
|
||||||
use ra_arena::map::ArenaMap;
|
use ra_arena::map::ArenaMap;
|
||||||
use ra_db::CrateId;
|
use ra_db::CrateId;
|
||||||
|
@ -172,7 +172,7 @@ impl Ty {
|
||||||
let segment = &remaining_segments[0];
|
let segment = &remaining_segments[0];
|
||||||
let associated_ty = associated_type_by_name_including_super_traits(
|
let associated_ty = associated_type_by_name_including_super_traits(
|
||||||
db,
|
db,
|
||||||
trait_ref.trait_.id,
|
trait_ref.trait_,
|
||||||
&segment.name,
|
&segment.name,
|
||||||
);
|
);
|
||||||
match associated_ty {
|
match associated_ty {
|
||||||
|
@ -263,7 +263,7 @@ impl Ty {
|
||||||
GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_),
|
GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_),
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
let traits = traits_from_env.flat_map(|t| all_super_traits(db, t.id)).map(Trait::from);
|
let traits = traits_from_env.flat_map(|t| all_super_traits(db, t)).map(Trait::from);
|
||||||
for t in traits {
|
for t in traits {
|
||||||
if let Some(associated_ty) = db.trait_data(t.id).associated_type_by_name(&segment.name)
|
if let Some(associated_ty) = db.trait_data(t.id).associated_type_by_name(&segment.name)
|
||||||
{
|
{
|
||||||
|
@ -423,7 +423,7 @@ impl TraitRef {
|
||||||
if let Some(self_ty) = explicit_self_ty {
|
if let Some(self_ty) = explicit_self_ty {
|
||||||
make_mut_slice(&mut substs.0)[0] = self_ty;
|
make_mut_slice(&mut substs.0)[0] = self_ty;
|
||||||
}
|
}
|
||||||
TraitRef { trait_: resolved, substs }
|
TraitRef { trait_: resolved.id, substs }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_hir(
|
pub(crate) fn from_hir(
|
||||||
|
@ -450,8 +450,8 @@ impl TraitRef {
|
||||||
substs_from_path_segment(db, resolver, segment, Some(resolved.id.into()), !has_self_param)
|
substs_from_path_segment(db, resolver, segment, Some(resolved.id.into()), !has_self_param)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef {
|
pub(crate) fn for_trait(db: &impl HirDatabase, trait_: TraitId) -> TraitRef {
|
||||||
let substs = Substs::identity(&db.generic_params(trait_.id.into()));
|
let substs = Substs::identity(&db.generic_params(trait_.into()));
|
||||||
TraitRef { trait_, substs }
|
TraitRef { trait_, substs }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,7 +510,7 @@ fn assoc_type_bindings_from_type_bound<'a>(
|
||||||
.flat_map(|args_and_bindings| args_and_bindings.bindings.iter())
|
.flat_map(|args_and_bindings| args_and_bindings.bindings.iter())
|
||||||
.map(move |(name, type_ref)| {
|
.map(move |(name, type_ref)| {
|
||||||
let associated_ty =
|
let associated_ty =
|
||||||
associated_type_by_name_including_super_traits(db, trait_ref.trait_.id, &name);
|
associated_type_by_name_including_super_traits(db, trait_ref.trait_, &name);
|
||||||
let associated_ty = match associated_ty {
|
let associated_ty = match associated_ty {
|
||||||
None => return GenericPredicate::Error,
|
None => return GenericPredicate::Error,
|
||||||
Some(t) => t,
|
Some(t) => t,
|
||||||
|
|
|
@ -68,7 +68,7 @@ impl CrateImplBlocks {
|
||||||
if let Some(tr) =
|
if let Some(tr) =
|
||||||
TraitRef::from_hir(db, &resolver, &trait_ref, Some(target_ty))
|
TraitRef::from_hir(db, &resolver, &trait_ref, Some(target_ty))
|
||||||
{
|
{
|
||||||
res.impls_by_trait.entry(tr.trait_.id).or_default().push(impl_id);
|
res.impls_by_trait.entry(tr.trait_).or_default().push(impl_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -249,13 +249,11 @@ fn iterate_trait_method_candidates<T>(
|
||||||
let traits_from_env = env
|
let traits_from_env = env
|
||||||
.trait_predicates_for_self_ty(&ty.value)
|
.trait_predicates_for_self_ty(&ty.value)
|
||||||
.map(|tr| tr.trait_)
|
.map(|tr| tr.trait_)
|
||||||
.flat_map(|t| all_super_traits(db, t.id))
|
.flat_map(|t| all_super_traits(db, t));
|
||||||
.map(Trait::from);
|
let traits =
|
||||||
let traits = inherent_trait
|
inherent_trait.chain(traits_from_env).chain(resolver.traits_in_scope(db).into_iter());
|
||||||
.chain(traits_from_env)
|
|
||||||
.chain(resolver.traits_in_scope(db).into_iter().map(Trait::from));
|
|
||||||
'traits: for t in traits {
|
'traits: for t in traits {
|
||||||
let data = db.trait_data(t.id);
|
let data = db.trait_data(t);
|
||||||
|
|
||||||
// we'll be lazy about checking whether the type implements the
|
// we'll be lazy about checking whether the type implements the
|
||||||
// trait, but if we find out it doesn't, we'll skip the rest of the
|
// trait, but if we find out it doesn't, we'll skip the rest of the
|
||||||
|
@ -330,7 +328,7 @@ pub(crate) fn implements_trait(
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
resolver: &Resolver,
|
resolver: &Resolver,
|
||||||
krate: Crate,
|
krate: Crate,
|
||||||
trait_: Trait,
|
trait_: TraitId,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if ty.value.inherent_trait() == Some(trait_) {
|
if ty.value.inherent_trait() == Some(trait_) {
|
||||||
// FIXME this is a bit of a hack, since Chalk should say the same thing
|
// FIXME this is a bit of a hack, since Chalk should say the same thing
|
||||||
|
@ -373,11 +371,11 @@ impl Ty {
|
||||||
fn generic_implements_goal(
|
fn generic_implements_goal(
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
env: Arc<TraitEnvironment>,
|
env: Arc<TraitEnvironment>,
|
||||||
trait_: Trait,
|
trait_: TraitId,
|
||||||
self_ty: Canonical<Ty>,
|
self_ty: Canonical<Ty>,
|
||||||
) -> Canonical<InEnvironment<super::Obligation>> {
|
) -> Canonical<InEnvironment<super::Obligation>> {
|
||||||
let num_vars = self_ty.num_vars;
|
let num_vars = self_ty.num_vars;
|
||||||
let substs = super::Substs::build_for_def(db, trait_.id)
|
let substs = super::Substs::build_for_def(db, trait_)
|
||||||
.push(self_ty.value)
|
.push(self_ty.value)
|
||||||
.fill_with_bound_vars(num_vars as u32)
|
.fill_with_bound_vars(num_vars as u32)
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -9,7 +9,9 @@ use chalk_ir::{
|
||||||
};
|
};
|
||||||
use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum};
|
use chalk_rust_ir::{AssociatedTyDatum, AssociatedTyValue, ImplDatum, StructDatum, TraitDatum};
|
||||||
|
|
||||||
use hir_def::{lang_item::LangItemTarget, ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId};
|
use hir_def::{
|
||||||
|
lang_item::LangItemTarget, AstItemDef, ContainerId, GenericDefId, Lookup, TraitId, TypeAliasId,
|
||||||
|
};
|
||||||
use hir_expand::name;
|
use hir_expand::name;
|
||||||
|
|
||||||
use ra_db::salsa::{InternId, InternKey};
|
use ra_db::salsa::{InternId, InternKey};
|
||||||
|
@ -19,7 +21,7 @@ use crate::{
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
ty::display::HirDisplay,
|
ty::display::HirDisplay,
|
||||||
ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk},
|
ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk},
|
||||||
Crate, ImplBlock, Trait, TypeAlias,
|
Crate, ImplBlock, TypeAlias,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This represents a trait whose name we could not resolve.
|
/// This represents a trait whose name we could not resolve.
|
||||||
|
@ -167,15 +169,15 @@ impl ToChalk for TraitRef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToChalk for Trait {
|
impl ToChalk for TraitId {
|
||||||
type Chalk = chalk_ir::TraitId;
|
type Chalk = chalk_ir::TraitId;
|
||||||
|
|
||||||
fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TraitId {
|
fn to_chalk(self, _db: &impl HirDatabase) -> chalk_ir::TraitId {
|
||||||
chalk_ir::TraitId(id_to_chalk(self.id))
|
chalk_ir::TraitId(id_to_chalk(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_chalk(_db: &impl HirDatabase, trait_id: chalk_ir::TraitId) -> Trait {
|
fn from_chalk(_db: &impl HirDatabase, trait_id: chalk_ir::TraitId) -> TraitId {
|
||||||
Trait { id: id_from_chalk(trait_id.0) }
|
id_from_chalk(trait_id.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,10 +445,10 @@ where
|
||||||
if trait_id == UNKNOWN_TRAIT {
|
if trait_id == UNKNOWN_TRAIT {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
let trait_: Trait = from_chalk(self.db, trait_id);
|
let trait_: TraitId = from_chalk(self.db, trait_id);
|
||||||
let mut result: Vec<_> = self
|
let mut result: Vec<_> = self
|
||||||
.db
|
.db
|
||||||
.impls_for_trait(self.krate, trait_)
|
.impls_for_trait(self.krate, trait_.into())
|
||||||
.iter()
|
.iter()
|
||||||
.copied()
|
.copied()
|
||||||
.map(Impl::ImplBlock)
|
.map(Impl::ImplBlock)
|
||||||
|
@ -459,7 +461,7 @@ where
|
||||||
[super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter()
|
[super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter()
|
||||||
{
|
{
|
||||||
if let Some(actual_trait) = get_fn_trait(self.db, self.krate, fn_trait) {
|
if let Some(actual_trait) = get_fn_trait(self.db, self.krate, fn_trait) {
|
||||||
if trait_.id == actual_trait {
|
if trait_ == actual_trait {
|
||||||
let impl_ = super::ClosureFnTraitImplData { def, expr, fn_trait };
|
let impl_ = super::ClosureFnTraitImplData { def, expr, fn_trait };
|
||||||
result.push(Impl::ClosureFnTraitImpl(impl_).to_chalk(self.db));
|
result.push(Impl::ClosureFnTraitImpl(impl_).to_chalk(self.db));
|
||||||
}
|
}
|
||||||
|
@ -516,7 +518,7 @@ pub(crate) fn associated_ty_data_query(
|
||||||
where_clauses: vec![],
|
where_clauses: vec![],
|
||||||
};
|
};
|
||||||
let datum = AssociatedTyDatum {
|
let datum = AssociatedTyDatum {
|
||||||
trait_id: Trait::from(trait_).to_chalk(db),
|
trait_id: trait_.to_chalk(db),
|
||||||
id,
|
id,
|
||||||
name: lalrpop_intern::intern(&db.type_alias_data(type_alias).name.to_string()),
|
name: lalrpop_intern::intern(&db.type_alias_data(type_alias).name.to_string()),
|
||||||
binders: make_binders(bound_data, generic_params.count_params_including_parent()),
|
binders: make_binders(bound_data, generic_params.count_params_including_parent()),
|
||||||
|
@ -548,29 +550,23 @@ pub(crate) fn trait_datum_query(
|
||||||
associated_ty_ids: vec![],
|
associated_ty_ids: vec![],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let trait_: Trait = from_chalk(db, trait_id);
|
let trait_: TraitId = from_chalk(db, trait_id);
|
||||||
debug!("trait {:?} = {:?}", trait_id, trait_.name(db));
|
let trait_data = db.trait_data(trait_);
|
||||||
let generic_params = db.generic_params(trait_.id.into());
|
debug!("trait {:?} = {:?}", trait_id, trait_data.name);
|
||||||
|
let generic_params = db.generic_params(trait_.into());
|
||||||
let bound_vars = Substs::bound_vars(&generic_params);
|
let bound_vars = Substs::bound_vars(&generic_params);
|
||||||
let flags = chalk_rust_ir::TraitFlags {
|
let flags = chalk_rust_ir::TraitFlags {
|
||||||
auto: trait_.is_auto(db),
|
auto: trait_data.auto,
|
||||||
upstream: trait_.module(db).krate() != krate,
|
upstream: trait_.module(db).krate != krate.crate_id,
|
||||||
non_enumerable: true,
|
non_enumerable: true,
|
||||||
coinductive: false, // only relevant for Chalk testing
|
coinductive: false, // only relevant for Chalk testing
|
||||||
// FIXME set these flags correctly
|
// FIXME set these flags correctly
|
||||||
marker: false,
|
marker: false,
|
||||||
fundamental: false,
|
fundamental: false,
|
||||||
};
|
};
|
||||||
let where_clauses = convert_where_clauses(db, trait_.id.into(), &bound_vars);
|
let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars);
|
||||||
let associated_ty_ids = trait_
|
let associated_ty_ids =
|
||||||
.items(db)
|
trait_data.associated_types().map(|type_alias| type_alias.to_chalk(db)).collect();
|
||||||
.into_iter()
|
|
||||||
.filter_map(|trait_item| match trait_item {
|
|
||||||
crate::AssocItem::TypeAlias(type_alias) => Some(type_alias.id),
|
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
.map(|type_alias| type_alias.to_chalk(db))
|
|
||||||
.collect();
|
|
||||||
let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses };
|
let trait_datum_bound = chalk_rust_ir::TraitDatumBound { where_clauses };
|
||||||
let trait_datum = TraitDatum {
|
let trait_datum = TraitDatum {
|
||||||
id: trait_id,
|
id: trait_id,
|
||||||
|
@ -661,7 +657,7 @@ fn impl_block_datum(
|
||||||
};
|
};
|
||||||
|
|
||||||
let impl_datum_bound = chalk_rust_ir::ImplDatumBound { trait_ref, where_clauses };
|
let impl_datum_bound = chalk_rust_ir::ImplDatumBound { trait_ref, where_clauses };
|
||||||
let trait_data = db.trait_data(trait_.id);
|
let trait_data = db.trait_data(trait_);
|
||||||
let associated_ty_value_ids = impl_block
|
let associated_ty_value_ids = impl_block
|
||||||
.items(db)
|
.items(db)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -785,7 +781,7 @@ fn type_alias_associated_ty_value(
|
||||||
.expect("assoc ty value should not exist") // we don't return any assoc ty values if the impl'd trait can't be resolved
|
.expect("assoc ty value should not exist") // we don't return any assoc ty values if the impl'd trait can't be resolved
|
||||||
.trait_;
|
.trait_;
|
||||||
let assoc_ty = db
|
let assoc_ty = db
|
||||||
.trait_data(trait_.id)
|
.trait_data(trait_)
|
||||||
.associated_type_by_name(&type_alias.name(db))
|
.associated_type_by_name(&type_alias.name(db))
|
||||||
.expect("assoc ty value should not exist"); // validated when building the impl data as well
|
.expect("assoc ty value should not exist"); // validated when building the impl data as well
|
||||||
let generic_params = db.generic_params(impl_block.id.into());
|
let generic_params = db.generic_params(impl_block.id.into());
|
||||||
|
|
Loading…
Reference in a new issue