V3001 effect_not_allowed
The body performs an effect that the function's signature does not allow.
An error from the effect phase. sakura explain V3001 prints this explanation offline.
The body performs an effect that the function's signature does not allow. A signature's effect
row is an upper bound (design §5.7); omitting ! means ! {}.
The cause span points at the call that introduced the effect. Two repairs:
- add the effect to the signature (
interface_change: every caller must allow it too), or - handle it locally with
with handler { … }(local).
Wrong:
fn greet(name: String) -> Unit { Console.print("hello, {name}") }Fixed:
fn greet(name: String) -> Unit ! {Console} { Console.print("hello, {name}") }Wrong program
compiler/tests/ui/V3001_greet_without_console.sakura, which the compiler's ui suite runs through sakura check:
fn greet(name: String) -> Unit { Console.print("hello, {name}") }
pub fn main() -> Unit ! {Console} { greet("Sakura Lang") }sakura check --json reports this record (pretty-printed; $DIR is the fixture's directory):
{
"schema_version": "1.0",
"kind": "diagnostic",
"id": "d:2d3bc08f407f66bb",
"code": "V3001",
"severity": "error",
"phase": "effect",
"message": "function `greet` performs `Console`, which its signature does not allow (allowed: `{}`)",
"snapshot": "sha256:$SNAPSHOT",
"symbol_id": "main::V3001_greet_without_console::greet",
"spans": [
{
"uri": "file://$DIR/V3001_greet_without_console.sakura",
"content_hash": "sha256:167ca72fd1e1d0fc9cd0d2f54661186c5db27ec82383560357de1a360f630b68",
"start_byte": 70,
"end_byte": 75,
"role": "primary"
},
{
"uri": "file://$DIR/V3001_greet_without_console.sakura",
"content_hash": "sha256:167ca72fd1e1d0fc9cd0d2f54661186c5db27ec82383560357de1a360f630b68",
"start_byte": 100,
"end_byte": 130,
"role": "cause",
"label": "`Console.print` performs `Console` here"
}
],
"related_ids": [],
"expected": {
"render": "{}",
"row": {
"labels": [],
"tail": null
}
},
"actual": {
"render": "{Console}",
"row": {
"labels": [
{
"effect": "std::Console",
"args": []
}
],
"tail": null
}
},
"obligation": null,
"counterexample": null,
"explanation_uri": "sakura://explain/V3001",
"fixes": [
{
"id": "f:2d3bc08f407f66bb.0",
"title": "Add `Console` to the signature",
"applicability": "suggested",
"impact": "interface_change",
"edits": [
{
"span": {
"uri": "file://$DIR/V3001_greet_without_console.sakura",
"content_hash": "sha256:167ca72fd1e1d0fc9cd0d2f54661186c5db27ec82383560357de1a360f630b68",
"start_byte": 97,
"end_byte": 97,
"role": "primary"
},
"replacement": " ! {Console}"
}
]
},
{
"id": "f:2d3bc08f407f66bb.1",
"title": "Handle the effect locally with `with`",
"applicability": "incomplete",
"impact": "local",
"edits": [
{
"span": {
"uri": "file://$DIR/V3001_greet_without_console.sakura",
"content_hash": "sha256:167ca72fd1e1d0fc9cd0d2f54661186c5db27ec82383560357de1a360f630b68",
"start_byte": 98,
"end_byte": 98,
"role": "primary"
},
"replacement": "{ with ?handler "
},
{
"span": {
"uri": "file://$DIR/V3001_greet_without_console.sakura",
"content_hash": "sha256:167ca72fd1e1d0fc9cd0d2f54661186c5db27ec82383560357de1a360f630b68",
"start_byte": 132,
"end_byte": 132,
"role": "primary"
},
"replacement": " }"
}
]
}
]
}Fixed program
compiler/tests/ui/V3001_greet_without_console.fixed.sakura, which sakura check accepts with no diagnostics:
fn greet(name: String) -> Unit ! {Console} { Console.print("hello, {name}") }
pub fn main() -> Unit ! {Console} { greet("Sakura Lang") }