Suffixed pure function warning

This commit is contained in:
Agus Zubiaga 2024-10-16 16:20:29 -03:00
parent 1da8af390b
commit d22b2a79f5
No known key found for this signature in database
5 changed files with 59 additions and 3 deletions

View file

@ -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.
"###
);
}

View file

@ -101,7 +101,8 @@ pub fn remove_module_param_arguments(
| TypeError::MissingModuleParams(_, _, _)
| TypeError::ModuleParamsMismatch(_, _, _, _)
| TypeError::PureStmt(_)
| TypeError::UnsuffixedEffectfulFunction(_, _) => {}
| TypeError::UnsuffixedEffectfulFunction(_, _)
| TypeError::SuffixedPureFunction(_, _) => {}
}
}
}

View file

@ -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));
}
_ => {}
}
}
}
}
}

View file

@ -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),

View file

@ -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,
})
}
}
}