mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-28 12:14:43 +00:00
fix: method resolution bug
This commit is contained in:
parent
544fee8d59
commit
1954d27a63
3 changed files with 50 additions and 2 deletions
|
@ -1361,8 +1361,9 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let mut checked = vec![];
|
||||||
for ctx in self
|
for ctx in self
|
||||||
.get_nominal_super_type_ctxs(obj.ref_t())
|
.get_nominal_super_type_ctxs(&obj.ref_t().lower_bounded())
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
TyCheckError::type_not_found(
|
TyCheckError::type_not_found(
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
|
@ -1373,6 +1374,7 @@ impl Context {
|
||||||
)
|
)
|
||||||
})?
|
})?
|
||||||
{
|
{
|
||||||
|
checked.push(&ctx.typ);
|
||||||
if let Some(vi) = ctx.get_current_scope_non_param(&attr_name.name) {
|
if let Some(vi) = ctx.get_current_scope_non_param(&attr_name.name) {
|
||||||
self.validate_visibility(attr_name, vi, input, namespace)?;
|
self.validate_visibility(attr_name, vi, input, namespace)?;
|
||||||
return Ok(vi.clone());
|
return Ok(vi.clone());
|
||||||
|
@ -1395,6 +1397,45 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if obj.ref_t() != &obj.ref_t().lower_bounded() {
|
||||||
|
for ctx in self
|
||||||
|
.get_nominal_super_type_ctxs(obj.ref_t())
|
||||||
|
.ok_or_else(|| {
|
||||||
|
TyCheckError::type_not_found(
|
||||||
|
self.cfg.input.clone(),
|
||||||
|
line!() as usize,
|
||||||
|
obj.loc(),
|
||||||
|
self.caused_by(),
|
||||||
|
obj.ref_t(),
|
||||||
|
)
|
||||||
|
})?
|
||||||
|
{
|
||||||
|
if checked.contains(&&ctx.typ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if let Some(vi) = ctx.get_current_scope_non_param(&attr_name.name) {
|
||||||
|
self.validate_visibility(attr_name, vi, input, namespace)?;
|
||||||
|
return Ok(vi.clone());
|
||||||
|
}
|
||||||
|
for methods_ctx in ctx.methods_list.iter() {
|
||||||
|
if let Some(vi) = methods_ctx.get_current_scope_non_param(&attr_name.name) {
|
||||||
|
self.validate_visibility(attr_name, vi, input, namespace)?;
|
||||||
|
return Ok(vi.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(ctx) = self.get_same_name_context(&ctx.name) {
|
||||||
|
match ctx.rec_get_var_info(attr_name, AccessKind::BoundAttr, input, namespace) {
|
||||||
|
Triple::Ok(t) => {
|
||||||
|
return Ok(t);
|
||||||
|
}
|
||||||
|
Triple::Err(e) => {
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
Triple::None => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
match self.get_attr_type_by_name(obj, attr_name, namespace) {
|
match self.get_attr_type_by_name(obj, attr_name, namespace) {
|
||||||
Triple::Ok(method) => {
|
Triple::Ok(method) => {
|
||||||
let def_t = self
|
let def_t = self
|
||||||
|
@ -3013,6 +3054,7 @@ impl Context {
|
||||||
/// ```erg
|
/// ```erg
|
||||||
/// get_nominal_super_type_ctx(Nat) == [<Nat>, <Int>, <Float>, ..., <Obj>, <Eq>, ...]
|
/// get_nominal_super_type_ctx(Nat) == [<Nat>, <Int>, <Float>, ..., <Obj>, <Eq>, ...]
|
||||||
/// get_nominal_super_type_ctx({Nat}) == [<Type>, <Obj>, <Eq>, ...]
|
/// get_nominal_super_type_ctx({Nat}) == [<Type>, <Obj>, <Eq>, ...]
|
||||||
|
/// get_nominal_super_type_ctx(?T(:> Nat, <: Eq)) == == [<Eq>, ...]
|
||||||
/// ```
|
/// ```
|
||||||
pub fn get_nominal_super_type_ctxs<'a>(&'a self, t: &Type) -> Option<Vec<&'a TypeContext>> {
|
pub fn get_nominal_super_type_ctxs<'a>(&'a self, t: &Type) -> Option<Vec<&'a TypeContext>> {
|
||||||
match t {
|
match t {
|
||||||
|
|
|
@ -22,6 +22,12 @@ for! zip([1], ["a"]), ((i: Str, s: Str),) => # ERR
|
||||||
for! zip([1], ["a"]), ((i, s),) =>
|
for! zip([1], ["a"]), ((i, s),) =>
|
||||||
k = i + "a" # ERR
|
k = i + "a" # ERR
|
||||||
print! k
|
print! k
|
||||||
|
for! zip([1], ["a"]), (is) =>
|
||||||
|
i = is[0]
|
||||||
|
s = is[1]
|
||||||
|
k = i + "a" # ERR
|
||||||
|
_ = s + 1 # ERR
|
||||||
|
print! k
|
||||||
|
|
||||||
for! zip([1+1], ["a"+"b"]), ((i, s),) => # i: Nat, s: Str
|
for! zip([1+1], ["a"+"b"]), ((i, s),) => # i: Nat, s: Str
|
||||||
print! i + 1
|
print! i + 1
|
||||||
|
|
|
@ -716,7 +716,7 @@ fn exec_structural_err() -> Result<(), ()> {
|
||||||
#[test]
|
#[test]
|
||||||
fn exec_subtyping_err() -> Result<(), ()> {
|
fn exec_subtyping_err() -> Result<(), ()> {
|
||||||
// NOTE: The content of some errors is semantically redundant and can be reduced.
|
// NOTE: The content of some errors is semantically redundant and can be reduced.
|
||||||
expect_failure("tests/should_err/subtyping.er", 3, 13)
|
expect_failure("tests/should_err/subtyping.er", 3, 15)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue