Skip to content

Commit 75535a7

Browse files
committed
fix: method resolution bug
fix: performance regression
1 parent cacfad1 commit 75535a7

File tree

3 files changed

+27
-8
lines changed

3 files changed

+27
-8
lines changed

crates/erg_compiler/context/inquire.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2109,11 +2109,9 @@ impl Context {
21092109
// method: obj: 1, subr: (self: Int, other: Int) -> Int
21102110
// non-method: obj: Int, subr: (self: Int, other: Int) -> Int
21112111
// FIXME: staticmethod
2112-
let is_method = subr.self_t().map_or(false, |self_t| {
2113-
self.subtype_of(obj.ref_t(), self_t) || !self.subtype_of(obj.ref_t(), &Type)
2114-
});
2112+
let is_method_call = subr.self_t().is_some() && !obj.ref_t().is_singleton_refinement_type();
21152113
let callee = if let Some(ident) = attr_name {
2116-
if is_method {
2114+
if is_method_call {
21172115
obj.clone()
21182116
} else {
21192117
let attr = hir::Attribute::new(obj.clone(), hir::Identifier::bare(ident.clone()));
@@ -2122,7 +2120,7 @@ impl Context {
21222120
} else {
21232121
obj.clone()
21242122
};
2125-
let params_len = if is_method {
2123+
let params_len = if is_method_call {
21262124
subr.non_default_params.len().saturating_sub(1) + subr.default_params.len()
21272125
} else {
21282126
subr.non_default_params.len() + subr.default_params.len()
@@ -2133,10 +2131,16 @@ impl Context {
21332131
|| (params_len == pos_args.len() + kw_args.len() && there_var))
21342132
&& subr.is_no_var()
21352133
{
2136-
return Err(self.gen_too_many_args_error(&callee, subr, is_method, pos_args, kw_args));
2134+
return Err(self.gen_too_many_args_error(
2135+
&callee,
2136+
subr,
2137+
is_method_call,
2138+
pos_args,
2139+
kw_args,
2140+
));
21372141
}
21382142
let mut passed_params = set! {};
2139-
let non_default_params = if is_method {
2143+
let non_default_params = if is_method_call {
21402144
let mut non_default_params = subr.non_default_params.iter();
21412145
let self_pt = non_default_params.next().unwrap();
21422146
if let Err(mut es) = self.sub_unify(obj.ref_t(), self_pt.typ(), obj, self_pt.name()) {
@@ -2259,7 +2263,7 @@ impl Context {
22592263
.enumerate()
22602264
.filter(|(_, pt)| pt.name().map_or(true, |name| !passed_params.contains(name)))
22612265
.map(|(i, pt)| {
2262-
let n = if is_method { i } else { i + 1 };
2266+
let n = if is_method_call { i } else { i + 1 };
22632267
let nth = format!("({} param)", ordinal_num(n));
22642268
pt.name()
22652269
.map_or(nth.clone(), |name| format!("{name} {nth}"))

crates/erg_compiler/ty/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2634,6 +2634,17 @@ impl Type {
26342634
}
26352635
}
26362636

2637+
pub fn is_singleton_refinement_type(&self) -> bool {
2638+
match self {
2639+
Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_singleton_refinement_type(),
2640+
Self::Refinement(refine) => {
2641+
matches!(refine.pred.as_ref(), Predicate::Equal { rhs, .. } if rhs.as_type().is_some())
2642+
}
2643+
Self::And(tys, _) => tys.iter().any(|t| t.is_singleton_refinement_type()),
2644+
_ => false,
2645+
}
2646+
}
2647+
26372648
pub fn is_record(&self) -> bool {
26382649
match self {
26392650
Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_record(),

crates/erg_compiler/ty/typaram.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1536,6 +1536,10 @@ impl TyParam {
15361536
}
15371537
}
15381538

1539+
pub fn as_type(&self) -> Option<&Type> {
1540+
<&Type>::try_from(self).ok()
1541+
}
1542+
15391543
pub fn substitute(self, var: &str, to: &TyParam) -> TyParam {
15401544
if self.qual_name().is_some_and(|n| n == var) {
15411545
return to.clone();

0 commit comments

Comments
 (0)