fix: ignored match arms

This commit is contained in:
Shunsuke Shibayama 2024-08-29 02:37:19 +09:00
parent 8e9458e75a
commit 7e48a2f9c8
10 changed files with 633 additions and 138 deletions

View file

@ -19,7 +19,7 @@ use crate::ty::ConstSubr;
use crate::ty::GuardType;
use crate::ty::ValueObj;
use crate::ty::{HasType, Predicate, Type};
use crate::{type_feature_error, unreachable_error};
use crate::{mono_type_pattern, unreachable_error};
use Type::*;
use crate::context::{Context, VarInfo};
@ -40,7 +40,6 @@ pub struct TyVarCache {
pub(crate) tyvar_instances: Dict<VarName, Type>,
pub(crate) typaram_instances: Dict<VarName, TyParam>,
pub(crate) var_infos: Dict<VarName, VarInfo>,
pub(crate) structural_inner: bool,
}
impl fmt::Display for TyVarCache {
@ -61,7 +60,6 @@ impl TyVarCache {
tyvar_instances: Dict::new(),
typaram_instances: Dict::new(),
var_infos: Dict::new(),
structural_inner: false,
}
}
@ -419,6 +417,8 @@ impl Context {
tmp_tv_cache.instantiate_constraint(constr, self, loc)?;
fv.update_constraint(new_constr, true);
}
} else {
todo!("{tp}");
}
Ok(tp)
} else if let Some(t) = tmp_tv_cache.get_tyvar(&name) {
@ -433,6 +433,8 @@ impl Context {
tmp_tv_cache.instantiate_constraint(constr, self, loc)?;
fv.update_constraint(new_constr, true);
}
} else {
todo!("{t}");
}
Ok(TyParam::t(t))
} else {
@ -517,20 +519,28 @@ impl Context {
let nd_params = lambda
.nd_params
.into_iter()
.map(|pt| pt.try_map_type(|t| self.instantiate_t_inner(t, tmp_tv_cache, loc)))
.map(|pt| {
pt.try_map_type(&mut |t| self.instantiate_t_inner(t, tmp_tv_cache, loc))
})
.collect::<TyCheckResult<_>>()?;
let var_params = lambda
.var_params
.map(|pt| pt.try_map_type(|t| self.instantiate_t_inner(t, tmp_tv_cache, loc)))
.map(|pt| {
pt.try_map_type(&mut |t| self.instantiate_t_inner(t, tmp_tv_cache, loc))
})
.transpose()?;
let d_params = lambda
.d_params
.into_iter()
.map(|pt| pt.try_map_type(|t| self.instantiate_t_inner(t, tmp_tv_cache, loc)))
.map(|pt| {
pt.try_map_type(&mut |t| self.instantiate_t_inner(t, tmp_tv_cache, loc))
})
.collect::<TyCheckResult<_>>()?;
let kw_var_params = lambda
.kw_var_params
.map(|pt| pt.try_map_type(|t| self.instantiate_t_inner(t, tmp_tv_cache, loc)))
.map(|pt| {
pt.try_map_type(&mut |t| self.instantiate_t_inner(t, tmp_tv_cache, loc))
})
.transpose()?;
let body = lambda
.body
@ -579,21 +589,17 @@ impl Context {
Ok(TyParam::t(t))
}
TyParam::Value(val) => {
// println!("592: {val} / {tmp_tv_cache}");
let val = val.try_map_t(&mut |t| self.instantiate_t_inner(t, tmp_tv_cache, loc))?;
// .try_map_tp(&mut |tp| self.instantiate_tp(tp, tmp_tv_cache, loc))?;
// println!("596: {val} / {tmp_tv_cache}");
Ok(TyParam::Value(val))
}
TyParam::Erased(t) => {
let t = self.instantiate_t_inner(*t, tmp_tv_cache, loc)?;
Ok(TyParam::Erased(Box::new(t)))
}
p @ (TyParam::Mono(_) | TyParam::FreeVar(_)) => Ok(p),
other => {
type_feature_error!(
self,
loc.loc(),
&format!("instantiating type-parameter {other}")
)
}
p @ (TyParam::Mono(_) | TyParam::FreeVar(_) | TyParam::Failure) => Ok(p),
}
}
@ -670,7 +676,11 @@ impl Context {
let rhs = self.instantiate_pred(*rhs, tmp_tv_cache, loc)?;
Ok(Predicate::general_ne(lhs, rhs))
}
_ => Ok(pred),
Predicate::Attr { receiver, name } => {
let receiver = self.instantiate_tp(receiver, tmp_tv_cache, loc)?;
Ok(Predicate::attr(receiver, name))
}
Predicate::Const(_) | Predicate::Failure => Ok(pred),
}
}
@ -714,6 +724,10 @@ impl Context {
}
Ok(ValueObj::List(new.into()))
}
ValueObj::UnsizedList(lis) => {
let lis = self.instantiate_value(*lis, tmp_tv_cache, loc)?;
Ok(ValueObj::UnsizedList(Box::new(lis)))
}
ValueObj::Tuple(tup) => {
let mut new = vec![];
for v in tup.iter().cloned() {
@ -754,7 +768,18 @@ impl Context {
}
Ok(ValueObj::DataClass { name, fields: new })
}
_ => Ok(value),
ValueObj::Int(_)
| ValueObj::Nat(_)
| ValueObj::Float(_)
| ValueObj::Str(_)
| ValueObj::Bool(_)
| ValueObj::Code(_)
| ValueObj::None
| ValueObj::Ellipsis
| ValueObj::Inf
| ValueObj::NegInf
| ValueObj::NotImplemented
| ValueObj::Failure => Ok(value),
}
}
@ -776,8 +801,7 @@ impl Context {
let t = t.clone();
Ok(t)
} else if let Some(tp) = tmp_tv_cache.get_typaram(&name) {
if let TyParam::Type(t) = tp {
let t = *t.clone();
if let Ok(t) = self.convert_tp_into_type(tp.clone()) {
Ok(t)
} else {
todo!(
@ -797,8 +821,8 @@ impl Context {
if let Some(t) = tv_ctx.get_tyvar(&name) {
return Ok(t.clone());
} else if let Some(tp) = tv_ctx.get_typaram(&name) {
if let TyParam::Type(t) = tp {
return Ok(*t.clone());
if let Ok(t) = self.convert_tp_into_type(tp.clone()) {
return Ok(t);
} else {
todo!(
"typaram_insts: {}\ntyvar_insts:{}\n{tp}",
@ -902,16 +926,8 @@ impl Context {
Ok(poly(name, params))
}
Structural(t) => {
// avoid infinite recursion
if tmp_tv_cache.structural_inner {
Ok(t.structuralize())
} else {
if t.is_recursive() {
tmp_tv_cache.structural_inner = true;
}
let t = self.instantiate_t_inner(*t, tmp_tv_cache, loc)?;
Ok(t.structuralize())
}
let t = self.instantiate_t_inner(*t, tmp_tv_cache, loc)?;
Ok(t.structuralize())
}
FreeVar(fv) => {
if let Some((sub, sup)) = fv.get_subsup() {
@ -961,8 +977,15 @@ impl Context {
let sup = self.instantiate_t_inner(*sup, tmp_tv_cache, loc)?;
Ok(bounded(sub, sup))
}
other if other.is_monomorphic() => Ok(other),
other => type_feature_error!(self, loc.loc(), &format!("instantiating type {other}")),
Callable { param_ts, return_t } => {
let param_ts = param_ts
.into_iter()
.map(|t| self.instantiate_t_inner(t, tmp_tv_cache, loc))
.collect::<TyCheckResult<_>>()?;
let return_t = self.instantiate_t_inner(*return_t, tmp_tv_cache, loc)?;
Ok(callable(param_ts, return_t))
}
mono_type_pattern!() => Ok(unbound),
}
}
@ -983,9 +1006,9 @@ impl Context {
if let Some(self_t) = ty.self_t() {
self.sub_unify(callee.ref_t(), self_t, callee, Some(&Str::ever("self")))?;
}
if cfg!(feature = "debug") && ty.has_qvar() {
/*if DEBUG_MODE && ty.has_qvar() {
panic!("{ty} has qvar")
}
}*/
Ok(ty)
}
// HACK: {op: |T|(T -> T) | op == F} => ?T -> ?T
@ -1028,6 +1051,7 @@ impl Context {
log!(err "{subr} has qvar");
self.instantiate(Type::Subr(subr).quantify(), callee)
}
// There are no quantified types inside normal types (rank-0 types) due to the rank-1 restriction
// rank-1制限により、通常の型(rank-0型)の内側に量化型は存在しない
other => Ok(other),
}
@ -1047,9 +1071,9 @@ impl Context {
Quantified(quant) => {
let mut tmp_tv_cache = TyVarCache::new(self.level, self);
let ty = self.instantiate_t_inner(*quant, &mut tmp_tv_cache, &())?;
if cfg!(feature = "debug") && ty.has_qvar() {
/*if DEBUG_MODE && ty.has_qvar() {
panic!("{ty} has qvar")
}
}*/
Ok(ty)
}
Refinement(refine) if refine.t.is_quantified_subr() => {