chore: add TraitImpl::declared_in

This commit is contained in:
Shunsuke Shibayama 2024-02-11 13:08:03 +09:00
parent 40a01db38f
commit 4440d0a698
8 changed files with 92 additions and 14 deletions

View file

@ -1001,12 +1001,21 @@ impl Context {
pub(crate) fn register_methods(&mut self, t: &Type, ctx: &Self) {
for impl_trait in ctx.super_traits.iter() {
let declared_in = self.module_path().into();
if let Some(mut impls) = self.trait_impls().get_mut(&impl_trait.qual_name()) {
impls.insert(TraitImpl::new(t.clone(), impl_trait.clone()));
impls.insert(TraitImpl::new(
t.clone(),
impl_trait.clone(),
Some(declared_in),
));
} else {
self.trait_impls().register(
impl_trait.qual_name(),
set![TraitImpl::new(t.clone(), impl_trait.clone())],
set![TraitImpl::new(
t.clone(),
impl_trait.clone(),
Some(declared_in)
)],
);
}
}

View file

@ -3036,7 +3036,7 @@ impl Context {
let lti = l_impls.iter().find(|ti| &ti.sub_type == base).unwrap();
let rti = r_impls.iter().find(|ti| &ti.sub_type == base).unwrap();
let sup_trait = self.intersection(&lti.sup_trait, &rti.sup_trait);
isec.insert(TraitImpl::new(lti.sub_type.clone(), sup_trait));
isec.insert(TraitImpl::new(lti.sub_type.clone(), sup_trait, None));
}
isec
}

View file

@ -120,10 +120,26 @@ impl ControlKind {
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Clone)]
pub struct TraitImpl {
pub sub_type: Type,
pub sup_trait: Type,
pub declared_in: Option<NormalizedPathBuf>,
}
impl PartialEq for TraitImpl {
fn eq(&self, other: &Self) -> bool {
self.sub_type == other.sub_type && self.sup_trait == other.sup_trait
}
}
impl Eq for TraitImpl {}
impl std::hash::Hash for TraitImpl {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.sub_type.hash(state);
self.sup_trait.hash(state);
}
}
impl std::fmt::Display for TraitImpl {
@ -133,10 +149,15 @@ impl std::fmt::Display for TraitImpl {
}
impl TraitImpl {
pub const fn new(sub_type: Type, sup_trait: Type) -> Self {
pub const fn new(
sub_type: Type,
sup_trait: Type,
declared_in: Option<NormalizedPathBuf>,
) -> Self {
Self {
sub_type,
sup_trait,
declared_in,
}
}
}
@ -1036,7 +1057,7 @@ impl Context {
Self::poly(
name.into(),
cfg,
ContextKind::GluePatch(TraitImpl::new(base, impls)),
ContextKind::GluePatch(TraitImpl::new(base, impls, None)),
params,
None,
shared,

View file

@ -980,12 +980,17 @@ impl Context {
trait_loc: &impl Locational,
) -> TyCheckResult<()> {
// TODO: polymorphic trait
let declared_in = self.module_path().into();
if let Some(mut impls) = self.trait_impls().get_mut(&trait_.qual_name()) {
impls.insert(TraitImpl::new(class.clone(), trait_.clone()));
impls.insert(TraitImpl::new(
class.clone(),
trait_.clone(),
Some(declared_in),
));
} else {
self.trait_impls().register(
trait_.qual_name(),
set! {TraitImpl::new(class.clone(), trait_.clone())},
set! {TraitImpl::new(class.clone(), trait_.clone(), Some(declared_in))},
);
}
let trait_ctx = if let Some(trait_ctx) = self.get_nominal_type_ctx(trait_) {

View file

@ -739,14 +739,19 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
ctx.level,
);
ctx.super_traits.push(impl_trait.clone());
let declared_in = ctx.module_path().into();
if let Some(mut impls) =
ctx.trait_impls().get_mut(&impl_trait.qual_name())
{
impls.insert(TraitImpl::new(class.clone(), impl_trait.clone()));
impls.insert(TraitImpl::new(
class.clone(),
impl_trait.clone(),
Some(declared_in),
));
} else {
ctx.trait_impls().register(
impl_trait.qual_name(),
set! { TraitImpl::new(class.clone(), impl_trait.clone()) },
set! { TraitImpl::new(class.clone(), impl_trait.clone(), Some(declared_in)) },
);
}
ctx.methods_list.push(MethodContext::new(

View file

@ -58,7 +58,7 @@ impl SharedCompilerResource {
self.py_mod_cache.initialize();
self.index.initialize();
self.graph.initialize();
// self.trait_impls.initialize();
self.trait_impls.initialize();
self.promises.initialize();
self.errors.clear();
self.warns.clear();
@ -79,6 +79,7 @@ impl SharedCompilerResource {
}
self.index.remove_path(path);
// self.graph.remove(path);
self.trait_impls.remove_by_path(path);
self.promises.remove(path);
self.errors.remove(path);
self.warns.remove(path);
@ -90,6 +91,7 @@ impl SharedCompilerResource {
self.py_mod_cache.remove(path);
self.index.remove_path(path);
// self.graph.remove(path);
self.trait_impls.remove_by_path(path);
self.promises.remove(path);
self.errors.remove(path);
self.warns.remove(path);
@ -99,6 +101,7 @@ impl SharedCompilerResource {
self.mod_cache.rename_path(old, new.clone());
self.py_mod_cache.rename_path(old, new.clone());
self.index.rename_path(old, new.clone());
self.trait_impls.rename_path(old, new.clone());
self.graph.rename_path(old, new.clone());
self.promises.rename(old, new);
}

View file

@ -3,6 +3,7 @@ use std::fmt;
use std::hash::Hash;
use erg_common::dict::Dict;
use erg_common::pathutil::NormalizedPathBuf;
use erg_common::set::Set;
use erg_common::shared::{
MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLockReadGuard, RwLockWriteGuard, Shared,
@ -61,6 +62,12 @@ impl TraitImpls {
self.cache.remove(path)
}
pub fn remove_by_path(&mut self, path: &NormalizedPathBuf) {
for impls in self.cache.values_mut() {
impls.retain(|impl_| impl_.declared_in.as_ref() != Some(path));
}
}
pub fn rename<Q: Eq + Hash + ?Sized>(&mut self, old: &Q, new: Str)
where
Str: Borrow<Q>,
@ -70,8 +77,24 @@ impl TraitImpls {
}
}
pub fn rename_path(&mut self, old: &NormalizedPathBuf, new: NormalizedPathBuf) {
for impls in self.cache.values_mut() {
impls.inplace_map(|mut impl_| {
if impl_.declared_in.as_ref() == Some(old) {
impl_.declared_in = Some(new.clone());
impl_
} else {
impl_
}
});
}
}
pub fn initialize(&mut self) {
self.cache.clear();
for impls in self.cache.values_mut() {
impls.retain(|impl_| impl_.declared_in.is_none());
}
self.cache.retain(|_, impls| !impls.is_empty());
}
}
@ -125,11 +148,15 @@ impl SharedTraitImpls {
self.0.borrow_mut().register(name, impls);
}
pub fn remove<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<Set<TraitImpl>>
pub fn remove<Q: Eq + Hash + ?Sized>(&self, qual_name: &Q) -> Option<Set<TraitImpl>>
where
Str: Borrow<Q>,
{
self.0.borrow_mut().remove(path)
self.0.borrow_mut().remove(qual_name)
}
pub fn remove_by_path(&self, path: &NormalizedPathBuf) {
self.0.borrow_mut().remove_by_path(path);
}
pub fn rename<Q: Eq + Hash + ?Sized>(&self, old: &Q, new: Str)
@ -139,6 +166,10 @@ impl SharedTraitImpls {
self.0.borrow_mut().rename(old, new);
}
pub fn rename_path(&self, old: &NormalizedPathBuf, new: NormalizedPathBuf) {
self.0.borrow_mut().rename_path(old, new);
}
pub fn ref_inner(&self) -> MappedRwLockReadGuard<Dict<Str, Set<TraitImpl>>> {
RwLockReadGuard::map(self.0.borrow(), |tis| &tis.cache)
}