Unify poly_classes and poly_traits of Context

This commit is contained in:
Shunsuke Shibayama 2022-09-03 12:07:27 +09:00
parent e1eebb252f
commit 618f73f0c0
4 changed files with 10 additions and 48 deletions

View file

@ -71,13 +71,7 @@ impl Context {
if t.typarams_len().is_none() { if t.typarams_len().is_none() {
self.register_mono_type(t, ctx, muty); self.register_mono_type(t, ctx, muty);
} else { } else {
if t.is_class() { self.register_poly_type(t, ctx, muty);
self.register_poly_class(t, ctx, muty);
} else if t.is_trait() {
self.register_poly_trait(t, ctx, muty);
} else {
todo!()
}
} }
} }
@ -103,10 +97,10 @@ impl Context {
} }
} }
fn register_poly_class(&mut self, t: Type, ctx: Self, muty: Mutability) { fn register_poly_type(&mut self, t: Type, ctx: Self, muty: Mutability) {
let mut tv_ctx = TyVarContext::new(self.level, ctx.type_params_bounds(), self); let mut tv_ctx = TyVarContext::new(self.level, ctx.type_params_bounds(), self);
let t = Self::instantiate_t(t, &mut tv_ctx); let t = Self::instantiate_t(t, &mut tv_ctx);
if let Some((_, root_ctx)) = self.poly_classes.get_mut(&t.name()) { if let Some((_, root_ctx)) = self.poly_types.get_mut(&t.name()) {
root_ctx.specializations.push((t, ctx)); root_ctx.specializations.push((t, ctx));
} else { } else {
let name = VarName::from_str(t.name()); let name = VarName::from_str(t.name());
@ -123,31 +117,7 @@ impl Context {
); );
} }
} }
self.poly_classes.insert(name, (t, ctx)); self.poly_types.insert(name, (t, ctx));
}
}
fn register_poly_trait(&mut self, t: Type, ctx: Self, muty: Mutability) {
if self.poly_traits.contains_key(&t.name()) {
panic!("{} has already been registered", t.name());
} else {
let mut tv_ctx = TyVarContext::new(self.level, ctx.type_params_bounds(), self);
let t = Self::instantiate_t(t, &mut tv_ctx);
let name = VarName::from_str(t.name());
self.locals
.insert(name.clone(), VarInfo::new(Type, muty, Private, Builtin));
self.consts.insert(name.clone(), ValueObj::t(t.clone()));
for impl_trait in ctx.super_traits.iter() {
if let Some(impls) = self.trait_impls.get_mut(&impl_trait.name()) {
impls.push(TraitInstance::new(t.clone(), impl_trait.clone()));
} else {
self.trait_impls.insert(
impl_trait.name(),
vec![TraitInstance::new(t.clone(), impl_trait.clone())],
);
}
}
self.poly_traits.insert(name, (t, ctx));
} }
} }

View file

@ -1000,13 +1000,8 @@ impl Context {
Type::Quantified(_) => { Type::Quantified(_) => {
return self.rec_get_nominal_type_ctx(&class("QuantifiedFunction")); return self.rec_get_nominal_type_ctx(&class("QuantifiedFunction"));
} }
Type::PolyClass { name, params: _ } => { Type::PolyClass { name, params: _ } | Type::PolyTrait { name, params: _ } => {
if let Some((t, ctx)) = self.poly_classes.get(name) { if let Some((t, ctx)) = self.poly_types.get(name) {
return Some((t, ctx));
}
}
Type::PolyTrait { name, params: _ } => {
if let Some((t, ctx)) = self.poly_traits.get(name) {
return Some((t, ctx)); return Some((t, ctx));
} }
} }

View file

@ -258,9 +258,7 @@ pub struct Context {
// Implementation Contexts for Polymorphic Types // Implementation Contexts for Polymorphic Types
// Vec<TyParam> are specialization parameters // Vec<TyParam> are specialization parameters
// e.g. {"Array": [(Array(Nat), ctx), (Array(Int), ctx), (Array(Str), ctx), (Array(Obj), ctx), (Array('T), ctx)], ...} // e.g. {"Array": [(Array(Nat), ctx), (Array(Int), ctx), (Array(Str), ctx), (Array(Obj), ctx), (Array('T), ctx)], ...}
pub(crate) poly_classes: Dict<VarName, (Type, Context)>, pub(crate) poly_types: Dict<VarName, (Type, Context)>,
// Traits cannot be specialized
pub(crate) poly_traits: Dict<VarName, (Type, Context)>,
// patches can be accessed like normal records // patches can be accessed like normal records
// but when used as a fallback to a type, values are traversed instead of accessing by keys // but when used as a fallback to a type, values are traversed instead of accessing by keys
pub(crate) patches: Dict<VarName, Context>, pub(crate) patches: Dict<VarName, Context>,
@ -295,7 +293,7 @@ impl fmt::Display for Context {
.field("locals", &self.params) .field("locals", &self.params)
.field("consts", &self.consts) .field("consts", &self.consts)
.field("mono_types", &self.mono_types) .field("mono_types", &self.mono_types)
.field("poly_types", &self.poly_classes) .field("poly_types", &self.poly_types)
.field("patches", &self.patches) .field("patches", &self.patches)
.field("mods", &self.mods) .field("mods", &self.mods)
.finish() .finish()
@ -368,8 +366,7 @@ impl Context {
locals: Dict::with_capacity(capacity), locals: Dict::with_capacity(capacity),
consts: Dict::default(), consts: Dict::default(),
mono_types: Dict::default(), mono_types: Dict::default(),
poly_classes: Dict::default(), poly_types: Dict::default(),
poly_traits: Dict::default(),
mods: Dict::default(), mods: Dict::default(),
patches: Dict::default(), patches: Dict::default(),
_nlocals: 0, _nlocals: 0,

View file

@ -535,7 +535,7 @@ impl ASTLowerer {
ast::Expr::UnaryOp(unary) => Ok(hir::Expr::UnaryOp(self.lower_unary(unary)?)), ast::Expr::UnaryOp(unary) => Ok(hir::Expr::UnaryOp(self.lower_unary(unary)?)),
ast::Expr::Call(call) => Ok(hir::Expr::Call(self.lower_call(call)?)), ast::Expr::Call(call) => Ok(hir::Expr::Call(self.lower_call(call)?)),
ast::Expr::Lambda(lambda) => Ok(hir::Expr::Lambda(self.lower_lambda(lambda)?)), ast::Expr::Lambda(lambda) => Ok(hir::Expr::Lambda(self.lower_lambda(lambda)?)),
// ast::Expr::Def(def) => Ok(hir::Expr::Def(self.lower_def(def)?)), ast::Expr::Def(def) => Ok(hir::Expr::Def(self.lower_def(def)?)),
other => todo!("{other}"), other => todo!("{other}"),
} }
} }