Allow suffixed pure functions that are exposed to the host

This commit is contained in:
Agus Zubiaga 2024-11-27 14:02:13 -03:00
parent 4217ffa333
commit 6ffc8a507b
No known key found for this signature in database
8 changed files with 57 additions and 45 deletions

View file

@ -19,7 +19,7 @@ use roc_can::constraint::{
};
use roc_can::expected::{Expected, PExpected};
use roc_can::module::ModuleParams;
use roc_collections::VecMap;
use roc_collections::{VecMap, VecSet};
use roc_debug_flags::dbg_do;
#[cfg(debug_assertions)]
use roc_debug_flags::ROC_VERIFY_RIGID_LET_GENERALIZED;
@ -136,6 +136,7 @@ fn run_help(
function_kind,
module_params,
module_params_vars,
host_exposed_symbols,
..
} = config;
@ -190,6 +191,7 @@ fn run_help(
&mut awaiting_specializations,
module_params,
module_params_vars,
host_exposed_symbols,
);
RunSolveOutput {
@ -249,6 +251,7 @@ fn solve(
awaiting_specializations: &mut AwaitingSpecializations,
module_params: Option<ModuleParams>,
module_params_vars: VecMap<ModuleId, Variable>,
host_exposed_symbols: Option<&VecSet<Symbol>>,
) -> State {
let scope = Scope::new(module_params);
@ -455,6 +458,7 @@ fn solve(
solve_suffix_fx(
env,
problems,
host_exposed_symbols,
FxSuffixKind::Let(*symbol),
loc_var.value,
&loc_var.region,
@ -853,7 +857,7 @@ fn solve(
*type_index,
);
solve_suffix_fx(env, problems, *kind, actual, region);
solve_suffix_fx(env, problems, host_exposed_symbols, *kind, actual, region);
state
}
ExpectEffectful(variable, reason, region) => {
@ -1625,6 +1629,7 @@ fn solve(
fn solve_suffix_fx(
env: &mut InferenceEnv<'_>,
problems: &mut Vec<TypeError>,
host_exposed_symbols: Option<&VecSet<Symbol>>,
kind: FxSuffixKind,
variable: Variable,
region: &Region,
@ -1651,7 +1656,16 @@ fn solve_suffix_fx(
let fx = *fx;
match env.subs.get_content_without_compacting(fx) {
Content::Pure => {
problems.push(TypeError::SuffixedPureFunction(*region, kind));
match (kind.symbol(), host_exposed_symbols) {
(Some(sym), Some(host_exposed)) if host_exposed.contains(sym) => {
// If exposed to the platform, it's allowed to be suffixed but pure
// The platform might require a `main!` function that could perform
// effects, but that's not a requirement.
}
_ => {
problems.push(TypeError::SuffixedPureFunction(*region, kind));
}
}
}
Content::FlexVar(_) => {
env.subs.set_content(fx, Content::Effectful);