Create can::module::ModuleParams for convenience

This commit is contained in:
Agus Zubiaga 2024-08-17 13:10:37 -03:00
parent e80e3e5b2d
commit 519ff56a85
No known key found for this signature in database
12 changed files with 164 additions and 137 deletions

View file

@ -6,10 +6,10 @@ use crate::def::{canonicalize_defs, report_unused_imports, Def};
use crate::effect_module::HostedGeneratedFunctions;
use crate::env::Env;
use crate::expr::{
AnnotatedMark, ClosureData, DbgLookup, Declarations, ExpectLookup, Expr, Output, PendingDerives,
ClosureData, DbgLookup, Declarations, ExpectLookup, Expr, Output, PendingDerives,
};
use crate::pattern::{
canonicalize_record_destructure, BindingsFromPattern, Pattern, PermitShadows,
canonicalize_record_destructs, BindingsFromPattern, Pattern, PermitShadows, RecordDestruct,
};
use crate::procedure::References;
use crate::scope::Scope;
@ -20,7 +20,7 @@ use roc_module::ident::Ident;
use roc_module::ident::Lowercase;
use roc_module::symbol::{IdentIds, IdentIdsByModule, ModuleId, PackageModuleIds, Symbol};
use roc_parse::ast::{Defs, TypeAnnotation};
use roc_parse::header::{HeaderType, ModuleParams};
use roc_parse::header::HeaderType;
use roc_parse::pattern::PatternType;
use roc_problem::can::{Problem, RuntimeError};
use roc_region::all::{Loc, Region};
@ -138,7 +138,31 @@ pub struct Module {
pub abilities_store: PendingAbilitiesStore,
pub loc_expects: VecMap<Region, Vec<ExpectLookup>>,
pub loc_dbgs: VecMap<Symbol, DbgLookup>,
pub params_pattern: Option<(Variable, AnnotatedMark, Loc<Pattern>)>,
pub module_params: Option<ModuleParams>,
}
#[derive(Debug, Clone)]
pub struct ModuleParams {
pub region: Region,
pub whole_symbol: Symbol,
pub whole_var: Variable,
pub record_var: Variable,
pub record_ext_var: Variable,
pub destructs: Vec<Loc<RecordDestruct>>,
}
impl ModuleParams {
pub fn pattern(&self) -> Loc<Pattern> {
let record_pattern = Pattern::RecordDestructure {
whole_var: self.record_var,
ext_var: self.record_ext_var,
destructs: self.destructs.clone(),
};
let loc_record_pattern = Loc::at(self.region, record_pattern);
let as_pattern = Pattern::As(Box::new(loc_record_pattern), self.whole_symbol);
Loc::at(self.region, as_pattern)
}
}
#[derive(Debug, Default)]
@ -152,7 +176,7 @@ pub struct RigidVariables {
pub struct ModuleOutput {
pub aliases: MutMap<Symbol, Alias>,
pub rigid_variables: RigidVariables,
pub params_pattern: Option<(Variable, AnnotatedMark, Loc<Pattern>)>,
pub module_params: Option<ModuleParams>,
pub declarations: Declarations,
pub exposed_imports: MutMap<Symbol, Region>,
pub exposed_symbols: VecSet<Symbol>,
@ -390,13 +414,13 @@ pub fn canonicalize_module_defs<'a>(
let mut output = Output::default();
let params_pattern = header_type.get_params().as_ref().map(
|ModuleParams {
let module_params = header_type.get_params().as_ref().map(
|roc_parse::header::ModuleParams {
pattern,
before_arrow: _,
after_arrow: _,
}| {
let can_pattern = canonicalize_record_destructure(
let (destructs, _) = canonicalize_record_destructs(
&mut env,
var_store,
&mut scope,
@ -407,17 +431,21 @@ pub fn canonicalize_module_defs<'a>(
PermitShadows(false),
);
let loc_pattern = Loc::at(pattern.region, can_pattern);
for (symbol, _) in BindingsFromPattern::new(&loc_pattern) {
env.top_level_symbols.insert(symbol);
for destruct in destructs.iter() {
env.top_level_symbols.insert(destruct.value.symbol);
}
(
var_store.fresh(),
AnnotatedMark::new(var_store),
loc_pattern,
)
let whole_symbol = scope.gen_unique_symbol();
env.top_level_symbols.insert(whole_symbol);
ModuleParams {
region: pattern.region,
whole_var: var_store.fresh(),
whole_symbol,
record_var: var_store.fresh(),
record_ext_var: var_store.fresh(),
destructs,
}
},
);
@ -851,7 +879,7 @@ pub fn canonicalize_module_defs<'a>(
scope,
aliases,
rigid_variables,
params_pattern,
module_params,
declarations,
referenced_values,
exposed_imports: can_exposed_imports,

View file

@ -623,16 +623,29 @@ pub fn canonicalize_pattern<'a>(
}
}
RecordDestructure(patterns) => canonicalize_record_destructure(
env,
var_store,
scope,
output,
pattern_type,
patterns,
region,
permit_shadows,
),
RecordDestructure(patterns) => {
let ext_var = var_store.fresh();
let whole_var = var_store.fresh();
let (destructs, opt_erroneous) = canonicalize_record_destructs(
env,
var_store,
scope,
output,
pattern_type,
patterns,
region,
permit_shadows,
);
// If we encountered an erroneous pattern (e.g. one with shadowing),
// use the resulting RuntimeError. Otherwise, return a successful record destructure.
opt_erroneous.unwrap_or(Pattern::RecordDestructure {
whole_var,
ext_var,
destructs,
})
}
RequiredField(_name, _loc_pattern) => {
unreachable!("should have been handled in RecordDestructure");
@ -779,7 +792,7 @@ pub fn canonicalize_pattern<'a>(
}
#[allow(clippy::too_many_arguments)]
pub fn canonicalize_record_destructure<'a>(
pub fn canonicalize_record_destructs<'a>(
env: &mut Env<'a>,
var_store: &mut VarStore,
scope: &mut Scope,
@ -788,11 +801,9 @@ pub fn canonicalize_record_destructure<'a>(
patterns: &ast::Collection<Loc<ast::Pattern<'a>>>,
region: Region,
permit_shadows: PermitShadows,
) -> Pattern {
) -> (Vec<Loc<RecordDestruct>>, Option<Pattern>) {
use ast::Pattern::*;
let ext_var = var_store.fresh();
let whole_var = var_store.fresh();
let mut destructs = Vec::with_capacity(patterns.len());
let mut opt_erroneous = None;
@ -907,13 +918,7 @@ pub fn canonicalize_record_destructure<'a>(
}
}
// If we encountered an erroneous pattern (e.g. one with shadowing),
// use the resulting RuntimeError. Otherwise, return a successful record destructure.
opt_erroneous.unwrap_or(Pattern::RecordDestructure {
whole_var,
ext_var,
destructs,
})
(destructs, opt_erroneous)
}
/// When we detect an unsupported pattern type (e.g. 5 = 1 + 2 is unsupported because you can't