Sakura Lang

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() } }
Edit on GitHub

On this page