Skip to content

Commit

Permalink
fix: method resolution bug
Browse files Browse the repository at this point in the history
fix: performance regression
  • Loading branch information
mtshiba committed Oct 20, 2024
1 parent cacfad1 commit 75535a7
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 8 deletions.
20 changes: 12 additions & 8 deletions crates/erg_compiler/context/inquire.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2109,11 +2109,9 @@ impl Context {
// method: obj: 1, subr: (self: Int, other: Int) -> Int
// non-method: obj: Int, subr: (self: Int, other: Int) -> Int
// FIXME: staticmethod
let is_method = subr.self_t().map_or(false, |self_t| {
self.subtype_of(obj.ref_t(), self_t) || !self.subtype_of(obj.ref_t(), &Type)
});
let is_method_call = subr.self_t().is_some() && !obj.ref_t().is_singleton_refinement_type();
let callee = if let Some(ident) = attr_name {
if is_method {
if is_method_call {
obj.clone()
} else {
let attr = hir::Attribute::new(obj.clone(), hir::Identifier::bare(ident.clone()));
Expand All @@ -2122,7 +2120,7 @@ impl Context {
} else {
obj.clone()
};
let params_len = if is_method {
let params_len = if is_method_call {
subr.non_default_params.len().saturating_sub(1) + subr.default_params.len()
} else {
subr.non_default_params.len() + subr.default_params.len()
Expand All @@ -2133,10 +2131,16 @@ impl Context {
|| (params_len == pos_args.len() + kw_args.len() && there_var))
&& subr.is_no_var()
{
return Err(self.gen_too_many_args_error(&callee, subr, is_method, pos_args, kw_args));
return Err(self.gen_too_many_args_error(
&callee,
subr,
is_method_call,
pos_args,
kw_args,
));
}
let mut passed_params = set! {};
let non_default_params = if is_method {
let non_default_params = if is_method_call {
let mut non_default_params = subr.non_default_params.iter();
let self_pt = non_default_params.next().unwrap();
if let Err(mut es) = self.sub_unify(obj.ref_t(), self_pt.typ(), obj, self_pt.name()) {
Expand Down Expand Up @@ -2259,7 +2263,7 @@ impl Context {
.enumerate()
.filter(|(_, pt)| pt.name().map_or(true, |name| !passed_params.contains(name)))
.map(|(i, pt)| {
let n = if is_method { i } else { i + 1 };
let n = if is_method_call { i } else { i + 1 };
let nth = format!("({} param)", ordinal_num(n));
pt.name()
.map_or(nth.clone(), |name| format!("{name} {nth}"))
Expand Down
11 changes: 11 additions & 0 deletions crates/erg_compiler/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2634,6 +2634,17 @@ impl Type {
}
}

pub fn is_singleton_refinement_type(&self) -> bool {
match self {
Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_singleton_refinement_type(),
Self::Refinement(refine) => {
matches!(refine.pred.as_ref(), Predicate::Equal { rhs, .. } if rhs.as_type().is_some())
}
Self::And(tys, _) => tys.iter().any(|t| t.is_singleton_refinement_type()),
_ => false,
}
}

pub fn is_record(&self) -> bool {
match self {
Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_record(),
Expand Down
4 changes: 4 additions & 0 deletions crates/erg_compiler/ty/typaram.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1536,6 +1536,10 @@ impl TyParam {
}
}

pub fn as_type(&self) -> Option<&Type> {
<&Type>::try_from(self).ok()
}

pub fn substitute(self, var: &str, to: &TyParam) -> TyParam {
if self.qual_name().is_some_and(|n| n == var) {
return to.clone();
Expand Down

0 comments on commit 75535a7

Please sign in to comment.