Fix broken ability implementation

This commit is contained in:
Sam Mohr 2025-01-04 05:37:17 -08:00
parent 2aac2e01f8
commit 30b8a1407d
No known key found for this signature in database
GPG key ID: EA41D161A3C1BC99
11 changed files with 130 additions and 132 deletions

View file

@ -109,7 +109,7 @@ pub(crate) fn derive_to_inspector(
}
fn to_inspector_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
// Build \lst -> list, List.walk, (\elem -> Inspect.toInspector elem)
// Build \lst -> list, List.walk, (\elem -> Inspect.to_inspector elem)
use Expr::*;
@ -124,7 +124,7 @@ fn to_inspector_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
Content::Structure(FlatType::Apply(Symbol::LIST_LIST, elem_var_slice)),
);
// build `toInspector elem` type
// build `to_inspector elem` type
// val -[uls]-> Inspector fmt where fmt implements InspectorFormatter
let to_inspector_fn_var = env.import_builtin_symbol_var(Symbol::INSPECT_TO_INSPECTOR);
@ -145,7 +145,7 @@ fn to_inspector_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
// ~ elem -[clos]-> t1
env.unify(to_inspector_fn_var, elem_to_inspector_fn_var);
// toInspector : (typeof rcd.a) -[clos]-> Inspector fmt where fmt implements InspectorFormatter
// to_inspector : (typeof rcd.a) -[clos]-> Inspector fmt where fmt implements InspectorFormatter
let to_inspector_var =
AbilityMember(Symbol::INSPECT_TO_INSPECTOR, None, elem_to_inspector_fn_var);
let to_inspector_fn = Box::new((
@ -156,14 +156,14 @@ fn to_inspector_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
Variable::PURE,
));
// toInspector elem
// to_inspector elem
let to_inspector_call = Call(
to_inspector_fn,
vec![(elem_var, Loc::at_zero(Var(elem_sym, elem_var)))],
CalledVia::Space,
);
// elem -[to_elem_inspector]-> toInspector elem
// elem -[to_elem_inspector]-> to_inspector elem
let to_elem_inspector_sym = env.new_symbol("to_elem_inspector");
// Create fn_var for ambient capture; we fix it up below.
@ -181,7 +181,7 @@ fn to_inspector_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
ambient_function: to_elem_inspector_fn_var,
}),
);
// elem -[to_elem_inspector]-> toInspector elem
// elem -[to_elem_inspector]-> to_inspector elem
env.subs.set_content(
to_elem_inspector_fn_var,
Content::Structure(FlatType::Func(
@ -192,7 +192,7 @@ fn to_inspector_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
)),
);
// \elem -> toInspector elem
// \elem -> to_inspector elem
let to_elem_inspector = Closure(ClosureData {
function_type: to_elem_inspector_fn_var,
closure_type: to_elem_inspector_lset,
@ -210,7 +210,7 @@ fn to_inspector_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
loc_body: Box::new(Loc::at_zero(to_inspector_call)),
});
// build `Inspect.list lst (\elem -> Inspect.toInspector elem)` type
// build `Inspect.list lst (\elem -> Inspect.to_inspector elem)` type
// List e, (e -> Inspector fmt) -[uls]-> Inspector fmt where fmt implements InspectorFormatter
let inspect_list_fn_var = env.import_builtin_symbol_var(Symbol::INSPECT_LIST);
@ -268,7 +268,7 @@ fn to_inspector_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
list_var,
);
// \lst -> Inspect.list lst (\elem -> Inspect.toInspector elem)
// \lst -> Inspect.list lst (\elem -> Inspect.to_inspector elem)
// Create fn_var for ambient capture; we fix it up below.
let fn_var = synth_var(env.subs, Content::Error);
@ -295,7 +295,7 @@ fn to_inspector_list(env: &mut Env<'_>, fn_name: Symbol) -> (Expr, Variable) {
)),
);
// \lst -[fn_name]-> Inspect.list lst (\elem -> Inspect.toInspector elem)
// \lst -[fn_name]-> Inspect.list lst (\elem -> Inspect.to_inspector elem)
let clos = Closure(ClosureData {
function_type: fn_var,
closure_type: fn_clos_var,
@ -325,8 +325,8 @@ fn to_inspector_record(
// Suppose rcd = { a: t1, b: t2 }. Build
//
// \rcd -> Inspect.record [
// { key: "a", value: Inspect.toInspector rcd.a },
// { key: "b", value: Inspect.toInspector rcd.b },
// { key: "a", value: Inspect.to_inspector rcd.a },
// { key: "b", value: Inspect.to_inspector rcd.b },
// ]
let rcd_sym = env.new_symbol("rcd");
@ -360,7 +360,7 @@ fn to_inspector_record(
field: field_name,
};
// build `toInspector rcd.a` type
// build `to_inspector rcd.a` type
// val -[uls]-> Inspector fmt where fmt implements InspectorFormatter
let to_inspector_fn_var = env.import_builtin_symbol_var(Symbol::INSPECT_TO_INSPECTOR);
@ -381,7 +381,7 @@ fn to_inspector_record(
// ~ (typeof rcd.a) -[clos]-> t1
env.unify(to_inspector_fn_var, this_to_inspector_fn_var);
// toInspector : (typeof rcd.a) -[clos]-> Inspector fmt where fmt implements InspectorFormatter
// to_inspector : (typeof rcd.a) -[clos]-> Inspector fmt where fmt implements InspectorFormatter
let to_inspector_var =
AbilityMember(Symbol::INSPECT_TO_INSPECTOR, None, to_inspector_fn_var);
let to_inspector_fn = Box::new((
@ -392,21 +392,21 @@ fn to_inspector_record(
Variable::PURE,
));
// toInspector rcd.a
// to_inspector rcd.a
let to_inspector_call = Call(
to_inspector_fn,
vec![(field_var, Loc::at_zero(field_access))],
CalledVia::Space,
);
// value: toInspector rcd.a
// value: to_inspector rcd.a
let value_field = Field {
var: inspector_var,
region: Region::zero(),
loc_expr: Box::new(Loc::at_zero(to_inspector_call)),
};
// { key: "a", value: toInspector rcd.a }
// { key: "a", value: to_inspector rcd.a }
let mut kv = SendMap::default();
kv.insert("key".into(), key_field);
kv.insert("value".into(), value_field);
@ -542,8 +542,8 @@ fn to_inspector_tuple(
// Suppose tup = (t1, t2). Build
//
// \tup -> Inspect.tuple [
// Inspect.toInspector tup.0,
// Inspect.toInspector tup.1,
// Inspect.to_inspector tup.0,
// Inspect.to_inspector tup.1,
// ]
let tup_sym = env.new_symbol("tup");
@ -570,7 +570,7 @@ fn to_inspector_tuple(
index,
};
// build `toInspector tup.0` type
// build `to_inspector tup.0` type
// val -[uls]-> Inspector fmt where fmt implements InspectorFormatter
let to_inspector_fn_var = env.import_builtin_symbol_var(Symbol::INSPECT_TO_INSPECTOR);
@ -591,7 +591,7 @@ fn to_inspector_tuple(
// ~ (typeof tup.0) -[clos]-> t1
env.unify(to_inspector_fn_var, this_to_inspector_fn_var);
// toInspector : (typeof tup.0) -[clos]-> Inspector fmt where fmt implements InspectorFormatter
// to_inspector : (typeof tup.0) -[clos]-> Inspector fmt where fmt implements InspectorFormatter
let to_inspector_var =
AbilityMember(Symbol::INSPECT_TO_INSPECTOR, None, to_inspector_fn_var);
let to_inspector_fn = Box::new((
@ -602,7 +602,7 @@ fn to_inspector_tuple(
Variable::PURE,
));
// toInspector tup.0
// to_inspector tup.0
let to_inspector_call = Call(
to_inspector_fn,
vec![(elem_var, Loc::at_zero(tuple_access))],
@ -616,7 +616,7 @@ fn to_inspector_tuple(
})
.collect::<Vec<_>>();
// typeof [ toInspector tup.0, toInspector tup.1 ]
// typeof [ to_inspector tup.0, to_inspector tup.1 ]
let whole_inspector_in_list_var_slice =
env.subs.insert_into_vars(once(whole_inspector_in_list_var));
let elem_inspectors_list_var = synth_var(
@ -627,13 +627,13 @@ fn to_inspector_tuple(
)),
);
// [ toInspector tup.0, toInspector tup.1 ]
// [ to_inspector tup.0, to_inspector tup.1 ]
let elem_inspectors_list = List {
elem_var: whole_inspector_in_list_var,
loc_elems: elem_inspectors_list,
};
// build `Inspect.tuple [ toInspector tup.0, toInspector tup.1 ]` type
// build `Inspect.tuple [ to_inspector tup.0, to_inspector tup.1 ]` type
// List (Inspector fmt) -[uls]-> Inspector fmt where fmt implements InspectorFormatter
let inspect_tuple_fn_var = env.import_builtin_symbol_var(Symbol::INSPECT_TUPLE);
@ -732,8 +732,8 @@ fn to_inspector_tag_union(
// Suppose tag = [ A t1 t2, B t3 ]. Build
//
// \tag -> when tag is
// A v1 v2 -> Inspect.tag "A" [ Inspect.toInspector v1, Inspect.toInspector v2 ]
// B v3 -> Inspect.tag "B" [ Inspect.toInspector v3 ]
// A v1 v2 -> Inspect.tag "A" [ Inspect.to_inspector v1, Inspect.to_inspector v2 ]
// B v3 -> Inspect.tag "B" [ Inspect.to_inspector v3 ]
let tag_sym = env.new_symbol("tag");
let whole_tag_inspectors_var = env.subs.fresh_unnamed_flex_var(); // type of the Inspect.tag ... calls in the branch bodies
@ -769,13 +769,13 @@ fn to_inspector_tag_union(
degenerate: false,
};
// whole type of the elements in [ Inspect.toInspector v1, Inspect.toInspector v2 ]
// whole type of the elements in [ Inspect.to_inspector v1, Inspect.to_inspector v2 ]
let whole_payload_inspectors_var = env.subs.fresh_unnamed_flex_var();
// [ Inspect.toInspector v1, Inspect.toInspector v2 ]
// [ Inspect.to_inspector v1, Inspect.to_inspector v2 ]
let payload_to_inspectors = (payload_syms.iter())
.zip(payload_vars.iter())
.map(|(&sym, &sym_var)| {
// build `toInspector v1` type
// build `to_inspector v1` type
// expected: val -[uls]-> Inspector fmt where fmt implements InspectorFormatter
let to_inspector_fn_var =
env.import_builtin_symbol_var(Symbol::INSPECT_TO_INSPECTOR);
@ -798,7 +798,7 @@ fn to_inspector_tag_union(
// ~ t1 -[clos]-> t'
env.unify(to_inspector_fn_var, this_to_inspector_fn_var);
// toInspector : t1 -[clos]-> Inspector fmt where fmt implements InspectorFormatter
// to_inspector : t1 -[clos]-> Inspector fmt where fmt implements InspectorFormatter
let to_inspector_var =
AbilityMember(Symbol::INSPECT_TO_INSPECTOR, None, this_to_inspector_fn_var);
let to_inspector_fn = Box::new((
@ -809,7 +809,7 @@ fn to_inspector_tag_union(
Variable::PURE,
));
// toInspector rcd.a
// to_inspector rcd.a
let to_inspector_call = Call(
to_inspector_fn,
vec![(sym_var, Loc::at_zero(Var(sym, sym_var)))],
@ -823,7 +823,7 @@ fn to_inspector_tag_union(
})
.collect();
// typeof [ Inspect.toInspector v1, Inspect.toInspector v2 ]
// typeof [ Inspect.to_inspector v1, Inspect.to_inspector v2 ]
let whole_inspectors_var_slice =
env.subs.insert_into_vars([whole_payload_inspectors_var]);
let payload_inspectors_list_var = synth_var(
@ -834,7 +834,7 @@ fn to_inspector_tag_union(
)),
);
// [ Inspect.toInspector v1, Inspect.toInspector v2 ]
// [ Inspect.to_inspector v1, Inspect.to_inspector v2 ]
let payload_inspectors_list = List {
elem_var: whole_payload_inspectors_var,
loc_elems: payload_to_inspectors,
@ -874,13 +874,13 @@ fn to_inspector_tag_union(
Variable::PURE,
));
// Inspect.tag "A" [ Inspect.toInspector v1, Inspect.toInspector v2 ]
// Inspect.tag "A" [ Inspect.to_inspector v1, Inspect.to_inspector v2 ]
let inspect_tag_call = Call(
inspect_tag_fn,
vec![
// (Str, "A")
(Variable::STR, Loc::at_zero(Str(tag_name.0.as_str().into()))),
// (List (Inspector fmt), [ Inspect.toInspector v1, Inspect.toInspector v2 ])
// (List (Inspector fmt), [ Inspect.to_inspector v1, Inspect.to_inspector v2 ])
(
payload_inspectors_list_var,
Loc::at_zero(payload_inspectors_list),
@ -890,7 +890,7 @@ fn to_inspector_tag_union(
);
// NOTE: must be done to unify the lambda sets under `inspector_var`
// Inspect.tag "A" [ Inspect.toInspector v1, Inspect.toInspector v2 ] ~ whole_inspectors
// Inspect.tag "A" [ Inspect.to_inspector v1, Inspect.to_inspector v2 ] ~ whole_inspectors
env.unify(this_inspector_var, whole_tag_inspectors_var);
WhenBranch {
@ -903,8 +903,8 @@ fn to_inspector_tag_union(
.collect::<Vec<_>>();
// when tag is
// A v1 v2 -> Inspect.tag "A" [ Inspect.toInspector v1, Inspect.toInspector v2 ]
// B v3 -> Inspect.tag "B" [ Inspect.toInspector v3 ]
// A v1 v2 -> Inspect.tag "A" [ Inspect.to_inspector v1, Inspect.to_inspector v2 ]
// B v3 -> Inspect.tag "B" [ Inspect.to_inspector v3 ]
let when_branches = When {
loc_cond: Box::new(Loc::at_zero(Var(tag_sym, tag_union_var))),
cond_var: tag_union_var,
@ -953,8 +953,8 @@ fn to_inspector_tag_union(
// \tag ->
// Inspect.custom \fmt -> Inspect.apply (
// when tag is
// A v1 v2 -> Inspect.tag "A" [ Inspect.toInspector v1, Inspect.toInspector v2 ]
// B v3 -> Inspect.tag "B" [ Inspect.toInspector v3 ])
// A v1 v2 -> Inspect.tag "A" [ Inspect.to_inspector v1, Inspect.to_inspector v2 ]
// B v3 -> Inspect.tag "B" [ Inspect.to_inspector v3 ])
// fmt
let clos = Closure(ClosureData {
function_type: fn_var,