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

@ -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);