fix: trait registering bugs

This commit is contained in:
Shunsuke Shibayama 2023-08-12 19:05:00 +09:00
parent bb3e3d9b96
commit 4f93c393c0
6 changed files with 58 additions and 15 deletions

View file

@ -19,8 +19,8 @@ use erg_parser::desugar::Desugarer;
use erg_parser::token::{Token, TokenKind};
use crate::ty::constructors::{
array_t, dict_t, mono, poly, proj, proj_call, ref_, ref_mut, refinement, set_t, subr_t,
tp_enum, tuple_t, v_enum,
array_t, dict_t, mono, named_free_var, poly, proj, proj_call, ref_, ref_mut, refinement, set_t,
subr_t, tp_enum, tuple_t, v_enum,
};
use crate::ty::free::{Constraint, FreeTyVar, HasLevel};
use crate::ty::typaram::{OpKind, TyParam};
@ -344,7 +344,7 @@ impl<'c> Substituter<'c> {
Ok(())
}
pub(crate) fn undo_substitute_typarams(substituted_q: &Type) {
fn undo_substitute_typarams(substituted_q: &Type) {
for tp in substituted_q.typarams().into_iter() {
Self::undo_substitute_typaram(tp);
}
@ -1697,6 +1697,12 @@ impl Context {
Ok(Type::from(kvs))
}
TyParam::FreeVar(fv) if fv.is_linked() => self.convert_tp_into_type(fv.crack().clone()),
// TyParam(Ts: Array(Type)) -> Type(Ts: Array(Type))
TyParam::FreeVar(fv) if fv.get_type().is_some() => Ok(named_free_var(
fv.unbound_name().unwrap(),
fv.level().unwrap(),
fv.constraint().unwrap(),
)),
TyParam::Type(t) => Ok(t.as_ref().clone()),
TyParam::Mono(name) => Ok(Type::Mono(name)),
TyParam::App { name, args } => Ok(Type::Poly { name, params: args }),
@ -1954,7 +1960,7 @@ impl Context {
/// e.g.
/// F((Int), 3) => F(Int, 3)
/// F(?T, ?T) => F(?1, ?1)
fn detach(&self, ty: Type, tv_cache: &mut TyVarCache) -> Type {
pub(crate) fn detach(&self, ty: Type, tv_cache: &mut TyVarCache) -> Type {
match ty {
Type::FreeVar(fv) if fv.is_linked() => self.detach(fv.crack().clone(), tv_cache),
Type::FreeVar(fv) => {

View file

@ -164,15 +164,14 @@ impl Context {
Visibility::BUILTIN_PUBLIC,
);
float.register_marker_trait(self, mono(NUM)).unwrap();
float.register_marker_trait(self, mono(ORD)).unwrap();
let mut float_ord = Self::builtin_methods(Some(mono(ORD)), 2);
float_ord.register_builtin_erg_impl(
let mut float_partial_ord = Self::builtin_methods(Some(mono(PARTIAL_ORD)), 2);
float_partial_ord.register_builtin_erg_impl(
OP_CMP,
fn1_met(Float, Float, mono(ORDERING)),
Const,
Visibility::BUILTIN_PUBLIC,
);
float.register_trait(Float, float_ord);
float.register_trait(Float, float_partial_ord);
// Float doesn't have an `Eq` implementation
let op_t = fn1_met(Float, Float, Float);
let mut float_add = Self::builtin_methods(Some(poly(ADD, vec![ty_tp(Float)])), 2);
@ -1320,6 +1319,7 @@ impl Context {
array_
.register_marker_trait(self, poly(SEQUENCE, vec![ty_tp(T.clone())]))
.unwrap();
array_.unregister_trait(&poly(INDEXABLE, vec![ty_tp(Nat), ty_tp(T.clone())]));
let mut array_show = Self::builtin_methods(Some(mono(SHOW)), 1);
array_show.register_builtin_py_impl(
TO_STR,

View file

@ -691,7 +691,7 @@ impl Context {
let op_t = bin_op(E.clone(), E, Bool).quantify();
self.register_builtin_erg_impl(OP_EQ, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);
self.register_builtin_erg_impl(OP_NE, op_t, Const, Visibility::BUILTIN_PRIVATE);
let O = mono_q(TY_O, subtypeof(mono(ORD)));
let O = mono_q(TY_O, subtypeof(mono(PARTIAL_ORD)));
let op_t = bin_op(O.clone(), O.clone(), Bool).quantify();
self.register_builtin_erg_impl(OP_LT, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);
self.register_builtin_erg_impl(OP_LE, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE);

View file

@ -98,6 +98,7 @@ const MAPPING: &str = "Mapping";
const MUTABLE_MAPPING: &str = "Mapping!";
const SHAPE: &str = "Shape";
const EQ: &str = "Eq";
const PARTIAL_ORD: &str = "PartialOrd";
const ORD: &str = "Ord";
const TO_STR: &str = "to_str";
const ORDERING: &str = "Ordering";

View file

@ -196,8 +196,14 @@ impl Context {
// __eq__: |Self <: Eq| (self: Self, other: Self) -> Bool
let op_t = fn1_met(Slf.clone(), Slf, Bool).quantify();
eq.register_builtin_erg_decl(OP_EQ, op_t, Visibility::BUILTIN_PUBLIC);
/* PartialOrd */
let mut partial_ord = Self::builtin_mono_trait(PARTIAL_ORD, 2);
let Slf = mono_q(SELF, subtypeof(mono(PARTIAL_ORD)));
let op_t = fn1_met(Slf.clone(), Slf, or(mono(ORDERING), NoneType)).quantify();
partial_ord.register_builtin_erg_decl(OP_CMP, op_t, Visibility::BUILTIN_PUBLIC);
/* Ord */
let mut ord = Self::builtin_mono_trait(ORD, 2);
ord.register_superclass(mono(PARTIAL_ORD), &partial_ord);
ord.register_superclass(mono(EQ), &eq);
let Slf = mono_q(SELF, subtypeof(mono(ORD)));
let op_t = fn1_met(Slf.clone(), Slf, or(mono(ORDERING), NoneType)).quantify();
@ -473,6 +479,7 @@ impl Context {
None,
);
self.register_builtin_type(mono(EQ), eq, vis.clone(), Const, None);
self.register_builtin_type(mono(PARTIAL_ORD), partial_ord, vis.clone(), Const, None);
self.register_builtin_type(mono(ORD), ord, vis.clone(), Const, None);
self.register_builtin_type(mono(NUM), num, vis.clone(), Const, None);
self.register_builtin_type(

View file

@ -18,7 +18,7 @@ use erg_common::pathutil::{DirKind, FileKind};
use erg_common::python_util::BUILTIN_PYTHON_MODS;
use erg_common::set::Set;
use erg_common::spawn::spawn_new_thread;
use erg_common::traits::{Locational, Stream};
use erg_common::traits::{Locational, Stream, StructuralEq};
use erg_common::triple::Triple;
use erg_common::{dict, get_hash, log, set, unique_in_place, Str};
@ -50,6 +50,7 @@ use crate::{feature_error, hir};
use Mutability::*;
use RegistrationMode::*;
use super::eval::Substituter;
use super::instantiate::TyVarCache;
use super::instantiate_spec::ParamKind;
use super::{ModuleContext, ParamSpec};
@ -1221,7 +1222,7 @@ impl Context {
}
pub(crate) fn register_marker_trait(&mut self, ctx: &Self, trait_: Type) -> CompileResult<()> {
let (_, trait_ctx) = ctx.get_nominal_type_ctx(&trait_).ok_or_else(|| {
let (typ, trait_ctx) = ctx.get_nominal_type_ctx(&trait_).ok_or_else(|| {
CompileError::type_not_found(
self.cfg.input.clone(),
line!() as usize,
@ -1230,14 +1231,42 @@ impl Context {
&trait_,
)
})?;
// self.register_supertrait(trait_, ctx);
let traits = trait_ctx.super_traits.clone();
self.super_traits.push(trait_);
self.super_traits.extend(traits);
if typ.has_qvar() {
let _substituter = Substituter::substitute_typarams(ctx, typ, &trait_)?;
self.super_traits.push(trait_);
let mut tv_cache = TyVarCache::new(ctx.level, ctx);
let traits = trait_ctx.super_classes.iter().cloned().map(|ty| {
if ty.has_undoable_linked_var() {
ctx.detach(ty, &mut tv_cache)
} else {
ty
}
});
self.super_traits.extend(traits);
let traits = trait_ctx.super_traits.iter().cloned().map(|ty| {
if ty.has_undoable_linked_var() {
ctx.detach(ty, &mut tv_cache)
} else {
ty
}
});
self.super_traits.extend(traits);
} else {
self.super_traits.push(trait_);
let traits = trait_ctx.super_classes.clone();
self.super_traits.extend(traits);
let traits = trait_ctx.super_traits.clone();
self.super_traits.extend(traits);
}
unique_in_place(&mut self.super_traits);
Ok(())
}
pub(crate) fn unregister_trait(&mut self, trait_: &Type) {
self.super_traits.retain(|t| !t.structural_eq(trait_));
// .retain(|t| !ctx.same_type_of(t, trait_));
}
pub(crate) fn register_gen_const(
&mut self,
ident: &Identifier,