iter 22b.2.1: add Constraint struct, Type::Forall.constraints
This commit is contained in:
@@ -79,6 +79,7 @@ pub fn install(env: &mut crate::Env) {
|
||||
"==".into(),
|
||||
Type::Forall {
|
||||
vars: vec!["a".into()],
|
||||
constraints: vec![],
|
||||
body: Box::new(Type::Fn {
|
||||
params: vec![
|
||||
Type::Var { name: "a".into() },
|
||||
@@ -112,6 +113,7 @@ pub fn install(env: &mut crate::Env) {
|
||||
"__unreachable__".into(),
|
||||
Type::Forall {
|
||||
vars: vec!["a".into()],
|
||||
constraints: vec![],
|
||||
body: Box::new(Type::Var { name: "a".into() }),
|
||||
},
|
||||
);
|
||||
|
||||
@@ -96,8 +96,9 @@ impl Subst {
|
||||
param_modes: vec![],
|
||||
ret_mode: ParamMode::Implicit,
|
||||
},
|
||||
Type::Forall { vars, body } => Type::Forall {
|
||||
Type::Forall { vars, constraints, body } => Type::Forall {
|
||||
vars: vars.clone(),
|
||||
constraints: constraints.clone(),
|
||||
body: Box::new(self.apply(body)),
|
||||
},
|
||||
}
|
||||
@@ -136,7 +137,7 @@ fn substitute_rigids(t: &Type, mapping: &BTreeMap<String, Type>) -> Type {
|
||||
param_modes: vec![],
|
||||
ret_mode: ParamMode::Implicit,
|
||||
},
|
||||
Type::Forall { vars, body } => {
|
||||
Type::Forall { vars, constraints, body } => {
|
||||
// Inner forall shadows: only substitute vars not re-bound here.
|
||||
let inner: BTreeMap<String, Type> = mapping
|
||||
.iter()
|
||||
@@ -145,6 +146,7 @@ fn substitute_rigids(t: &Type, mapping: &BTreeMap<String, Type>) -> Type {
|
||||
.collect();
|
||||
Type::Forall {
|
||||
vars: vars.clone(),
|
||||
constraints: constraints.clone(),
|
||||
body: Box::new(substitute_rigids(body, &inner)),
|
||||
}
|
||||
}
|
||||
@@ -1082,7 +1084,7 @@ fn check_fn(f: &FnDef, env: &Env) -> Result<()> {
|
||||
// with themselves. An empty `vars` list (vacuously polymorphic)
|
||||
// gets normalised to a non-polymorphic body.
|
||||
let (rigids, inner_ty): (Vec<String>, Type) = match &f.ty {
|
||||
Type::Forall { vars, body } => (vars.clone(), (**body).clone()),
|
||||
Type::Forall { vars, constraints: _, body } => (vars.clone(), (**body).clone()),
|
||||
other => (vec![], other.clone()),
|
||||
};
|
||||
|
||||
@@ -1337,7 +1339,7 @@ pub(crate) fn synth(
|
||||
Type::Fn { params, ret, effects: fx, .. } => {
|
||||
(params.clone(), (**ret).clone(), fx.clone())
|
||||
}
|
||||
Type::Forall { vars, body } => {
|
||||
Type::Forall { vars, constraints: _, body } => {
|
||||
// Defensive — Var should already have instantiated.
|
||||
let (_, body) = instantiate(vars, body, counter);
|
||||
match &body {
|
||||
@@ -1797,7 +1799,7 @@ pub(crate) fn synth(
|
||||
/// If `t` is a `Forall`, instantiate it with fresh metavars; otherwise
|
||||
/// pass through unchanged. Used at every var-resolution site.
|
||||
fn maybe_instantiate(t: Type, counter: &mut u32) -> Type {
|
||||
if let Type::Forall { vars, body } = &t {
|
||||
if let Type::Forall { vars, constraints: _, body } = &t {
|
||||
let (_, inst) = instantiate(vars, body, counter);
|
||||
inst
|
||||
} else {
|
||||
@@ -1845,8 +1847,9 @@ fn qualify_local_types(t: &Type, owner_module: &str, local_types: &IndexMap<Stri
|
||||
param_modes: vec![],
|
||||
ret_mode: ParamMode::Implicit,
|
||||
},
|
||||
Type::Forall { vars, body } => Type::Forall {
|
||||
Type::Forall { vars, constraints, body } => Type::Forall {
|
||||
vars: vars.clone(),
|
||||
constraints: constraints.clone(),
|
||||
body: Box::new(qualify_local_types(body, owner_module, local_types)),
|
||||
},
|
||||
Type::Var { .. } => t.clone(),
|
||||
@@ -2380,6 +2383,7 @@ mod tests {
|
||||
"id",
|
||||
Type::Forall {
|
||||
vars: vec!["a".into()],
|
||||
constraints: vec![],
|
||||
body: Box::new(Type::Fn {
|
||||
params: vec![Type::Var { name: "a".into() }],
|
||||
ret: Box::new(Type::Var { name: "a".into() }),
|
||||
@@ -2405,6 +2409,7 @@ mod tests {
|
||||
"id",
|
||||
Type::Forall {
|
||||
vars: vec!["a".into()],
|
||||
constraints: vec![],
|
||||
body: Box::new(Type::Fn {
|
||||
params: vec![Type::Var { name: "a".into() }],
|
||||
ret: Box::new(Type::Var { name: "a".into() }),
|
||||
@@ -2468,6 +2473,7 @@ mod tests {
|
||||
"id",
|
||||
Type::Forall {
|
||||
vars: vec!["a".into()],
|
||||
constraints: vec![],
|
||||
body: Box::new(Type::Fn {
|
||||
params: vec![Type::Var { name: "a".into() }],
|
||||
ret: Box::new(Type::Var { name: "a".into() }),
|
||||
@@ -2516,6 +2522,7 @@ mod tests {
|
||||
"apply",
|
||||
Type::Forall {
|
||||
vars: vec!["a".into(), "b".into()],
|
||||
constraints: vec![],
|
||||
body: Box::new(Type::Fn {
|
||||
params: vec![
|
||||
Type::Fn {
|
||||
@@ -2649,6 +2656,7 @@ mod tests {
|
||||
name: "unbox".into(),
|
||||
ty: Type::Forall {
|
||||
vars: vec!["a".into()],
|
||||
constraints: vec![],
|
||||
body: Box::new(Type::Fn {
|
||||
params: vec![Type::Con {
|
||||
name: "Box".into(),
|
||||
@@ -3708,6 +3716,7 @@ mod tests {
|
||||
"outer",
|
||||
Type::Forall {
|
||||
vars: vec!["a".into()],
|
||||
constraints: vec![],
|
||||
body: Box::new(Type::Fn {
|
||||
params: vec![Type::Var { name: "a".into() }],
|
||||
ret: Box::new(Type::Var { name: "a".into() }),
|
||||
@@ -3788,7 +3797,7 @@ mod tests {
|
||||
// Original LetRec params: [Int]; captures (BTreeSet order):
|
||||
// x: a then z: Int (alphabetical). Ret: a.
|
||||
match &synth.ty {
|
||||
Type::Forall { vars, body } => {
|
||||
Type::Forall { vars, constraints: _, body } => {
|
||||
assert_eq!(
|
||||
vars,
|
||||
&vec!["a".to_string()],
|
||||
|
||||
@@ -558,6 +558,7 @@ impl<'a> Lifter<'a> {
|
||||
} else {
|
||||
Type::Forall {
|
||||
vars: self.current_def_forall_vars.clone(),
|
||||
constraints: vec![],
|
||||
body: Box::new(inner_augmented_ty),
|
||||
}
|
||||
};
|
||||
@@ -867,7 +868,7 @@ fn substitute_rigids_local(t: &Type, mapping: &BTreeMap<String, Type>) -> Type {
|
||||
param_modes: vec![],
|
||||
ret_mode: ParamMode::Implicit,
|
||||
},
|
||||
Type::Forall { vars, body } => {
|
||||
Type::Forall { vars, constraints, body } => {
|
||||
let inner: BTreeMap<String, Type> = mapping
|
||||
.iter()
|
||||
.filter(|(k, _)| !vars.contains(k))
|
||||
@@ -875,6 +876,7 @@ fn substitute_rigids_local(t: &Type, mapping: &BTreeMap<String, Type>) -> Type {
|
||||
.collect();
|
||||
Type::Forall {
|
||||
vars: vars.clone(),
|
||||
constraints: constraints.clone(),
|
||||
body: Box::new(substitute_rigids_local(body, &inner)),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user