mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 18:58:30 +00:00
chore: add TraitImpl::declared_in
This commit is contained in:
parent
40a01db38f
commit
4440d0a698
8 changed files with 92 additions and 14 deletions
|
@ -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)
|
||||
)],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(<i.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
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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_) {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue