mirror of
https://github.com/roc-lang/roc.git
synced 2025-12-15 21:23:57 +00:00
Suffixed pure function warning
This commit is contained in:
parent
1da8af390b
commit
d22b2a79f5
5 changed files with 59 additions and 3 deletions
|
|
@ -14751,4 +14751,32 @@ All branches in an `if` must have the same type!
|
|||
This will help readers identify it as a source of effects.
|
||||
"###
|
||||
);
|
||||
|
||||
test_report!(
|
||||
function_def_leftover_bang,
|
||||
indoc!(
|
||||
r#"
|
||||
app [main!] { pf: platform "../../../../../examples/cli/effects-platform/main.roc" }
|
||||
|
||||
import pf.Effect
|
||||
|
||||
main! = \{} ->
|
||||
Effect.putLine! (hello! {})
|
||||
|
||||
hello! = \{} ->
|
||||
"hello"
|
||||
"#
|
||||
),
|
||||
@r###"
|
||||
── UNNECESSARY EXCLAMATION in /code/proj/Main.roc ──────────────────────────────
|
||||
|
||||
This function is pure, but its name suggests otherwise:
|
||||
|
||||
8│ hello! = \{} ->
|
||||
^^^^^^
|
||||
|
||||
Remove the exclamation mark to give an accurate impression of its
|
||||
behavior.
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,7 +101,8 @@ pub fn remove_module_param_arguments(
|
|||
| TypeError::MissingModuleParams(_, _, _)
|
||||
| TypeError::ModuleParamsMismatch(_, _, _, _)
|
||||
| TypeError::PureStmt(_)
|
||||
| TypeError::UnsuffixedEffectfulFunction(_, _) => {}
|
||||
| TypeError::UnsuffixedEffectfulFunction(_, _)
|
||||
| TypeError::SuffixedPureFunction(_, _) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1543,7 +1543,17 @@ fn check_symbol_suffix(
|
|||
}
|
||||
}
|
||||
IdentSuffix::Bang => {
|
||||
// [purity-inference] TODO
|
||||
if let Content::Structure(FlatType::Func(_, _, _, fx)) =
|
||||
env.subs.get_content_without_compacting(loc_var.value)
|
||||
{
|
||||
match env.subs.get_content_without_compacting(*fx) {
|
||||
// [purity-inference] TODO: Should FlexVar actually be a case?
|
||||
Content::Pure | Content::FlexVar(_) => {
|
||||
problems.push(TypeError::SuffixedPureFunction(loc_var.region, symbol));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ pub enum TypeError {
|
|||
ModuleParamsMismatch(Region, ModuleId, ErrorType, ErrorType),
|
||||
PureStmt(Region),
|
||||
UnsuffixedEffectfulFunction(Region, Symbol),
|
||||
SuffixedPureFunction(Region, Symbol),
|
||||
}
|
||||
|
||||
impl TypeError {
|
||||
|
|
@ -67,6 +68,7 @@ impl TypeError {
|
|||
TypeError::IngestedFileUnsupportedType(..) => Fatal,
|
||||
TypeError::PureStmt(..) => Warning,
|
||||
TypeError::UnsuffixedEffectfulFunction(_, _) => Warning,
|
||||
TypeError::SuffixedPureFunction(_, _) => Warning,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -84,7 +86,8 @@ impl TypeError {
|
|||
| TypeError::MissingModuleParams(region, ..)
|
||||
| TypeError::ModuleParamsMismatch(region, ..)
|
||||
| TypeError::PureStmt(region)
|
||||
| TypeError::UnsuffixedEffectfulFunction(region, _) => Some(*region),
|
||||
| TypeError::UnsuffixedEffectfulFunction(region, _)
|
||||
| TypeError::SuffixedPureFunction(region, _) => Some(*region),
|
||||
TypeError::UnfulfilledAbility(ab, ..) => ab.region(),
|
||||
TypeError::Exhaustive(e) => Some(e.region()),
|
||||
TypeError::CircularDef(c) => c.first().map(|ce| ce.symbol_region),
|
||||
|
|
|
|||
|
|
@ -347,6 +347,20 @@ pub fn type_problem<'b>(
|
|||
severity,
|
||||
})
|
||||
}
|
||||
SuffixedPureFunction(region, _symbol) => {
|
||||
let stack = [
|
||||
alloc.reflow("This function is pure, but its name suggests otherwise:"),
|
||||
alloc.region(lines.convert_region(region), severity),
|
||||
alloc.reflow("Remove the exclamation mark to give an accurate impression of its behavior."),
|
||||
];
|
||||
|
||||
Some(Report {
|
||||
title: "UNNECESSARY EXCLAMATION".to_string(),
|
||||
filename,
|
||||
doc: alloc.stack(stack),
|
||||
severity,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue