mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-28 04:09:05 +00:00
fix(typechecker): type assignment bug for bound methods
This commit is contained in:
parent
b452503105
commit
26046d90e5
5 changed files with 34 additions and 1 deletions
|
@ -458,6 +458,10 @@ impl Context {
|
||||||
}
|
}
|
||||||
match self.get_attr_from_nominal_t(obj, ident, input, namespace) {
|
match self.get_attr_from_nominal_t(obj, ident, input, namespace) {
|
||||||
Ok(vi) => {
|
Ok(vi) => {
|
||||||
|
if let Some(self_t) = vi.t.self_t() {
|
||||||
|
self.sub_unify(obj.ref_t(), self_t, obj.loc(), Some(&"self".into()))
|
||||||
|
.map_err(|mut e| e.remove(0))?;
|
||||||
|
}
|
||||||
return Ok(vi);
|
return Ok(vi);
|
||||||
}
|
}
|
||||||
Err(e) if e.core.kind == ErrorKind::AttributeError => {}
|
Err(e) if e.core.kind == ErrorKind::AttributeError => {}
|
||||||
|
|
|
@ -360,6 +360,10 @@ impl SubrType {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_method(&self) -> bool {
|
||||||
|
self.self_t().is_some()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn non_var_params(&self) -> impl Iterator<Item = &ParamTy> + Clone {
|
pub fn non_var_params(&self) -> impl Iterator<Item = &ParamTy> + Clone {
|
||||||
if self.var_params.is_some() {
|
if self.var_params.is_some() {
|
||||||
self.non_default_params.iter().chain([].iter())
|
self.non_default_params.iter().chain([].iter())
|
||||||
|
@ -1268,6 +1272,16 @@ impl Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_method(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_method(),
|
||||||
|
Self::Refinement(refine) => refine.t.is_method(),
|
||||||
|
Self::Subr(subr) => subr.is_method(),
|
||||||
|
Self::Quantified(quant) => quant.is_method(),
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_quantified(&self) -> bool {
|
pub fn is_quantified(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_quantified(),
|
Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_quantified(),
|
||||||
|
|
|
@ -720,7 +720,11 @@ impl TyParam {
|
||||||
pub fn qvars(&self) -> Set<(Str, Constraint)> {
|
pub fn qvars(&self) -> Set<(Str, Constraint)> {
|
||||||
match self {
|
match self {
|
||||||
Self::FreeVar(fv) if !fv.constraint_is_uninited() => {
|
Self::FreeVar(fv) if !fv.constraint_is_uninited() => {
|
||||||
set! { (fv.unbound_name().unwrap(), fv.constraint().unwrap()) }
|
if let (Some(name), Some(constraint)) = (fv.unbound_name(), fv.constraint()) {
|
||||||
|
set! { (name, constraint) }
|
||||||
|
} else {
|
||||||
|
set! {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Self::FreeVar(fv) if fv.is_linked() => fv.forced_as_ref().linked().unwrap().qvars(),
|
Self::FreeVar(fv) if fv.is_linked() => fv.forced_as_ref().linked().unwrap().qvars(),
|
||||||
Self::Type(t) => t.qvars(),
|
Self::Type(t) => t.qvars(),
|
||||||
|
|
6
tests/should_err/move.er
Normal file
6
tests/should_err/move.er
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
a = ![]
|
||||||
|
|
||||||
|
a.sort! # WARN
|
||||||
|
|
||||||
|
# NOTE: For safety reasons this is assumed to be an error, but maybe this restriction can be relaxed
|
||||||
|
print! a # ERR
|
|
@ -249,3 +249,8 @@ fn exec_var_args() -> Result<(), ()> {
|
||||||
fn exec_var_args_err() -> Result<(), ()> {
|
fn exec_var_args_err() -> Result<(), ()> {
|
||||||
expect_failure("tests/should_err/var_args.er", 2)
|
expect_failure("tests/should_err/var_args.er", 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn exec_move() -> Result<(), ()> {
|
||||||
|
expect_failure("tests/should_err/move.er", 1)
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue