mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 22:09:09 +00:00
Report effectful top-level exprs
This commit is contained in:
parent
b62665e49e
commit
f666dba67d
5 changed files with 61 additions and 4 deletions
|
@ -1891,7 +1891,7 @@ fn constrain_call_fx(
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
None => constraints.push_expected_type(ForReason(
|
None => constraints.push_expected_type(ForReason(
|
||||||
Reason::CallInTopLevelDef,
|
Reason::CallInTopLevel,
|
||||||
// top-level defs are only allowed to call pure functions
|
// top-level defs are only allowed to call pure functions
|
||||||
constraints.push_variable(Variable::PURE),
|
constraints.push_variable(Variable::PURE),
|
||||||
region,
|
region,
|
||||||
|
|
|
@ -14824,6 +14824,44 @@ All branches in an `if` must have the same type!
|
||||||
"###
|
"###
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test_report!(
|
||||||
|
effect_in_top_level_value_def,
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app [main!] { pf: platform "../../../../../examples/cli/effects-platform/main.roc" }
|
||||||
|
|
||||||
|
import pf.Effect
|
||||||
|
|
||||||
|
hello =
|
||||||
|
Effect.putLine! "calling hello!"
|
||||||
|
"hello"
|
||||||
|
|
||||||
|
main! = \{} ->
|
||||||
|
Effect.putLine! hello
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
@r###"
|
||||||
|
── EFFECT IN TOP-LEVEL in /code/proj/Main.roc ──────────────────────────────────
|
||||||
|
|
||||||
|
This top-level expression calls an effectful function:
|
||||||
|
|
||||||
|
6│ Effect.putLine! "calling hello!"
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
However, only functions are allowed to be effectful. This limitation
|
||||||
|
ensures that importing a module never produces a side effect.
|
||||||
|
|
||||||
|
Tip: If you don't need any arguments, use an empty record:
|
||||||
|
|
||||||
|
askName! : {} => Str
|
||||||
|
askName! = \{} ->
|
||||||
|
Stdout.line! "What's your name?"
|
||||||
|
Stdin.line! {}
|
||||||
|
|
||||||
|
This will allow the caller to control when the effect runs.
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
|
||||||
test_report!(
|
test_report!(
|
||||||
aliased_fx_fn,
|
aliased_fx_fn,
|
||||||
indoc!(
|
indoc!(
|
||||||
|
|
|
@ -186,7 +186,7 @@ fn remove_for_reason(
|
||||||
| Reason::CrashArg
|
| Reason::CrashArg
|
||||||
| Reason::ImportParams(_)
|
| Reason::ImportParams(_)
|
||||||
| Reason::CallInFunction(_)
|
| Reason::CallInFunction(_)
|
||||||
| Reason::CallInTopLevelDef
|
| Reason::CallInTopLevel
|
||||||
| Reason::Stmt
|
| Reason::Stmt
|
||||||
| Reason::FunctionOutput => {}
|
| Reason::FunctionOutput => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3450,7 +3450,7 @@ pub enum Reason {
|
||||||
},
|
},
|
||||||
Stmt,
|
Stmt,
|
||||||
CallInFunction(Option<Region>),
|
CallInFunction(Option<Region>),
|
||||||
CallInTopLevelDef,
|
CallInTopLevel,
|
||||||
FloatLiteral,
|
FloatLiteral,
|
||||||
IntLiteral,
|
IntLiteral,
|
||||||
NumLiteral,
|
NumLiteral,
|
||||||
|
|
|
@ -1763,7 +1763,26 @@ fn to_expr_report<'b>(
|
||||||
severity,
|
severity,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reason::CallInTopLevelDef => todo!("[purity-inference] CallInTopLevelDef"),
|
Reason::CallInTopLevel => {
|
||||||
|
let lines = [
|
||||||
|
alloc.reflow("This top-level expression calls an effectful function:"),
|
||||||
|
alloc.region(lines.convert_region(region), severity),
|
||||||
|
alloc.reflow("However, only functions are allowed to be effectful. This limitation ensures that importing a module never produces a side effect."),
|
||||||
|
alloc.concat([
|
||||||
|
alloc.tip(),
|
||||||
|
alloc.reflow("If you don't need any arguments, use an empty record:"),
|
||||||
|
]),
|
||||||
|
alloc.parser_suggestion(" askName! : {} => Str\n askName! = \\{} ->\n Stdout.line! \"What's your name?\"\n Stdin.line! {}"),
|
||||||
|
alloc.reflow("This will allow the caller to control when the effect runs."),
|
||||||
|
];
|
||||||
|
|
||||||
|
Report {
|
||||||
|
filename,
|
||||||
|
title: "EFFECT IN TOP-LEVEL".to_string(),
|
||||||
|
doc: alloc.stack(lines),
|
||||||
|
severity,
|
||||||
|
}
|
||||||
|
}
|
||||||
Reason::Stmt => todo!("[purity-inference] Stmt"),
|
Reason::Stmt => todo!("[purity-inference] Stmt"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue