Sakura Lang

V6001 capability_construction

Capability values (Dir, NetScope, EnvScope, SecretStore) cannot be constructed by user code.

An error from the capability phase. sakura explain V6001 prints this explanation offline.

Capability values (Dir, NetScope, EnvScope, SecretStore) cannot be constructed by user code. Obtain one from a root handler or attenuate an existing one (design §6.2).

An @external declaration outside std is the one door the checker cannot see through, so its parameter and result types may not mention, at any depth, an external or @resource type declared in another package (Dir, File, Body, …) or a Handler<…> (design §17.91). A package may declare externals over external types it declares itself.

Wrong:

import std/fs.{Dir}
@external(js, "./forge.js", "root")
fn forge() -> Dir

Fixed:

import std/fs.{Fs, Dir}
fn root() -> Dir ! {Fs} { Fs.root() }

A Trust is a capability too (design §6.4): it exists only as the literal @trust("reason") passed directly to a sink (Untrusted.trust, Secret.expose, Html.raw), so every trust decision is visible at the sink and listed by sakura audit. It cannot be stored in a binding or field, returned, or accepted by a function outside std.

Wrong:

let t = @trust("display only")
u.trust(t)

Fixed:

u.trust(@trust("display only"))

Wrong program

compiler/tests/ui/V6001_capability_construction.sakura, which the compiler's ui suite runs through sakura check:

import std/fs.{Dir}

@external(js, "./forge.js", "root")
fn forge() -> Dir

sakura check --json reports this record (pretty-printed; $DIR is the fixture's directory):

{
  "schema_version": "1.0",
  "kind": "diagnostic",
  "id": "d:1eb0d9e918e05b5c",
  "code": "V6001",
  "severity": "error",
  "phase": "capability",
  "message": "`Dir` (std/fs) is a capability of another package: a user `@external` cannot construct or receive it; obtain it from a handler (design §6.2)",
  "snapshot": "sha256:$SNAPSHOT",
  "symbol_id": "main::V6001_capability_construction::forge",
  "spans": [
    {
      "uri": "file://$DIR/V6001_capability_construction.sakura",
      "content_hash": "sha256:c4777cc6bde9a20e0e5888061689b5b68f25177b3155829732f48e0606ac8e45",
      "start_byte": 120,
      "end_byte": 123,
      "role": "primary"
    }
  ],
  "related_ids": [],
  "expected": null,
  "actual": null,
  "obligation": null,
  "counterexample": null,
  "explanation_uri": "sakura://explain/V6001",
  "fixes": []
}

Fixed program

compiler/tests/ui/V6001_capability_construction.fixed.sakura, which sakura check accepts with no diagnostics:

import std/fs.{Dir, Fs}

fn root() -> Dir ! {Fs} { Fs.root() }
Edit on GitHub

On this page