Sakura Lang

V6020 dependency_acquires_authority

A dependency acquires authority itself: it calls a std host() constructor (Fs.host(), Env.host(), …) or declares an @external binding (RFC 0003 §5.2, experimental).

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

A dependency acquires authority itself: it calls a std host() constructor (Fs.host(), Env.host(), …) or declares an @external binding (RFC 0003 §5.2, experimental). In any package other than the one being built, authority comes only from the consumer: the dependency performs the effects its public rows declare, through the handlers its caller installs. A host() call reads the program's root grants, so without this rule a dependency could use Fs without Fs in any public row. Rewrite the dependency to declare the effect in its row, or, if you have reviewed it, write trusted = true on its line in the consumer's [dependencies]; sakura audit and build --manifest then list each such site under the package's name. test bodies of a dependency are not compiled by its consumers and are not checked.

Wrong:

# util/src/lib.sak, a dependency
import std/env.{Env}
pub fn home() -> Option<String> { with Env.host() { Env.get("HOME") } }

Fixed:

import std/env.{Env}
pub fn home() -> Option<String> ! {Env} { Env.get("HOME") }

Wrong program

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

main.sak:

// RFC 0003 §5.2: an `@external` declaration in a dependency is `V6020` at the attribute unless the
// root trusts the dependency.
pub fn main() -> Unit ! {Console} { Console.print("hi") }

Open in playground

sakura.toml:

[package]
name = "billing"

[dependencies]
util = { path = "util" }

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

{
  "schema_version": "1.0",
  "kind": "diagnostic",
  "id": "d:81422692b3f5d1c9",
  "code": "V6020",
  "severity": "error",
  "phase": "capability",
  "message": "dependency `util` declares an `@external` binding, which acquires authority: a dependency performs only the effects its rows declare, through its caller's handlers. Declare the effect in the function's row instead, or, after reviewing `util`, write `trusted = true` on its line in the root package's `[dependencies]`",
  "snapshot": "sha256:$SNAPSHOT",
  "symbol_id": "util::clock::now",
  "spans": [
    {
      "uri": "file://$DIR/V6020_dependency_external/util/src/clock.sak",
      "content_hash": "sha256:bb7ad686f0499dc68f493b5eb87e1fe2d9ef378de8d9b4065c4bef768b4e9e31",
      "start_byte": 64,
      "end_byte": 72,
      "role": "primary"
    }
  ],
  "related_ids": [],
  "expected": null,
  "actual": null,
  "obligation": null,
  "counterexample": null,
  "explanation_uri": "sakura://explain/V6020",
  "fixes": []
}

Fixed program

No fixed program is checked in for this code yet; the explanation above describes the repair.

Edit on GitHub

Last updated

On this page