WIP: trait implementation

This commit is contained in:
Shunsuke Shibayama 2022-09-17 20:39:13 +09:00
parent 3b7eebe041
commit abb6bcd320
7 changed files with 23 additions and 10 deletions

View file

@ -423,6 +423,7 @@ impl Context {
default_params.clone(),
enum_t(set![return_t.clone()]),
);
let sig_t = self.generalize_t(sig_t);
let as_type = subr_t(
SubrKind::from(lambda.op.kind),
non_default_params,
@ -430,6 +431,7 @@ impl Context {
default_params,
return_t.as_type().ok_or_else(|| todo!())?.into_typ(),
);
let as_type = self.generalize_t(as_type);
let subr = ConstSubr::User(UserConstSubr::new(
Str::ever("<lambda>"),
lambda.sig.params.clone(),

View file

@ -81,6 +81,12 @@ impl Context {
unique_in_place(&mut self.super_traits);
}
pub(crate) fn register_supertrait(&mut self, sup: Type, sup_ctx: &Context) {
self.super_traits.push(sup);
self.super_traits.extend(sup_ctx.super_traits.clone());
unique_in_place(&mut self.super_traits);
}
fn register_builtin_type(&mut self, t: Type, ctx: Self, muty: Mutability) {
if t.typarams_len().is_none() {
self.register_mono_type(t, ctx, muty);

View file

@ -390,7 +390,6 @@ impl Context {
) -> TyCheckResult<Type> {
let bounds = self.instantiate_ty_bounds(&sig.bounds, PreRegister)?;
let mut tv_ctx = TyVarContext::new(self.level, bounds, self);
erg_common::log!(err "{sig}, {tv_ctx}");
let non_defaults = sig
.params
.non_defaults

View file

@ -670,7 +670,7 @@ impl Context {
let mut ctx = Self::mono_trait(gen.t.name(), self.level);
for sup in super_classes.into_iter() {
let (_, sup_ctx) = self.get_nominal_type_ctx(&sup).unwrap();
ctx.register_superclass(sup, sup_ctx);
ctx.register_supertrait(sup, sup_ctx);
}
self.register_gen_mono_type(ident, gen, ctx, Const);
} else {

View file

@ -6,7 +6,7 @@ use erg_common::error::Location;
use erg_common::set::Set;
use erg_common::traits::{Locational, Stream};
use erg_common::Str;
use erg_common::{assume_unreachable, fn_name, set};
use erg_common::{assume_unreachable, fn_name, log, set};
use erg_type::constructors::*;
use erg_type::free::{Constraint, Cyclicity, FreeKind};
@ -41,7 +41,6 @@ impl Context {
match free {
TyParam::Type(t) => TyParam::t(self.generalize_t_inner(*t, bounds, lazy_inits)),
TyParam::FreeVar(v) if v.is_linked() => {
erg_common::log!(err "borrow mut");
if let FreeKind::Linked(tp) = &mut *v.borrow_mut() {
*tp = self.generalize_tp(tp.clone(), bounds, lazy_inits);
} else {
@ -96,7 +95,6 @@ impl Context {
) -> Type {
match free_type {
FreeVar(v) if v.is_linked() => {
erg_common::log!(err "borrow mut");
if let FreeKind::Linked(t) = &mut *v.borrow_mut() {
*t = self.generalize_t_inner(t.clone(), bounds, lazy_inits);
} else {
@ -789,7 +787,7 @@ impl Context {
sup_loc: Option<Location>,
param_name: Option<&Str>,
) -> TyCheckResult<()> {
erg_common::log!(info "trying sub_unify:\nmaybe_sub: {maybe_sub}\nmaybe_sup: {maybe_sup}");
log!(info "trying sub_unify:\nmaybe_sub: {maybe_sub}\nmaybe_sup: {maybe_sup}");
// In this case, there is no new information to be gained
// この場合、特に新しく得られる情報はない
if maybe_sub == &Type::Never || maybe_sup == &Type::Obj || maybe_sup == maybe_sub {

View file

@ -863,6 +863,15 @@ impl ASTLowerer {
methods: &Context,
) -> LowerResult<()> {
if let Some((impl_trait, loc)) = impl_trait {
// assume the class has implemented the trait, regardless of whether the implementation is correct
let trait_ctx = self
.ctx
.get_nominal_type_ctx(&impl_trait)
.unwrap()
.1
.clone();
let (_, class_ctx) = self.ctx.get_mut_nominal_type_ctx(class).unwrap();
class_ctx.register_supertrait(impl_trait.clone(), &trait_ctx);
if let Some(trait_obj) = self.ctx.rec_get_const_obj(&impl_trait.name()) {
if let ValueObj::Type(typ) = trait_obj {
match typ {
@ -872,9 +881,8 @@ impl ASTLowerer {
methods.locals.keys().collect::<Set<_>>();
for (field, typ) in attrs.iter() {
if let Some((name, vi)) = methods.get_local_kv(&field.symbol) {
if self.ctx.supertype_of(typ, &vi.t) {
unverified_names.remove(name);
} else {
unverified_names.remove(name);
if !self.ctx.supertype_of(typ, &vi.t) {
self.errs.push(LowerError::trait_member_type_error(
line!() as usize,
name.loc(),