V3003 try_unknown_failures
try without catch must name every failure of its body in Result<T, E>.
An error from the effect phase. sakura explain V3003 prints this explanation offline.
try without catch must name every failure of its body in Result<T, E>. When the body's
row ends in a row variable e that is never written next to Fail<…> in its declaration, e
may hide failures nobody can name (design §5.2 rule 8, §5.3), so E cannot be written.
Declare the failures with a type parameter, which makes e Fail-free. (try … catch is fine:
its arms match the named tags and the hidden failures stay in the row.)
Wrong:
fn wrap<e>(f: fn() -> Int ! e) -> Result<Int, Never> ! e { try { f() } }Fixed:
fn wrap<E, e>(f: fn() -> Int ! {Fail<E> | e}) -> Result<Int, E> ! e { try { f() } }Wrong program
compiler/tests/ui/V3003_try_unknown_failures.sakura, which the compiler's ui suite runs through sakura check:
fn wrap<e>(f: fn() -> Int ! e) -> Result<Int, Never> ! e { try { f() } }sakura check --json reports this record (pretty-printed; $DIR is the fixture's directory):
{
"schema_version": "1.0",
"kind": "diagnostic",
"id": "d:488bcf070436dae6",
"code": "V3003",
"severity": "error",
"phase": "effect",
"message": "`try` cannot name the failures of its body: the row ends in `e`, which may hide `Fail<…>`; declare them with a type parameter (`fn f<E, e>(g: fn() -> T ! {Fail<E> | e}) -> Result<T, E> ! e`)",
"snapshot": "sha256:$SNAPSHOT",
"symbol_id": "main::V3003_try_unknown_failures::wrap",
"spans": [
{
"uri": "file://$DIR/V3003_try_unknown_failures.sakura",
"content_hash": "sha256:68cf14995b2b4537e9a972833172f335e9abd89eee9b5fba28a1f371d57f9873",
"start_byte": 93,
"end_byte": 104,
"role": "primary"
}
],
"related_ids": [],
"expected": null,
"actual": {
"render": "e",
"row": {
"labels": [],
"tail": "e"
}
},
"obligation": null,
"counterexample": null,
"explanation_uri": "sakura://explain/V3003",
"fixes": [
{
"id": "f:488bcf070436dae6.0",
"title": "Declare the failures of `e` as `Fail<E>` in the signature",
"applicability": "incomplete",
"impact": "interface_change",
"edits": []
}
]
}Fixed program
compiler/tests/ui/V3003_try_unknown_failures.fixed.sakura, which sakura check accepts with no diagnostics:
fn wrap<E, e>(f: fn() -> Int ! {Fail<E> | e}) -> Result<Int, E> ! e { try { f() } }