mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
Add variable to ParamsVar
This commit is contained in:
parent
a14a110293
commit
7a8b9f7d6d
5 changed files with 37 additions and 24 deletions
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue