mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 02:39:20 +00:00
fix: ignored match arms
This commit is contained in:
parent
8e9458e75a
commit
7e48a2f9c8
10 changed files with 633 additions and 138 deletions
|
@ -18,7 +18,7 @@ use crate::ty::{HasType, Predicate, SubrType, Type};
|
|||
|
||||
use crate::context::{Context, Variance};
|
||||
use crate::error::{TyCheckError, TyCheckErrors, TyCheckResult};
|
||||
use crate::{feature_error, hir, unreachable_error};
|
||||
use crate::{feature_error, hir, mono_type_pattern, mono_value_pattern, unreachable_error};
|
||||
|
||||
use Type::*;
|
||||
use Variance::*;
|
||||
|
@ -45,7 +45,10 @@ impl Generalizer {
|
|||
fn generalize_tp(&mut self, free: TyParam, uninit: bool) -> TyParam {
|
||||
match free {
|
||||
TyParam::Type(t) => TyParam::t(self.generalize_t(*t, uninit)),
|
||||
TyParam::Value(val) => TyParam::Value(val.map_t(&mut |t| self.generalize_t(t, uninit))),
|
||||
TyParam::Value(val) => TyParam::Value(
|
||||
val.map_t(&mut |t| self.generalize_t(t, uninit))
|
||||
.map_tp(&mut |tp| self.generalize_tp(tp, uninit)),
|
||||
),
|
||||
TyParam::FreeVar(fv) if fv.is_generalized() => TyParam::FreeVar(fv),
|
||||
TyParam::FreeVar(fv) if fv.is_linked() => {
|
||||
let tp = fv.crack().clone();
|
||||
|
@ -63,6 +66,9 @@ impl Generalizer {
|
|||
.map(|tp| self.generalize_tp(tp, uninit))
|
||||
.collect(),
|
||||
),
|
||||
TyParam::UnsizedList(tp) => {
|
||||
TyParam::UnsizedList(Box::new(self.generalize_tp(*tp, uninit)))
|
||||
}
|
||||
TyParam::Tuple(tps) => TyParam::Tuple(
|
||||
tps.into_iter()
|
||||
.map(|tp| self.generalize_tp(tp, uninit))
|
||||
|
@ -126,6 +132,14 @@ impl Generalizer {
|
|||
let obj = self.generalize_tp(*obj, uninit);
|
||||
TyParam::proj(obj, attr)
|
||||
}
|
||||
TyParam::ProjCall { obj, attr, args } => {
|
||||
let obj = self.generalize_tp(*obj, uninit);
|
||||
let args = args
|
||||
.into_iter()
|
||||
.map(|tp| self.generalize_tp(tp, uninit))
|
||||
.collect();
|
||||
TyParam::proj_call(obj, attr, args)
|
||||
}
|
||||
TyParam::Erased(t) => TyParam::erased(self.generalize_t(*t, uninit)),
|
||||
TyParam::App { name, args } => {
|
||||
let args = args
|
||||
|
@ -143,13 +157,7 @@ impl Generalizer {
|
|||
let val = self.generalize_tp(*val, uninit);
|
||||
TyParam::unary(op, val)
|
||||
}
|
||||
other if other.has_no_unbound_var() => other,
|
||||
other => {
|
||||
if DEBUG_MODE {
|
||||
todo!("{other:?}");
|
||||
}
|
||||
other
|
||||
}
|
||||
TyParam::Mono(_) | TyParam::Failure => free,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,6 +209,7 @@ impl Generalizer {
|
|||
Type::FreeVar(fv)
|
||||
}
|
||||
}
|
||||
FreeVar(_) => free_type,
|
||||
Subr(mut subr) => {
|
||||
self.variance = Contravariant;
|
||||
let qnames = subr.essential_qnames();
|
||||
|
@ -229,6 +238,10 @@ impl Generalizer {
|
|||
return_t,
|
||||
)
|
||||
}
|
||||
Quantified(quant) => {
|
||||
log!(err "{quant}");
|
||||
quant.quantify()
|
||||
}
|
||||
Record(rec) => {
|
||||
let fields = rec
|
||||
.into_iter()
|
||||
|
@ -305,8 +318,14 @@ impl Generalizer {
|
|||
let to = self.generalize_t(*grd.to, uninit);
|
||||
guard(grd.namespace, grd.target, to)
|
||||
}
|
||||
// REVIEW: その他何でもそのまま通していいのか?
|
||||
other => other,
|
||||
Bounded { sub, sup } => {
|
||||
let sub = self.generalize_t(*sub, uninit);
|
||||
let sup = self.generalize_t(*sup, uninit);
|
||||
bounded(sub, sup)
|
||||
}
|
||||
Int | Nat | Float | Ratio | Complex | Bool | Str | Never | Obj | Type | Error
|
||||
| Code | Frame | NoneType | Inf | NegInf | NotImplementedType | Ellipsis
|
||||
| ClassType | TraitType | Patch | Failure | Uninited | Mono(_) => free_type,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -450,7 +469,7 @@ impl<'c, 'q, 'l, L: Locational> Dereferencer<'c, 'q, 'l, L> {
|
|||
fn deref_value(&mut self, val: ValueObj) -> TyCheckResult<ValueObj> {
|
||||
match val {
|
||||
ValueObj::Type(mut t) => {
|
||||
t.try_map_t(|t| self.deref_tyvar(t.clone()))?;
|
||||
t.try_map_t(&mut |t| self.deref_tyvar(t.clone()))?;
|
||||
Ok(ValueObj::Type(t))
|
||||
}
|
||||
ValueObj::List(vs) => {
|
||||
|
@ -501,7 +520,8 @@ impl<'c, 'q, 'l, L: Locational> Dereferencer<'c, 'q, 'l, L> {
|
|||
})
|
||||
}
|
||||
ValueObj::UnsizedList(v) => Ok(ValueObj::UnsizedList(Box::new(self.deref_value(*v)?))),
|
||||
_ => Ok(val),
|
||||
ValueObj::Subr(subr) => Ok(ValueObj::Subr(subr)),
|
||||
mono_value_pattern!() => Ok(val),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -526,6 +546,7 @@ impl<'c, 'q, 'l, L: Locational> Dereferencer<'c, 'q, 'l, L> {
|
|||
fv.update_type(t);
|
||||
Ok(TyParam::FreeVar(fv))
|
||||
}
|
||||
TyParam::FreeVar(_) => Ok(tp),
|
||||
TyParam::Type(t) => Ok(TyParam::t(self.deref_tyvar(*t)?)),
|
||||
TyParam::Value(val) => self.deref_value(val).map(TyParam::Value),
|
||||
TyParam::Erased(t) => Ok(TyParam::erased(self.deref_tyvar(*t)?)),
|
||||
|
@ -558,6 +579,7 @@ impl<'c, 'q, 'l, L: Locational> Dereferencer<'c, 'q, 'l, L> {
|
|||
}
|
||||
Ok(TyParam::List(new_tps))
|
||||
}
|
||||
TyParam::UnsizedList(tp) => Ok(TyParam::UnsizedList(Box::new(self.deref_tp(*tp)?))),
|
||||
TyParam::Tuple(tps) => {
|
||||
let mut new_tps = vec![];
|
||||
for tp in tps {
|
||||
|
@ -609,20 +631,20 @@ impl<'c, 'q, 'l, L: Locational> Dereferencer<'c, 'q, 'l, L> {
|
|||
let nd_params = lambda
|
||||
.nd_params
|
||||
.into_iter()
|
||||
.map(|pt| pt.try_map_type(|t| self.deref_tyvar(t)))
|
||||
.map(|pt| pt.try_map_type(&mut |t| self.deref_tyvar(t)))
|
||||
.collect::<TyCheckResult<_>>()?;
|
||||
let var_params = lambda
|
||||
.var_params
|
||||
.map(|pt| pt.try_map_type(|t| self.deref_tyvar(t)))
|
||||
.map(|pt| pt.try_map_type(&mut |t| self.deref_tyvar(t)))
|
||||
.transpose()?;
|
||||
let d_params = lambda
|
||||
.d_params
|
||||
.into_iter()
|
||||
.map(|pt| pt.try_map_type(|t| self.deref_tyvar(t)))
|
||||
.map(|pt| pt.try_map_type(&mut |t| self.deref_tyvar(t)))
|
||||
.collect::<TyCheckResult<_>>()?;
|
||||
let kw_var_params = lambda
|
||||
.kw_var_params
|
||||
.map(|pt| pt.try_map_type(|t| self.deref_tyvar(t)))
|
||||
.map(|pt| pt.try_map_type(&mut |t| self.deref_tyvar(t)))
|
||||
.transpose()?;
|
||||
let body = lambda
|
||||
.body
|
||||
|
@ -645,10 +667,22 @@ impl<'c, 'q, 'l, L: Locational> Dereferencer<'c, 'q, 'l, L> {
|
|||
attr,
|
||||
})
|
||||
}
|
||||
TyParam::ProjCall { obj, attr, args } => {
|
||||
let obj = self.deref_tp(*obj)?;
|
||||
let mut new_args = vec![];
|
||||
for arg in args.into_iter() {
|
||||
new_args.push(self.deref_tp(arg)?);
|
||||
}
|
||||
Ok(TyParam::ProjCall {
|
||||
obj: Box::new(obj),
|
||||
attr,
|
||||
args: new_args,
|
||||
})
|
||||
}
|
||||
TyParam::Failure if self.level == 0 => Err(TyCheckErrors::from(
|
||||
TyCheckError::dummy_infer_error(self.ctx.cfg.input.clone(), fn_name!(), line!()),
|
||||
)),
|
||||
t => Ok(t),
|
||||
TyParam::Mono(_) | TyParam::Failure => Ok(tp),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -765,8 +799,12 @@ impl<'c, 'q, 'l, L: Locational> Dereferencer<'c, 'q, 'l, L> {
|
|||
let pred = self.deref_pred(*pred)?;
|
||||
Ok(!pred)
|
||||
}
|
||||
Predicate::Attr { receiver, name } => {
|
||||
let receiver = self.deref_tp(receiver)?;
|
||||
Ok(Predicate::attr(receiver, name))
|
||||
}
|
||||
Predicate::Value(v) => self.deref_value(v).map(Predicate::Value),
|
||||
_ => Ok(pred),
|
||||
Predicate::Const(_) | Predicate::Failure => Ok(pred),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -891,6 +929,7 @@ impl<'c, 'q, 'l, L: Locational> Dereferencer<'c, 'q, 'l, L> {
|
|||
Ok(Type::FreeVar(fv))
|
||||
}
|
||||
}
|
||||
FreeVar(_) => Ok(t),
|
||||
Poly { name, mut params } => {
|
||||
let typ = poly(&name, params.clone());
|
||||
let ctx = self.ctx.get_nominal_type_ctx(&typ).ok_or_else(|| {
|
||||
|
@ -1055,7 +1094,12 @@ impl<'c, 'q, 'l, L: Locational> Dereferencer<'c, 'q, 'l, L> {
|
|||
let to = self.deref_tyvar(*grd.to)?;
|
||||
Ok(guard(grd.namespace, grd.target, to))
|
||||
}
|
||||
t => Ok(t),
|
||||
Bounded { sub, sup } => {
|
||||
let sub = self.deref_tyvar(*sub)?;
|
||||
let sup = self.deref_tyvar(*sup)?;
|
||||
Ok(bounded(sub, sup))
|
||||
}
|
||||
mono_type_pattern!() => Ok(t),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue