Skip to content

Commit

Permalink
fix: subtype relation bug
Browse files Browse the repository at this point in the history
  • Loading branch information
mtshiba committed Oct 15, 2024
1 parent ce1e5ab commit 566b9aa
Show file tree
Hide file tree
Showing 6 changed files with 220 additions and 178 deletions.
8 changes: 4 additions & 4 deletions crates/erg_compiler/context/compare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ impl Context {
None
}

fn _nominal_subtype_of<'c>(
fn _nominal_supertype_of<'c>(
&'c self,
lhs: &Type,
rhs: &Type,
Expand Down Expand Up @@ -332,7 +332,7 @@ impl Context {
if !self.is_class(lhs) || !self.is_class(rhs) {
return (Maybe, false);
}
self._nominal_subtype_of(lhs, rhs, |ty_ctx| &ty_ctx.super_classes)
self._nominal_supertype_of(lhs, rhs, |ty_ctx| &ty_ctx.super_classes)
}

// e.g. Eq(Nat) :> Nat
Expand All @@ -342,11 +342,11 @@ impl Context {
if !self.is_trait(lhs) {
return (Maybe, false);
}
let (cred, judge) = self._nominal_subtype_of(lhs, rhs, |ty_ctx| &ty_ctx.super_traits[..]);
let (cred, judge) = self._nominal_supertype_of(lhs, rhs, |ty_ctx| &ty_ctx.super_traits[..]);
if judge {
return (cred, judge);
}
self._nominal_subtype_of(lhs, rhs, |ty_ctx| &ty_ctx.super_classes[..])
self._nominal_supertype_of(lhs, rhs, |ty_ctx| &ty_ctx.super_classes[..])
}

/// lhs :> rhs?
Expand Down
13 changes: 12 additions & 1 deletion crates/erg_compiler/context/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2866,6 +2866,7 @@ impl Context {
}
}
TyParam::Type(t) => Ok(ValueObj::builtin_type(*t)),
TyParam::Failure => Ok(ValueObj::Failure),
other => self.convert_tp_into_type(other).map(ValueObj::builtin_type),
}
}
Expand All @@ -2885,6 +2886,7 @@ impl Context {
}
Type::Quantified(quant) => self.convert_singular_type_into_value(*quant),
Type::Subr(subr) => self.convert_singular_type_into_value(*subr.return_t),
Type::Failure => Ok(ValueObj::Failure),
_ => Err(typ),
}
}
Expand Down Expand Up @@ -3027,6 +3029,7 @@ impl Context {
fields: new_fields,
})
}
ValueObj::Failure => Ok(TyParam::Failure),
_ => Err(TyParam::Value(value)),
}
}
Expand Down Expand Up @@ -3072,6 +3075,7 @@ impl Context {
Err(())
}
}
Type::Failure => Ok(dict! { Failure => Failure }),
_ => Err(()),
}
}
Expand All @@ -3082,7 +3086,7 @@ impl Context {
) -> Result<Dict<ValueObj, ValueObj>, ()> {
match val {
ValueObj::Dict(dic) => Ok(dic.clone()),
ValueObj::Type(ty) if ty.typ().is_dict() || ty.typ().is_dict_mut() => {
ValueObj::Type(ty) => {
let Ok(dict) = self
.convert_type_to_dict_type(ty.typ().clone())
.map(|dict| {
Expand All @@ -3095,6 +3099,7 @@ impl Context {
};
Ok(dict)
}
ValueObj::Failure => Ok(dict! { ValueObj::Failure => ValueObj::Failure }),
_ => Err(()),
}
}
Expand Down Expand Up @@ -3140,6 +3145,8 @@ impl Context {
Err(())
}
}
// FIXME: unsized tuple
Type::Failure => Ok(vec![Type::Failure; 100]),
_ => Err(()),
}
}
Expand Down Expand Up @@ -3183,6 +3190,8 @@ impl Context {
_ => Err(old),
}
}
// FIXME: unsized list
Type::Failure => Ok(vec![ValueObj::Failure; 100]),
_ => Err(ty),
}
}
Expand All @@ -3194,6 +3203,8 @@ impl Context {
ValueObj::Type(t) => self
.convert_type_to_list(t.into_typ())
.map_err(ValueObj::builtin_type),
// FIXME: unsized list
ValueObj::Failure => Ok(vec![ValueObj::Failure; 100]),
_ => Err(val),
}
}
Expand Down
8 changes: 8 additions & 0 deletions crates/erg_compiler/context/initialize/classes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2216,6 +2216,14 @@ impl Context {
Immutable,
Visibility::BUILTIN_PUBLIC,
);
let ret = poly(DICT_ITEMS, vec![ty_tp(tuple_t(vec![Obj, Never]))]);
let dict_items_t = fn0_met(g_dict_t.clone(), ret).quantify();
generic_dict.register_builtin_erg_impl(
ITEMS,
dict_items_t,
Immutable,
Visibility::BUILTIN_PUBLIC,
);
let inner = ty_tp(tuple_t(vec![T.clone(), U.clone()]));
let t_call = func1(
poly(ITERABLE, vec![inner]),
Expand Down
29 changes: 20 additions & 9 deletions crates/erg_compiler/context/initialize/procs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,26 @@ impl Context {
} else {
mono("ContextManager")
};
let t_with = nd_proc(
vec![
kw("obj", C),
kw("proc!", nd_proc(vec![anon(T)], None, U.clone())),
],
None,
U,
)
.quantify();
let t_with = if PYTHON_MODE {
nd_proc(
vec![
kw("obj", C),
kw("proc!", nd_proc(vec![anon(T)], None, Obj.clone())),
],
None,
NoneType,
)
} else {
nd_proc(
vec![
kw("obj", C),
kw("proc!", nd_proc(vec![anon(T)], None, U.clone())),
],
None,
U,
)
.quantify()
};
self.register_builtin_py_impl(
"breakpoint!",
t_breakpoint,
Expand Down
28 changes: 18 additions & 10 deletions crates/erg_compiler/context/inquire.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ impl Context {
// NG: expr_t: Nat, union_pat_t: {1, 2}
// OK: expr_t: Int, union_pat_t: {1} or 'T
if let Err(err) = self.sub_unify(match_target_expr_t, &union_pat_t, &pos_args[0], None) {
if cfg!(feature = "debug") {
if DEBUG_MODE {
eprintln!("match error: {err}");
}
errs.push(TyCheckError::match_error(
Expand Down Expand Up @@ -1354,7 +1354,7 @@ impl Context {
if let Some(fv) = obj.ref_t().as_free() {
if let Some((_sub, sup)) = fv.get_subsup() {
// avoid recursion
*subr_t.mut_self_t().unwrap() = Never;
*subr_t.mut_self_t().unwrap() = Failure;
let vis = self
.instantiate_vis_modifier(&attr_name.vis)
.unwrap_or(VisibilityModifier::Public);
Expand Down Expand Up @@ -3379,23 +3379,27 @@ impl Context {
}
}
Type::Proj { lhs, rhs } => {
if let Ok(typ) = self.eval_proj(*lhs.clone(), rhs.clone(), self.level, &()) {
return self.get_nominal_type_ctx(&typ);
if let Ok(evaled) = self.eval_proj(*lhs.clone(), rhs.clone(), self.level, &()) {
if typ != &evaled {
return self.get_nominal_type_ctx(&evaled);
}
}
}
Type::ProjCall {
lhs,
attr_name,
args,
} => {
if let Ok(typ) = self.eval_proj_call_t(
if let Ok(evaled) = self.eval_proj_call_t(
*lhs.clone(),
attr_name.clone(),
args.clone(),
self.level,
&(),
) {
return self.get_nominal_type_ctx(&typ);
if typ != &evaled {
return self.get_nominal_type_ctx(&evaled);
}
}
}
other => {
Expand Down Expand Up @@ -3462,23 +3466,27 @@ impl Context {
}
}
Type::Proj { lhs, rhs } => {
if let Ok(typ) = self.eval_proj(*lhs.clone(), rhs.clone(), self.level, &()) {
return self.get_mut_nominal_type_ctx(&typ);
if let Ok(evaled) = self.eval_proj(*lhs.clone(), rhs.clone(), self.level, &()) {
if typ != &evaled {
return self.get_mut_nominal_type_ctx(&evaled);
}
}
}
Type::ProjCall {
lhs,
attr_name,
args,
} => {
if let Ok(typ) = self.eval_proj_call_t(
if let Ok(evaled) = self.eval_proj_call_t(
*lhs.clone(),
attr_name.clone(),
args.clone(),
self.level,
&(),
) {
return self.get_mut_nominal_type_ctx(&typ);
if typ != &evaled {
return self.get_mut_nominal_type_ctx(&evaled);
}
}
}
other => {
Expand Down
Loading

0 comments on commit 566b9aa

Please sign in to comment.