From 9f85c88e7ed918f4741366e59eef2dd68196539f Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Mon, 24 Oct 2022 14:32:34 +0900 Subject: [PATCH] WIP --- compiler/erg_compiler/context/compare.rs | 4 +- compiler/erg_compiler/context/eval.rs | 2 +- .../erg_compiler/context/initialize/mod.rs | 14 ++--- compiler/erg_compiler/context/instantiate.rs | 54 ++++++++++--------- compiler/erg_compiler/context/mod.rs | 11 ++-- compiler/erg_compiler/context/test.rs | 4 +- compiler/erg_compiler/context/tyvar.rs | 8 +-- 7 files changed, 53 insertions(+), 44 deletions(-) diff --git a/compiler/erg_compiler/context/compare.rs b/compiler/erg_compiler/context/compare.rs index f1175cb3..d462792d 100644 --- a/compiler/erg_compiler/context/compare.rs +++ b/compiler/erg_compiler/context/compare.rs @@ -628,7 +628,7 @@ impl Context { // REVIEW: maybe this should be `unreachable` let tmp_tv_ctx = TyVarInstContext::new(self.level, q.bounds.clone(), self); let q_callable = self - .instantiate_t( + .instantiate_t_inner( q.unbound_callable.as_ref().clone(), &tmp_tv_ctx, Location::Unknown, @@ -640,7 +640,7 @@ impl Context { // REVIEW: maybe this should be `unreachable` let tmp_tv_ctx = TyVarInstContext::new(self.level, q.bounds.clone(), self); let q_callable = self - .instantiate_t( + .instantiate_t_inner( q.unbound_callable.as_ref().clone(), &tmp_tv_ctx, Location::Unknown, diff --git a/compiler/erg_compiler/context/eval.rs b/compiler/erg_compiler/context/eval.rs index 0a3bed62..66f340b4 100644 --- a/compiler/erg_compiler/context/eval.rs +++ b/compiler/erg_compiler/context/eval.rs @@ -175,7 +175,7 @@ impl<'c> SubstContext<'c> { pub fn substitute(&self, quant_t: Type) -> TyCheckResult { let tv_ctx = TyVarInstContext::new(self.ctx.level, self.bounds.clone(), self.ctx); - let inst = self.ctx.instantiate_t(quant_t, &tv_ctx, self.loc)?; + let inst = self.ctx.instantiate_t_inner(quant_t, &tv_ctx, self.loc)?; for param in inst.typarams() { self.substitute_tp(¶m)?; } diff --git a/compiler/erg_compiler/context/initialize/mod.rs b/compiler/erg_compiler/context/initialize/mod.rs index 23cb934c..f3f6c9d3 100644 --- a/compiler/erg_compiler/context/initialize/mod.rs +++ b/compiler/erg_compiler/context/initialize/mod.rs @@ -2136,15 +2136,16 @@ impl Context { PS::named_nd("P", Int), ]; let class = Type::from(&m..=&n); + let impls = poly("Add", vec![TyParam::from(&o..=&p)]); // Interval is a bounding patch connecting M..N and (Add(O..P, M+O..N..P), Sub(O..P, M-P..N-O)) - let mut interval = Self::builtin_poly_patch("Interval", class.clone(), params, 2); + let mut interval = + Self::builtin_poly_glue_patch("Interval", class.clone(), impls.clone(), params, 2); let op_t = fn1_met( class.clone(), Type::from(&o..=&p), Type::from(m.clone() + o.clone()..=n.clone() + p.clone()), ); - let mut interval_add = - Self::builtin_methods(Some(poly("Add", vec![TyParam::from(&o..=&p)])), 2); + let mut interval_add = Self::builtin_methods(Some(impls), 2); interval_add.register_builtin_impl("__add__", op_t, Const, Public); interval_add.register_builtin_const( "Output", @@ -2174,10 +2175,11 @@ impl Context { let t = mono_q("T"); let u = mono_q("U"); let base = or(t.clone(), u.clone()); + let impls = poly("Eq", vec![ty_tp(base.clone())]); let params = vec![PS::named_nd("T", Type), PS::named_nd("U", Type)]; - let mut union_eq = Self::builtin_poly_patch("UnionEq", base.clone(), params, 1); - let mut union_eq_impl = - Self::builtin_methods(Some(poly("Eq", vec![ty_tp(base.clone())])), 1); + let mut union_eq = + Self::builtin_poly_glue_patch("UnionEq", base.clone(), impls.clone(), params, 1); + let mut union_eq_impl = Self::builtin_methods(Some(impls), 1); let op_t = fn1_met(base.clone(), base.clone(), Bool); let op_t = quant( op_t, diff --git a/compiler/erg_compiler/context/instantiate.rs b/compiler/erg_compiler/context/instantiate.rs index 0daf788c..d6ff42ff 100644 --- a/compiler/erg_compiler/context/instantiate.rs +++ b/compiler/erg_compiler/context/instantiate.rs @@ -730,7 +730,7 @@ impl Context { other if simple.args.is_empty() => { if let Some(tmp_tv_ctx) = tmp_tv_ctx { if let Ok(t) = - self.instantiate_t(mono_q(Str::rc(other)), tmp_tv_ctx, simple.loc()) + self.instantiate_t_inner(mono_q(Str::rc(other)), tmp_tv_ctx, simple.loc()) { return Ok(t); } @@ -1190,14 +1190,14 @@ impl Context { }*/ // 'T -> ?T if t.is_mono_q() { - let t = self.instantiate_t(*t, tmp_tv_ctx, loc)?; + let t = self.instantiate_t_inner(*t, tmp_tv_ctx, loc)?; Ok(TyParam::t(t)) } // K('U) -> K(?U) else { let ctx = self.get_nominal_type_ctx(&t).unwrap(); let tv_ctx = TyVarInstContext::new(self.level, ctx.bounds(), self); - let t = self.instantiate_t(*t, &tv_ctx, loc)?; + let t = self.instantiate_t_inner(*t, &tv_ctx, loc)?; Ok(TyParam::t(t)) } } @@ -1213,7 +1213,7 @@ impl Context { } /// 'T -> ?T (quantified to free) - pub(crate) fn instantiate_t( + pub(crate) fn instantiate_t_inner( &self, unbound: Type, tmp_tv_ctx: &TyVarInstContext, @@ -1254,7 +1254,7 @@ impl Context { Ok(poly_q(name, params)) } Refinement(mut refine) => { - refine.t = Box::new(self.instantiate_t(*refine.t, tmp_tv_ctx, loc)?); + refine.t = Box::new(self.instantiate_t_inner(*refine.t, tmp_tv_ctx, loc)?); let mut new_preds = set! {}; for mut pred in refine.preds.into_iter() { for tp in pred.typarams_mut() { @@ -1267,16 +1267,18 @@ impl Context { } Subr(mut subr) => { for pt in subr.non_default_params.iter_mut() { - *pt.typ_mut() = self.instantiate_t(mem::take(pt.typ_mut()), tmp_tv_ctx, loc)?; + *pt.typ_mut() = + self.instantiate_t_inner(mem::take(pt.typ_mut()), tmp_tv_ctx, loc)?; } if let Some(var_args) = subr.var_params.as_mut() { *var_args.typ_mut() = - self.instantiate_t(mem::take(var_args.typ_mut()), tmp_tv_ctx, loc)?; + self.instantiate_t_inner(mem::take(var_args.typ_mut()), tmp_tv_ctx, loc)?; } for pt in subr.default_params.iter_mut() { - *pt.typ_mut() = self.instantiate_t(mem::take(pt.typ_mut()), tmp_tv_ctx, loc)?; + *pt.typ_mut() = + self.instantiate_t_inner(mem::take(pt.typ_mut()), tmp_tv_ctx, loc)?; } - let return_t = self.instantiate_t(*subr.return_t, tmp_tv_ctx, loc)?; + let return_t = self.instantiate_t_inner(*subr.return_t, tmp_tv_ctx, loc)?; let res = subr_t( subr.kind, subr.non_default_params, @@ -1288,23 +1290,23 @@ impl Context { } Record(mut dict) => { for v in dict.values_mut() { - *v = self.instantiate_t(mem::take(v), tmp_tv_ctx, loc)?; + *v = self.instantiate_t_inner(mem::take(v), tmp_tv_ctx, loc)?; } Ok(Type::Record(dict)) } Ref(t) => { - let t = self.instantiate_t(*t, tmp_tv_ctx, loc)?; + let t = self.instantiate_t_inner(*t, tmp_tv_ctx, loc)?; Ok(ref_(t)) } RefMut { before, after } => { - let before = self.instantiate_t(*before, tmp_tv_ctx, loc)?; + let before = self.instantiate_t_inner(*before, tmp_tv_ctx, loc)?; let after = after - .map(|aft| self.instantiate_t(*aft, tmp_tv_ctx, loc)) + .map(|aft| self.instantiate_t_inner(*aft, tmp_tv_ctx, loc)) .transpose()?; Ok(ref_mut(before, after)) } Proj { lhs, rhs } => { - let lhs = self.instantiate_t(*lhs, tmp_tv_ctx, loc)?; + let lhs = self.instantiate_t_inner(*lhs, tmp_tv_ctx, loc)?; Ok(proj(lhs, rhs)) } ProjCall { @@ -1328,29 +1330,29 @@ impl Context { panic!("a quantified type should not be instantiated, instantiate the inner type") } FreeVar(fv) if fv.is_linked() => { - self.instantiate_t(fv.crack().clone(), tmp_tv_ctx, loc) + self.instantiate_t_inner(fv.crack().clone(), tmp_tv_ctx, loc) } FreeVar(fv) => { let (sub, sup) = fv.get_bound_types().unwrap(); - let sub = self.instantiate_t(sub, tmp_tv_ctx, loc)?; - let sup = self.instantiate_t(sup, tmp_tv_ctx, loc)?; + let sub = self.instantiate_t_inner(sub, tmp_tv_ctx, loc)?; + let sup = self.instantiate_t_inner(sup, tmp_tv_ctx, loc)?; let new_constraint = Constraint::new_sandwiched(sub, sup, fv.cyclicity()); fv.update_constraint(new_constraint); Ok(FreeVar(fv)) } And(l, r) => { - let l = self.instantiate_t(*l, tmp_tv_ctx, loc)?; - let r = self.instantiate_t(*r, tmp_tv_ctx, loc)?; + let l = self.instantiate_t_inner(*l, tmp_tv_ctx, loc)?; + let r = self.instantiate_t_inner(*r, tmp_tv_ctx, loc)?; Ok(self.intersection(&l, &r)) } Or(l, r) => { - let l = self.instantiate_t(*l, tmp_tv_ctx, loc)?; - let r = self.instantiate_t(*r, tmp_tv_ctx, loc)?; + let l = self.instantiate_t_inner(*l, tmp_tv_ctx, loc)?; + let r = self.instantiate_t_inner(*r, tmp_tv_ctx, loc)?; Ok(self.union(&l, &r)) } Not(l, r) => { - let l = self.instantiate_t(*l, tmp_tv_ctx, loc)?; - let r = self.instantiate_t(*r, tmp_tv_ctx, loc)?; + let l = self.instantiate_t_inner(*l, tmp_tv_ctx, loc)?; + let r = self.instantiate_t_inner(*r, tmp_tv_ctx, loc)?; Ok(not(l, r)) } other if other.is_monomorphic() => Ok(other), @@ -1362,7 +1364,8 @@ impl Context { match quantified { Quantified(quant) => { let tmp_tv_ctx = TyVarInstContext::new(self.level, quant.bounds, self); - let t = self.instantiate_t(*quant.unbound_callable, &tmp_tv_ctx, callee.loc())?; + let t = + self.instantiate_t_inner(*quant.unbound_callable, &tmp_tv_ctx, callee.loc())?; match &t { Type::Subr(subr) => { if let Some(self_t) = subr.self_t() { @@ -1385,7 +1388,8 @@ impl Context { Refinement(refine) if refine.t.is_quantified() => { let quant = enum_unwrap!(*refine.t, Type::Quantified); let tmp_tv_ctx = TyVarInstContext::new(self.level, quant.bounds, self); - let t = self.instantiate_t(*quant.unbound_callable, &tmp_tv_ctx, callee.loc())?; + let t = + self.instantiate_t_inner(*quant.unbound_callable, &tmp_tv_ctx, callee.loc())?; match &t { Type::Subr(subr) => { if let Some(self_t) = subr.self_t() { diff --git a/compiler/erg_compiler/context/mod.rs b/compiler/erg_compiler/context/mod.rs index a9d18274..3085e64e 100644 --- a/compiler/erg_compiler/context/mod.rs +++ b/compiler/erg_compiler/context/mod.rs @@ -700,9 +700,10 @@ impl Context { #[allow(clippy::too_many_arguments)] #[inline] - pub fn poly_patch>( + pub fn poly_glue_patch>( name: S, base: Type, + impls: Type, params: Vec, cfg: ErgConfig, mod_cache: Option, @@ -713,7 +714,7 @@ impl Context { Self::poly( name.into(), cfg, - ContextKind::Patch(base), + ContextKind::GluePatch(TraitInstance::new(base, impls)), params, None, mod_cache, @@ -724,15 +725,17 @@ impl Context { } #[inline] - pub fn builtin_poly_patch>( + pub fn builtin_poly_glue_patch>( name: S, base: Type, + impls: Type, params: Vec, capacity: usize, ) -> Self { - Self::poly_patch( + Self::poly_glue_patch( name, base, + impls, params, ErgConfig::default(), None, diff --git a/compiler/erg_compiler/context/test.rs b/compiler/erg_compiler/context/test.rs index 282e2002..6311d8c3 100644 --- a/compiler/erg_compiler/context/test.rs +++ b/compiler/erg_compiler/context/test.rs @@ -57,7 +57,7 @@ impl Context { let tv_ctx = TyVarInstContext::new(self.level + 1, bounds, self); println!("tv_ctx: {tv_ctx}"); let inst = self - .instantiate_t(unbound_t, &tv_ctx, Location::Unknown) + .instantiate_t_inner(unbound_t, &tv_ctx, Location::Unknown) .map_err(|_| ())?; println!("inst: {inst}"); let quantified_again = self.generalize_t(inst); @@ -66,7 +66,7 @@ impl Context { let unbound_t = *enum_unwrap!(quantified_again, Type::Quantified).unbound_callable; // 同じtv_ctxで2回instantiateしないこと let inst = self - .instantiate_t(unbound_t, &tv_ctx, Location::Unknown) + .instantiate_t_inner(unbound_t, &tv_ctx, Location::Unknown) .map_err(|_| ())?; // (?T(<: Eq('T))[2]) -> ?T(<: Eq('T))[2] println!("inst: {inst}"); let quantified_again = self.generalize_t(inst); diff --git a/compiler/erg_compiler/context/tyvar.rs b/compiler/erg_compiler/context/tyvar.rs index 12de3faa..50af53ef 100644 --- a/compiler/erg_compiler/context/tyvar.rs +++ b/compiler/erg_compiler/context/tyvar.rs @@ -171,14 +171,14 @@ impl Context { // the input type of `is_class` must not be quantified (if the type is Proj). So instantiate it here. let l = if l.has_qvar() { let tv_ctx = TyVarInstContext::new(self.level, bounds.clone(), self); - self.instantiate_t(l.clone(), &tv_ctx, Location::Unknown) + self.instantiate_t_inner(l.clone(), &tv_ctx, Location::Unknown) .unwrap() } else { l.clone() }; let r = if r.has_qvar() { let tv_ctx = TyVarInstContext::new(self.level, bounds.clone(), self); - self.instantiate_t(r.clone(), &tv_ctx, Location::Unknown) + self.instantiate_t_inner(r.clone(), &tv_ctx, Location::Unknown) .unwrap() } else { r.clone() @@ -637,7 +637,7 @@ impl Context { let sub_type = if inst.sub_type.has_qvar() { let sub_ctx = self.get_nominal_type_ctx(&inst.sub_type).unwrap(); let tv_ctx = TyVarInstContext::new(self.level, sub_ctx.bounds(), self); - self.instantiate_t(inst.sub_type, &tv_ctx, Location::Unknown) + self.instantiate_t_inner(inst.sub_type, &tv_ctx, Location::Unknown) .unwrap() } else { inst.sub_type @@ -645,7 +645,7 @@ impl Context { let sup_trait = if inst.sup_trait.has_qvar() { let sup_ctx = self.get_nominal_type_ctx(&inst.sup_trait).unwrap(); let tv_ctx = TyVarInstContext::new(self.level, sup_ctx.bounds(), self); - self.instantiate_t(inst.sup_trait, &tv_ctx, Location::Unknown) + self.instantiate_t_inner(inst.sup_trait, &tv_ctx, Location::Unknown) .unwrap() } else { inst.sup_trait