V3002 effect_label_not_permitted
A closed effect row was required to be empty or smaller, but an effect label had to be in it (row unification {A | r} ~ {} failed, design §5.2).
An error from the effect phase. sakura explain V3002 prints this explanation offline.
A closed effect row was required to be empty or smaller, but an effect label had to be in it
(row unification {A | r} ~ {} failed, design §5.2). The usual cause is passing an effectful
function where a parameter's type is a pure fn() -> T. Make the parameter's row a variable so
the callee carries the argument's effects through, or handle the effect before passing the
function.
Wrong:
fn apply(f: fn() -> Int) -> Int { f() }
fn noisy() -> Int ! {Console} { apply(loud_one) }Fixed:
fn apply<e>(f: fn() -> Int ! e) -> Int ! e { f() }Wrong program
compiler/tests/ui/V3002_effect_label_not_permitted.sakura, which the compiler's ui suite runs through sakura check:
fn apply(f: fn() -> Int) -> Int { f() }
fn loud_one() -> Int ! {Console} {
Console.print("side effect")
1
}
fn noisy() -> Int ! {Console} { apply(loud_one) }sakura check --json reports this record (pretty-printed; $DIR is the fixture's directory):
{
"schema_version": "1.0",
"kind": "diagnostic",
"id": "d:eecd3c1441de6f7a",
"code": "V3002",
"severity": "error",
"phase": "effect",
"message": "expected `fn() -> Int`, found `fn() -> Int ! {Console}`: effect `Console` is performed by this value but not allowed by the expected type",
"snapshot": "sha256:$SNAPSHOT",
"symbol_id": "main::V3002_effect_label_not_permitted::noisy",
"spans": [
{
"uri": "file://$DIR/V3002_effect_label_not_permitted.sakura",
"content_hash": "sha256:a4b6e19ab0cafb694cd04bc0664109475cfca1b6e88f0e7eafea82702d83df5f",
"start_byte": 186,
"end_byte": 194,
"role": "primary",
"label": "this has type `fn() -> Int ! {Console}`"
}
],
"related_ids": [],
"expected": {
"render": "fn() -> Int"
},
"actual": {
"render": "fn() -> Int ! {Console}"
},
"obligation": null,
"counterexample": null,
"explanation_uri": "sakura://explain/V3002",
"fixes": []
}Fixed program
compiler/tests/ui/V3002_effect_label_not_permitted.fixed.sakura, which sakura check accepts with no diagnostics:
fn apply<e>(f: fn() -> Int ! e) -> Int ! e { f() }
fn loud_one() -> Int ! {Console} {
Console.print("side effect")
1
}
fn noisy() -> Int ! {Console} { apply(loud_one) }