This commit is contained in:
Shunsuke Shibayama 2022-10-24 14:32:34 +09:00
parent a8a59147f9
commit 9f85c88e7e
7 changed files with 53 additions and 44 deletions

View file

@ -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,

View file

@ -175,7 +175,7 @@ impl<'c> SubstContext<'c> {
pub fn substitute(&self, quant_t: Type) -> TyCheckResult<Type> {
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(&param)?;
}

View file

@ -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,

View file

@ -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() {

View file

@ -700,9 +700,10 @@ impl Context {
#[allow(clippy::too_many_arguments)]
#[inline]
pub fn poly_patch<S: Into<Str>>(
pub fn poly_glue_patch<S: Into<Str>>(
name: S,
base: Type,
impls: Type,
params: Vec<ParamSpec>,
cfg: ErgConfig,
mod_cache: Option<SharedModuleCache>,
@ -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<S: Into<Str>>(
pub fn builtin_poly_glue_patch<S: Into<Str>>(
name: S,
base: Type,
impls: Type,
params: Vec<ParamSpec>,
capacity: usize,
) -> Self {
Self::poly_patch(
Self::poly_glue_patch(
name,
base,
impls,
params,
ErgConfig::default(),
None,

View file

@ -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);

View file

@ -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