mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 16:44:33 +00:00
Fix broken ability implementation
This commit is contained in:
parent
2aac2e01f8
commit
30b8a1407d
11 changed files with 130 additions and 132 deletions
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue