Fix subtyping bug

This commit is contained in:
Shunsuke Shibayama 2022-10-21 20:04:14 +09:00
parent 978866b31a
commit c39973f536
7 changed files with 110 additions and 19 deletions

View file

@ -784,6 +784,13 @@ impl Context {
(_, TyParam::FreeVar(fv), _) if fv.is_linked() => {
self.supertype_of_tp(lp, &fv.crack(), variance)
}
// _: Type :> T == true
(TyParam::Erased(t), TyParam::Type(_), _)
| (TyParam::Type(_), TyParam::Erased(t), _)
if t.as_ref() == &Type =>
{
true
}
(TyParam::Type(l), TyParam::Type(r), Variance::Contravariant) => self.subtype_of(l, r),
(TyParam::Type(l), TyParam::Type(r), Variance::Covariant) => {
// if matches!(r.as_ref(), &Type::Refinement(_)) { log!(info "{l}, {r}, {}", self.structural_supertype_of(l, r, bounds, Some(lhs_variance))); }

View file

@ -9,6 +9,8 @@ use crate::ty::ValueArgs;
use erg_common::astr::AtomicStr;
use erg_common::color::{RED, RESET, YELLOW};
use erg_common::error::{ErrorCore, ErrorKind, Location};
use erg_common::str::Str;
use erg_common::vis::Field;
/// Requirement: Type, Impl := Type -> ClassType
pub fn class_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<ValueObj> {
@ -231,3 +233,27 @@ pub fn __dict_getitem__(mut args: ValueArgs, ctx: &Context) -> EvalValueResult<V
))
}
}
pub fn __range_getitem__(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult<ValueObj> {
let (_name, fields) = enum_unwrap!(
args.remove_left_or_key("Self").unwrap(),
ValueObj::DataClass { name, fields }
);
let index = enum_unwrap!(args.remove_left_or_key("Index").unwrap(), ValueObj::Nat);
let start = fields.get(&Field::private(Str::ever("start"))).unwrap();
let start = *enum_unwrap!(start, ValueObj::Nat);
let end = fields.get(&Field::private(Str::ever("end"))).unwrap();
let end = *enum_unwrap!(end, ValueObj::Nat);
// FIXME <= if inclusive
if start + index < end {
Ok(ValueObj::Nat(start + index))
} else {
Err(ErrorCore::new(
line!() as usize,
ErrorKind::IndexError,
Location::Unknown,
AtomicStr::from(format!("Index out of range: {}", index)),
None,
))
}
}

View file

@ -1534,6 +1534,7 @@ impl Context {
// range.register_superclass(Obj, &obj);
range.register_superclass(Type, &type_);
range.register_marker_trait(poly("Output", vec![ty_tp(mono_q("T"))]));
range.register_marker_trait(poly("Seq", vec![ty_tp(mono_q("T"))]));
let mut range_eq = Self::builtin_methods(Some(poly("Eq", vec![ty_tp(range_t.clone())])), 2);
range_eq.register_builtin_impl(
"__eq__",
@ -1551,6 +1552,15 @@ impl Context {
Public,
);
range.register_trait(range_t.clone(), range_iterable);
let range_getitem_t = fn1_kw_met(range_t.clone(), anon(mono_q("T")), mono_q("T"));
let range_getitem_t = quant(range_getitem_t, set! { static_instance("T", Type) });
let get_item = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new(
"__getitem__",
__range_getitem__,
range_getitem_t,
None,
)));
range.register_builtin_const("__getitem__", Public, get_item);
/* Proc */
let mut proc = Self::builtin_mono_class("Proc", 2);
proc.register_superclass(Obj, &obj);

View file

@ -1104,6 +1104,21 @@ impl Context {
self.sub_unify_tp(lhs, lhs2, variance, loc, allow_divergence)?;
self.sub_unify_tp(rhs, rhs2, variance, loc, allow_divergence)
}
(l, TyParam::Erased(t)) => {
let sub_t = self.get_tp_t(l)?;
if self.subtype_of(&sub_t, t) {
Ok(())
} else {
Err(TyCheckErrors::from(TyCheckError::subtyping_error(
self.cfg.input.clone(),
line!() as usize,
&sub_t,
t,
loc,
self.caused_by(),
)))
}
}
(l, r) => panic!("type-parameter unification failed:\nl:{l}\nr: {r}"),
}
}
@ -1123,6 +1138,10 @@ impl Context {
*l.borrow_mut() = r.clone();
Ok(())
}
/*(TyParam::Value(ValueObj::Mut(l)), TyParam::Erased(_)) => {
*l.borrow_mut() = after.clone();
Ok(())
}*/
(TyParam::Type(l), TyParam::Type(r)) => self.reunify(l, r, loc),
(TyParam::UnaryOp { op: lop, val: lval }, TyParam::UnaryOp { op: rop, val: rval })
if lop == rop =>