Add variable to ParamsVar

This commit is contained in:
Agus Zubiaga 2024-07-04 16:59:47 -03:00
parent a14a110293
commit 7a8b9f7d6d
No known key found for this signature in database
5 changed files with 37 additions and 24 deletions

View file

@ -290,12 +290,14 @@ fn deep_copy_expr_help<C: CopyEnv>(env: &mut C, copied: &mut Vec<Variable>, expr
Var(sym, var) => Var(*sym, sub!(*var)),
ParamsVar {
symbol,
params,
var,
params_symbol,
params_var,
} => ParamsVar {
symbol: *symbol,
params: *params,
var: sub!(*var),
params_symbol: *params_symbol,
params_var: sub!(*params_var),
},
ImportParams(module_id, region, opt_provided) => ImportParams(
*module_id,

View file

@ -165,6 +165,7 @@ enum PendingValueDef<'a> {
/// Module params from an import
ImportParams {
symbol: Symbol,
variable: Variable,
loc_pattern: Loc<Pattern>,
module_id: ModuleId,
opt_provided: Option<ast::Collection<'a, Loc<AssignedField<'a, ast::Expr<'a>>>>>,
@ -186,6 +187,7 @@ impl PendingValueDef<'_> {
PendingValueDef::ImportParams {
loc_pattern,
symbol: _,
variable: _,
module_id: _,
opt_provided: _,
} => loc_pattern,
@ -1153,6 +1155,7 @@ fn canonicalize_value_defs<'a>(
pending_value_defs.push(PendingValueDef::ImportParams {
symbol: params.symbol,
variable: params.variable,
loc_pattern: params.loc_pattern,
opt_provided: params.opt_provided,
module_id,
@ -2400,6 +2403,7 @@ fn canonicalize_pending_value_def<'a>(
}
ImportParams {
symbol,
variable,
loc_pattern,
module_id,
opt_provided,
@ -2418,7 +2422,7 @@ fn canonicalize_pending_value_def<'a>(
let references = can_output.references.clone();
output.union(can_output);
(Some((var_store.fresh(), Box::new(record))), references)
(Some((variable, Box::new(record))), references)
}
None => (None, References::new()),
};
@ -3003,6 +3007,7 @@ struct PendingModuleImport<'a> {
struct PendingModuleImportParams<'a> {
symbol: Symbol,
variable: Variable,
loc_pattern: Loc<Pattern>,
opt_provided: Option<ast::Collection<'a, Loc<AssignedField<'a, ast::Expr<'a>>>>>,
}
@ -3160,15 +3165,17 @@ fn to_pending_value_def<'a>(
// We do this even if params weren't provided so that solve can report if they are missing
let params_sym = scope.gen_unique_symbol();
let params_region = module_import.params.map(|p| p.params.region).unwrap_or(region);
let params_var = var_store.fresh();
let params =
PendingModuleImportParams {
symbol: params_sym,
variable: params_var,
loc_pattern: Loc::at(params_region, Pattern::Identifier(params_sym)),
opt_provided: module_import.params.map(|p| p.params.value),
};
let provided_params_sym = if module_import.params.is_some() {
let provided_params = if module_import.params.is_some() {
// Only add params to scope if they are provided
Some(params_sym)
Some((params_var, params_sym))
} else {
None
};
@ -3176,7 +3183,7 @@ fn to_pending_value_def<'a>(
if let Err(existing_import) =
scope
.modules
.insert(name_with_alias.clone(), module_id, provided_params_sym, region)
.insert(name_with_alias.clone(), module_id, provided_params, region)
{
env.problems.push(Problem::ImportNameConflict {
name: name_with_alias,

View file

@ -111,8 +111,9 @@ pub enum Expr {
/// Like Var, but from a module with params
ParamsVar {
symbol: Symbol,
params: Symbol,
var: Variable,
params_symbol: Symbol,
params_var: Variable,
},
AbilityMember(
/// Actual member name
@ -320,8 +321,9 @@ impl Expr {
&Self::Var(sym, _) => Category::Lookup(sym),
&Self::ParamsVar {
symbol,
params: _,
var: _,
params_symbol: _,
params_var: _,
} => Category::Lookup(symbol),
&Self::AbilityMember(sym, _, _) => Category::Lookup(sym),
Self::When { .. } => Category::When,
@ -1924,7 +1926,7 @@ fn canonicalize_var_lookup(
var_store.fresh(),
)
} else {
lookup_to_expr(lookup, var_store.fresh())
lookup_to_expr(var_store, lookup)
}
}
Err(problem) => {
@ -1949,7 +1951,7 @@ fn canonicalize_var_lookup(
var_store.fresh(),
)
} else {
lookup_to_expr(lookup, var_store.fresh())
lookup_to_expr(var_store, lookup)
}
}
Err(problem) => {
@ -1968,20 +1970,21 @@ fn canonicalize_var_lookup(
}
fn lookup_to_expr(
var_store: &mut VarStore,
SymbolLookup {
symbol,
module_params: params,
module_params,
}: SymbolLookup,
var: Variable,
) -> Expr {
if let Some(params) = params {
if let Some((params_var, params_symbol)) = module_params {
Expr::ParamsVar {
symbol,
params,
var,
var: var_store.fresh(),
params_symbol,
params_var,
}
} else {
Expr::Var(symbol, var)
Expr::Var(symbol, var_store.fresh())
}
}
@ -3201,8 +3204,9 @@ pub(crate) fn get_lookup_symbols(expr: &Expr) -> Vec<ExpectLookup> {
Expr::Var(symbol, var)
| Expr::ParamsVar {
symbol,
params: _,
var,
params_symbol: _,
params_var: _,
}
| Expr::RecordUpdate {
symbol,

View file

@ -669,7 +669,7 @@ pub struct ScopeModules {
/// Why is this module in scope?
sources: Vec<ScopeModuleSource>,
/// The params of a module if any
params: Vec<Option<Symbol>>,
params: Vec<Option<(Variable, Symbol)>>,
}
impl ScopeModules {
@ -731,7 +731,7 @@ impl ScopeModules {
&mut self,
module_name: ModuleName,
module_id: ModuleId,
params_symbol: Option<Symbol>,
params: Option<(Variable, Symbol)>,
region: Region,
) -> Result<(), ScopeModuleSource> {
if let Some(index) = self.names.iter().position(|name| name == &module_name) {
@ -745,7 +745,7 @@ impl ScopeModules {
self.ids.push(module_id);
self.names.push(module_name);
self.sources.push(ScopeModuleSource::Import(region));
self.params.push(params_symbol);
self.params.push(params);
Ok(())
}
@ -771,11 +771,11 @@ impl ScopeModules {
#[derive(Debug, Clone)]
pub struct SymbolLookup {
pub symbol: Symbol,
pub module_params: Option<Symbol>,
pub module_params: Option<(Variable, Symbol)>,
}
impl SymbolLookup {
pub fn new(symbol: Symbol, params: Option<Symbol>) -> Self {
pub fn new(symbol: Symbol, params: Option<(Variable, Symbol)>) -> Self {
Self {
symbol,
module_params: params,
@ -789,7 +789,7 @@ impl SymbolLookup {
pub struct ModuleLookup {
pub id: ModuleId,
pub params: Option<Symbol>,
pub params: Option<(Variable, Symbol)>,
}
impl ModuleLookup {

View file

@ -569,8 +569,8 @@ pub fn constrain_expr(
Var(symbol, variable)
| ParamsVar {
symbol,
params: _,
var: variable,
..
} => {
// Save the expectation in the variable, then lookup the symbol's type in the environment
let expected_type = *constraints[expected].get_type_ref();