mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-03 18:29:00 +00:00
Merge branch 'main' into fix-type-matching
This commit is contained in:
commit
2ad38717cd
23 changed files with 241 additions and 276 deletions
|
@ -113,9 +113,7 @@ impl Context {
|
|||
let constr = fv.constraint().unwrap();
|
||||
if let Some((l, r)) = constr.get_sub_sup() {
|
||||
// |Int <: T <: Int| T -> T ==> Int -> Int
|
||||
if l == r
|
||||
/*self.same_type_of(l, r)*/
|
||||
{
|
||||
if l == r {
|
||||
fv.forced_link(l);
|
||||
FreeVar(fv)
|
||||
} else if r != &Obj && self.is_class(r) && variance == Contravariant {
|
||||
|
|
|
@ -285,7 +285,7 @@ impl Context {
|
|||
mode,
|
||||
ParamKind::NonDefault,
|
||||
) {
|
||||
Ok(t) => non_defaults.push(t),
|
||||
Ok(pt) => non_defaults.push(pt),
|
||||
Err(es) => {
|
||||
errs.extend(es);
|
||||
non_defaults.push(ParamTy::pos(param.inspect().cloned(), Type::Failure));
|
||||
|
@ -325,7 +325,7 @@ impl Context {
|
|||
mode,
|
||||
ParamKind::Default(default_t),
|
||||
) {
|
||||
Ok(t) => defaults.push(t),
|
||||
Ok(pt) => defaults.push(pt),
|
||||
Err(es) => {
|
||||
errs.extend(es);
|
||||
defaults.push(ParamTy::pos(p.sig.inspect().cloned(), Type::Failure));
|
||||
|
@ -379,28 +379,25 @@ impl Context {
|
|||
mode: RegistrationMode,
|
||||
kind: ParamKind,
|
||||
) -> TyCheckResult<Type> {
|
||||
let spec_t = if let Some(t_spec_with_op) = &sig.t_spec {
|
||||
self.instantiate_typespec(
|
||||
&t_spec_with_op.t_spec,
|
||||
opt_decl_t,
|
||||
tmp_tv_cache,
|
||||
mode,
|
||||
false,
|
||||
)?
|
||||
let gen_free_t = || {
|
||||
let level = if mode == PreRegister {
|
||||
self.level
|
||||
} else {
|
||||
self.level + 1
|
||||
};
|
||||
free_var(level, Constraint::new_type_of(Type))
|
||||
};
|
||||
let spec_t = if let Some(spec_with_op) = &sig.t_spec {
|
||||
self.instantiate_typespec(&spec_with_op.t_spec, opt_decl_t, tmp_tv_cache, mode, false)?
|
||||
} else {
|
||||
match &sig.pat {
|
||||
ast::ParamPattern::Lit(lit) => v_enum(set![self.eval_lit(lit)?]),
|
||||
ast::ParamPattern::Discard(_) => Type::Obj,
|
||||
ast::ParamPattern::Ref(_) => ref_(gen_free_t()),
|
||||
ast::ParamPattern::RefMut(_) => ref_mut(gen_free_t(), None),
|
||||
// ast::ParamPattern::VarName(name) if &name.inspect()[..] == "_" => Type::Obj,
|
||||
// TODO: Array<Lit>
|
||||
_ => {
|
||||
let level = if mode == PreRegister {
|
||||
self.level
|
||||
} else {
|
||||
self.level + 1
|
||||
};
|
||||
free_var(level, Constraint::new_type_of(Type))
|
||||
}
|
||||
_ => gen_free_t(),
|
||||
}
|
||||
};
|
||||
if let Some(decl_pt) = opt_decl_t {
|
||||
|
|
|
@ -363,12 +363,16 @@ impl Context {
|
|||
)?;
|
||||
if &name.inspect()[..] == "self" {
|
||||
if let Some(self_t) = self.rec_get_self_t() {
|
||||
self.sub_unify(&spec_t, &self_t, name.loc(), Some(name.inspect()))?;
|
||||
self.sub_unify(
|
||||
&spec_t,
|
||||
&ref_(self_t),
|
||||
name.loc(),
|
||||
Some(name.inspect()),
|
||||
)?;
|
||||
} else {
|
||||
log!(err "self_t is None");
|
||||
}
|
||||
}
|
||||
let spec_t = ref_(spec_t);
|
||||
let kind = VarKind::parameter(DefId(get_hash(&(&self.name, name))), default);
|
||||
let vi = VarInfo::new(
|
||||
spec_t,
|
||||
|
@ -409,12 +413,16 @@ impl Context {
|
|||
)?;
|
||||
if &name.inspect()[..] == "self" {
|
||||
if let Some(self_t) = self.rec_get_self_t() {
|
||||
self.sub_unify(&spec_t, &self_t, name.loc(), Some(name.inspect()))?;
|
||||
self.sub_unify(
|
||||
&spec_t,
|
||||
&ref_mut(self_t, None),
|
||||
name.loc(),
|
||||
Some(name.inspect()),
|
||||
)?;
|
||||
} else {
|
||||
log!(err "self_t is None");
|
||||
}
|
||||
}
|
||||
let spec_t = ref_mut(spec_t.clone(), Some(spec_t));
|
||||
let kind = VarKind::parameter(DefId(get_hash(&(&self.name, name))), default);
|
||||
let vi = VarInfo::new(
|
||||
spec_t,
|
||||
|
|
|
@ -548,6 +548,12 @@ impl Context {
|
|||
return Ok(());
|
||||
}
|
||||
match (maybe_sub, maybe_sup) {
|
||||
(Type::FreeVar(lfv), _) if lfv.is_linked() => {
|
||||
self.sub_unify(&lfv.crack(), maybe_sup, loc, param_name)
|
||||
}
|
||||
(_, Type::FreeVar(rfv)) if rfv.is_linked() => {
|
||||
self.sub_unify(maybe_sub, &rfv.crack(), loc, param_name)
|
||||
}
|
||||
// lfv's sup can be shrunk (take min), rfv's sub can be expanded (take union)
|
||||
// lfvのsupは縮小可能(minを取る)、rfvのsubは拡大可能(unionを取る)
|
||||
// sub_unify(?T[0](:> Never, <: Int), ?U[1](:> Never, <: Nat)): (/* ?U[1] --> ?T[0](:> Never, <: Nat))
|
||||
|
@ -605,12 +611,6 @@ impl Context {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
(Type::FreeVar(lfv), _) if lfv.is_linked() => {
|
||||
self.sub_unify(&lfv.crack(), maybe_sup, loc, param_name)
|
||||
}
|
||||
(_, Type::FreeVar(rfv)) if rfv.is_linked() => {
|
||||
self.sub_unify(maybe_sub, &rfv.crack(), loc, param_name)
|
||||
}
|
||||
(_, Type::FreeVar(rfv)) if rfv.is_unbound() => {
|
||||
// NOTE: cannot `borrow_mut` because of cycle reference
|
||||
let rfv_ref = unsafe { rfv.as_ptr().as_mut().unwrap() };
|
||||
|
@ -849,7 +849,11 @@ impl Context {
|
|||
(_, Type::Or(l, r)) => self
|
||||
.sub_unify(maybe_sub, l, loc, param_name)
|
||||
.or_else(|_e| self.sub_unify(maybe_sub, r, loc, param_name)),
|
||||
(Type::Ref(l), Type::Ref(r)) => self.sub_unify(l, r, loc, param_name),
|
||||
(_, Type::Ref(t)) => self.sub_unify(maybe_sub, t, loc, param_name),
|
||||
(Type::RefMut { before: l, .. }, Type::RefMut { before: r, .. }) => {
|
||||
self.sub_unify(l, r, loc, param_name)
|
||||
}
|
||||
(_, Type::RefMut { before, .. }) => self.sub_unify(maybe_sub, before, loc, param_name),
|
||||
(Type::Proj { .. }, _) => todo!(),
|
||||
(_, Type::Proj { .. }) => todo!(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue