mirror of
https://github.com/roc-lang/roc.git
synced 2025-11-02 22:01:20 +00:00
Unsuffixed effectul function warning
This commit is contained in:
parent
75856ae804
commit
1da8af390b
5 changed files with 115 additions and 4 deletions
|
|
@ -14547,11 +14547,11 @@ All branches in an `if` must have the same type!
|
|||
leftover_statement,
|
||||
indoc!(
|
||||
r#"
|
||||
app [main] { pf: platform "../../../../../examples/cli/effects-platform/main.roc" }
|
||||
app [main!] { pf: platform "../../../../../examples/cli/effects-platform/main.roc" }
|
||||
|
||||
import pf.Effect
|
||||
|
||||
main = \{} ->
|
||||
main! = \{} ->
|
||||
identity {}
|
||||
|
||||
Effect.putLine! "hello"
|
||||
|
|
@ -14689,4 +14689,66 @@ All branches in an `if` must have the same type!
|
|||
Num *
|
||||
"###
|
||||
);
|
||||
|
||||
test_report!(
|
||||
function_def_fx_no_bang,
|
||||
indoc!(
|
||||
r#"
|
||||
app [main!] { pf: platform "../../../../../examples/cli/effects-platform/main.roc" }
|
||||
|
||||
import pf.Effect
|
||||
|
||||
main! = \{} ->
|
||||
printHello {}
|
||||
|
||||
printHello = \{} ->
|
||||
Effect.putLine! "hello"
|
||||
"#
|
||||
),
|
||||
@r###"
|
||||
── MISSING EXCLAMATION in /code/proj/Main.roc ──────────────────────────────────
|
||||
|
||||
This function is effectful, but its name does not indicate so:
|
||||
|
||||
8│ printHello = \{} ->
|
||||
^^^^^^^^^^
|
||||
|
||||
Add an exclamation mark at the end of its name, like:
|
||||
|
||||
printHello!
|
||||
|
||||
This will help readers identify it as a source of effects.
|
||||
"###
|
||||
);
|
||||
|
||||
test_report!(
|
||||
nested_function_def_fx_no_bang,
|
||||
indoc!(
|
||||
r#"
|
||||
app [main!] { pf: platform "../../../../../examples/cli/effects-platform/main.roc" }
|
||||
|
||||
import pf.Effect
|
||||
|
||||
main! = \{} ->
|
||||
printHello = \{} ->
|
||||
Effect.putLine! "hello"
|
||||
|
||||
printHello {}
|
||||
"#
|
||||
),
|
||||
@r###"
|
||||
── MISSING EXCLAMATION in /code/proj/Main.roc ──────────────────────────────────
|
||||
|
||||
This function is effectful, but its name does not indicate so:
|
||||
|
||||
6│ printHello = \{} ->
|
||||
^^^^^^^^^^
|
||||
|
||||
Add an exclamation mark at the end of its name, like:
|
||||
|
||||
printHello!
|
||||
|
||||
This will help readers identify it as a source of effects.
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,8 @@ pub fn remove_module_param_arguments(
|
|||
| TypeError::UnexpectedModuleParams(_, _)
|
||||
| TypeError::MissingModuleParams(_, _, _)
|
||||
| TypeError::ModuleParamsMismatch(_, _, _, _)
|
||||
| TypeError::PureStmt(_) => {}
|
||||
| TypeError::PureStmt(_)
|
||||
| TypeError::UnsuffixedEffectfulFunction(_, _) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ use roc_debug_flags::dbg_do;
|
|||
#[cfg(debug_assertions)]
|
||||
use roc_debug_flags::ROC_VERIFY_RIGID_LET_GENERALIZED;
|
||||
use roc_error_macros::internal_error;
|
||||
use roc_module::ident::IdentSuffix;
|
||||
use roc_module::symbol::{ModuleId, Symbol};
|
||||
use roc_problem::can::CycleEntry;
|
||||
use roc_region::all::Loc;
|
||||
|
|
@ -448,6 +449,8 @@ fn solve(
|
|||
);
|
||||
|
||||
new_scope.insert_symbol_var_if_vacant(*symbol, loc_var.value);
|
||||
|
||||
check_symbol_suffix(env, problems, *symbol, *loc_var);
|
||||
}
|
||||
|
||||
// Note that this vars_by_symbol is the one returned by the
|
||||
|
|
@ -1520,6 +1523,31 @@ fn solve(
|
|||
state
|
||||
}
|
||||
|
||||
fn check_symbol_suffix(
|
||||
env: &mut InferenceEnv<'_>,
|
||||
problems: &mut Vec<TypeError>,
|
||||
symbol: Symbol,
|
||||
loc_var: Loc<Variable>,
|
||||
) {
|
||||
match symbol.suffix() {
|
||||
IdentSuffix::None => {
|
||||
if let Content::Structure(FlatType::Func(_, _, _, fx)) =
|
||||
env.subs.get_content_without_compacting(loc_var.value)
|
||||
{
|
||||
if let Content::Effectful = env.subs.get_content_without_compacting(*fx) {
|
||||
problems.push(TypeError::UnsuffixedEffectfulFunction(
|
||||
loc_var.region,
|
||||
symbol,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
IdentSuffix::Bang => {
|
||||
// [purity-inference] TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn chase_alias_content(subs: &Subs, mut var: Variable) -> (Variable, &Content) {
|
||||
loop {
|
||||
match subs.get_content_without_compacting(var) {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ pub enum TypeError {
|
|||
MissingModuleParams(Region, ModuleId, ErrorType),
|
||||
ModuleParamsMismatch(Region, ModuleId, ErrorType, ErrorType),
|
||||
PureStmt(Region),
|
||||
UnsuffixedEffectfulFunction(Region, Symbol),
|
||||
}
|
||||
|
||||
impl TypeError {
|
||||
|
|
@ -65,6 +66,7 @@ impl TypeError {
|
|||
TypeError::IngestedFileBadUtf8(..) => Fatal,
|
||||
TypeError::IngestedFileUnsupportedType(..) => Fatal,
|
||||
TypeError::PureStmt(..) => Warning,
|
||||
TypeError::UnsuffixedEffectfulFunction(_, _) => Warning,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -81,7 +83,8 @@ impl TypeError {
|
|||
| TypeError::UnexpectedModuleParams(region, ..)
|
||||
| TypeError::MissingModuleParams(region, ..)
|
||||
| TypeError::ModuleParamsMismatch(region, ..)
|
||||
| TypeError::PureStmt(region) => Some(*region),
|
||||
| TypeError::PureStmt(region)
|
||||
| TypeError::UnsuffixedEffectfulFunction(region, _) => Some(*region),
|
||||
TypeError::UnfulfilledAbility(ab, ..) => ab.region(),
|
||||
TypeError::Exhaustive(e) => Some(e.region()),
|
||||
TypeError::CircularDef(c) => c.first().map(|ce| ce.symbol_region),
|
||||
|
|
|
|||
|
|
@ -330,6 +330,23 @@ pub fn type_problem<'b>(
|
|||
severity,
|
||||
})
|
||||
}
|
||||
UnsuffixedEffectfulFunction(region, symbol) => {
|
||||
let stack = [
|
||||
alloc.reflow("This function is effectful, but its name does not indicate so:"),
|
||||
alloc.region(lines.convert_region(region), severity),
|
||||
alloc.reflow("Add an exclamation mark at the end of its name, like:"),
|
||||
alloc
|
||||
.string(format!("{}!", symbol.as_str(alloc.interns)))
|
||||
.indent(4),
|
||||
alloc.reflow("This will help readers identify it as a source of effects."),
|
||||
];
|
||||
Some(Report {
|
||||
title: "MISSING EXCLAMATION".to_string(),
|
||||
filename,
|
||||
doc: alloc.stack(stack),
|
||||
severity,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue