Skip to content

Commit

Permalink
fix: method inference bug
Browse files Browse the repository at this point in the history
  • Loading branch information
mtshiba committed Oct 2, 2024
1 parent a849e7c commit a290684
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 35 deletions.
4 changes: 2 additions & 2 deletions crates/erg_compiler/context/inquire.rs
Original file line number Diff line number Diff line change
Expand Up @@ -631,14 +631,14 @@ impl Context {
.future_defined_locals
.get_key_value(&ident.inspect()[..])
{
if name.loc().is_real() && ident.loc() != name.loc() {
if name.loc().is_real() && ident.loc() < name.loc() {
return Triple::Err(TyCheckError::access_before_def_error(
input.clone(),
line!() as usize,
ident.loc(),
namespace.name.to_string(),
ident.inspect(),
name.ln_begin().unwrap_or(100),
name.ln_begin().unwrap_or(0),
self.get_similar_name(ident.inspect()),
));
} else if ident.loc() == name.loc() {
Expand Down
2 changes: 1 addition & 1 deletion crates/erg_compiler/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1411,7 +1411,7 @@ impl Context {
}

/// enumerates all the variables/methods in the current context & super contexts.
fn type_dir<'t>(&'t self, namespace: &'t Context) -> Dict<&VarName, &VarInfo> {
pub(crate) fn type_dir<'t>(&'t self, namespace: &'t Context) -> Dict<&VarName, &VarInfo> {
let mut attrs = self.locals.iter().collect::<Dict<_, _>>();
attrs.guaranteed_extend(
self.params
Expand Down
48 changes: 30 additions & 18 deletions crates/erg_compiler/context/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2182,24 +2182,36 @@ impl Context {
gen.typ().clone(),
)
};
if let Err(es) = methods.register_fixed_auto_impl(
"__call__",
call_t,
Immutable,
Visibility::private(ctx.name.clone()),
None,
) {
errs.extend(es);
}
// 必要なら、ユーザーが独自に上書きする
if let Err(es) = methods.register_auto_impl(
"new",
new_t,
Immutable,
Visibility::public(ctx.name.clone()),
None,
) {
errs.extend(es);
if PYTHON_MODE {
if let Err(es) = methods.register_auto_impl(
"__call__",
call_t,
Immutable,
Visibility::private(ctx.name.clone()),
None,
) {
errs.extend(es);
}
} else {
if let Err(es) = methods.register_fixed_auto_impl(
"__call__",
call_t,
Immutable,
Visibility::private(ctx.name.clone()),
None,
) {
errs.extend(es);
}
// 必要なら、ユーザーが独自に上書きする
if let Err(es) = methods.register_auto_impl(
"new",
new_t,
Immutable,
Visibility::public(ctx.name.clone()),
None,
) {
errs.extend(es);
}
}
ctx.methods_list.push(MethodContext::new(
DefId(0),
Expand Down
15 changes: 13 additions & 2 deletions crates/erg_compiler/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2694,7 +2694,7 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
);
errors.push(err);
}
let Some(methods_list) = &mut self
let Some(methods_list) = self
.module
.context
.get_mut_nominal_type_ctx(&class)
Expand All @@ -2709,7 +2709,8 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
continue;
};
let methods_idx = methods_list.iter().position(|m| m.id == methods.id);
let Some(methods_ctx) = methods_idx.map(|idx| methods_list.remove(idx)) else {
// We can't remove the method ctx here because methods' information must be hold
let Some(methods_ctx) = methods_idx.map(|idx| methods_list[idx].clone()) else {
let err = LowerError::unreachable(
self.cfg.input.clone(),
erg_common::fn_name!(),
Expand Down Expand Up @@ -2775,6 +2776,16 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
},
}
}
if let Some(methods_list) = self
.module
.context
.get_mut_nominal_type_ctx(&class)
.map(|ctx| &mut ctx.methods_list)
{
if let Some(idx) = methods_idx {
methods_list.remove(idx);
}
}
if let Err(errs) = self.module.context.check_decls() {
errors.extend(errs);
}
Expand Down
14 changes: 3 additions & 11 deletions crates/erg_compiler/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4172,17 +4172,9 @@ impl Type {
Self::FreeVar(fv) if fv.is_linked() => fv.unwrap_linked().eliminate_subsup(target),
Self::FreeVar(ref fv) if fv.constraint_is_sandwiched() => {
let (sub, sup) = fv.get_subsup().unwrap();
let sub = if sub.addr_eq(target) {
Type::Never
} else {
sub
};
let sup = if sup.addr_eq(target) { Type::Obj } else { sup };
fv.do_avoiding_recursion(|| {
let sub = sub.eliminate_subsup(target);
let sup = sup.eliminate_subsup(target);
self.update_tyvar(sub, sup, None, false);
});
let sub = sub.eliminate_subsup(target);
let sup = sup.eliminate_subsup(target);
self.update_tyvar(sub, sup, None, false);
self
}
Self::And(tys, idx) => Self::checked_and(
Expand Down
5 changes: 5 additions & 0 deletions tests/should_err/class_attr.er
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ _ = C.y # ERR
c = C.new({.x = 1; .y = 2})
_: Int = c.x
_: Int = c.y

D = Class()
D.
x = y # ERR
y = 1
2 changes: 1 addition & 1 deletion tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ fn exec_assert_cast_err() -> Result<(), ()> {

#[test]
fn exec_class_attr_err() -> Result<(), ()> {
expect_compile_failure("tests/should_err/class_attr.er", 1, 1)
expect_compile_failure("tests/should_err/class_attr.er", 1, 2)
}

#[test]
Expand Down

0 comments on commit a290684

Please sign in to comment.