mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 11:52:19 +00:00
Wrap import params expr so we can constrain later
This commit is contained in:
parent
dcb2767b6e
commit
674adf1fad
8 changed files with 68 additions and 14 deletions
|
@ -297,6 +297,9 @@ fn deep_copy_expr_help<C: CopyEnv>(env: &mut C, copied: &mut Vec<Variable>, expr
|
||||||
params: *params,
|
params: *params,
|
||||||
var: sub!(*var),
|
var: sub!(*var),
|
||||||
},
|
},
|
||||||
|
ImportParams(loc_expr, module_id) => {
|
||||||
|
ImportParams(Box::new(loc_expr.map(|e| go_help!(e))), *module_id)
|
||||||
|
}
|
||||||
&AbilityMember(sym, specialization, specialization_var) => {
|
&AbilityMember(sym, specialization, specialization_var) => {
|
||||||
AbilityMember(sym, specialization, sub!(specialization_var))
|
AbilityMember(sym, specialization, sub!(specialization_var))
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,6 +209,7 @@ fn expr<'a>(c: &Ctx, p: EPrec, f: &'a Arena<'a>, e: &'a Expr) -> DocBuilder<'a,
|
||||||
Var(sym, _) | ParamsVar { symbol: sym, .. } | AbilityMember(sym, _, _) => {
|
Var(sym, _) | ParamsVar { symbol: sym, .. } | AbilityMember(sym, _, _) => {
|
||||||
pp_sym(c, f, *sym)
|
pp_sym(c, f, *sym)
|
||||||
}
|
}
|
||||||
|
ImportParams(loc_expr, _) => expr(c, p, f, &loc_expr.value),
|
||||||
When {
|
When {
|
||||||
loc_cond, branches, ..
|
loc_cond, branches, ..
|
||||||
} => maybe_paren!(
|
} => maybe_paren!(
|
||||||
|
|
|
@ -167,10 +167,11 @@ enum PendingValueDef<'a> {
|
||||||
&'a Loc<ast::Expr<'a>>,
|
&'a Loc<ast::Expr<'a>>,
|
||||||
),
|
),
|
||||||
/// Module params from an import
|
/// Module params from an import
|
||||||
ImportParams(
|
ImportParams {
|
||||||
Loc<Pattern>,
|
loc_pattern: Loc<Pattern>,
|
||||||
ast::Collection<'a, Loc<AssignedField<'a, ast::Expr<'a>>>>,
|
module_id: ModuleId,
|
||||||
),
|
params: ast::Collection<'a, Loc<AssignedField<'a, ast::Expr<'a>>>>,
|
||||||
|
},
|
||||||
/// Ingested file
|
/// Ingested file
|
||||||
IngestedFile(
|
IngestedFile(
|
||||||
Loc<Pattern>,
|
Loc<Pattern>,
|
||||||
|
@ -185,7 +186,11 @@ impl PendingValueDef<'_> {
|
||||||
PendingValueDef::AnnotationOnly(_, loc_pattern, _) => loc_pattern,
|
PendingValueDef::AnnotationOnly(_, loc_pattern, _) => loc_pattern,
|
||||||
PendingValueDef::Body(loc_pattern, _) => loc_pattern,
|
PendingValueDef::Body(loc_pattern, _) => loc_pattern,
|
||||||
PendingValueDef::TypedBody(_, loc_pattern, _, _) => loc_pattern,
|
PendingValueDef::TypedBody(_, loc_pattern, _, _) => loc_pattern,
|
||||||
PendingValueDef::ImportParams(loc_pattern, _) => loc_pattern,
|
PendingValueDef::ImportParams {
|
||||||
|
loc_pattern,
|
||||||
|
module_id: _,
|
||||||
|
params: _,
|
||||||
|
} => loc_pattern,
|
||||||
PendingValueDef::IngestedFile(loc_pattern, _, _) => loc_pattern,
|
PendingValueDef::IngestedFile(loc_pattern, _, _) => loc_pattern,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1144,7 +1149,11 @@ fn canonicalize_value_defs<'a>(
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some((loc_pattern, params)) = params {
|
if let Some((loc_pattern, params)) = params {
|
||||||
pending_value_defs.push(PendingValueDef::ImportParams(loc_pattern, params));
|
pending_value_defs.push(PendingValueDef::ImportParams {
|
||||||
|
loc_pattern,
|
||||||
|
module_id,
|
||||||
|
params,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PendingValue::InvalidIngestedFile => { /* skip */ }
|
PendingValue::InvalidIngestedFile => { /* skip */ }
|
||||||
|
@ -2387,13 +2396,22 @@ fn canonicalize_pending_value_def<'a>(
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ImportParams(loc_pattern, params) => {
|
ImportParams {
|
||||||
let (expr, can_output) =
|
loc_pattern,
|
||||||
|
module_id,
|
||||||
|
params,
|
||||||
|
} => {
|
||||||
|
let (record, can_output) =
|
||||||
canonicalize_record(env, var_store, scope, loc_pattern.region, params);
|
canonicalize_record(env, var_store, scope, loc_pattern.region, params);
|
||||||
|
|
||||||
output.union(can_output);
|
output.union(can_output);
|
||||||
|
|
||||||
let loc_expr = Loc::at(loc_pattern.region, expr);
|
let loc_record = Loc::at(loc_pattern.region, record);
|
||||||
|
|
||||||
|
let loc_expr = Loc::at(
|
||||||
|
loc_pattern.region,
|
||||||
|
Expr::ImportParams(Box::new(loc_record), module_id),
|
||||||
|
);
|
||||||
|
|
||||||
let def = single_can_def(
|
let def = single_can_def(
|
||||||
loc_pattern,
|
loc_pattern,
|
||||||
|
|
|
@ -17,7 +17,7 @@ use roc_error_macros::internal_error;
|
||||||
use roc_module::called_via::CalledVia;
|
use roc_module::called_via::CalledVia;
|
||||||
use roc_module::ident::{ForeignSymbol, Lowercase, TagName};
|
use roc_module::ident::{ForeignSymbol, Lowercase, TagName};
|
||||||
use roc_module::low_level::LowLevel;
|
use roc_module::low_level::LowLevel;
|
||||||
use roc_module::symbol::{LookedupSymbol, Symbol};
|
use roc_module::symbol::{LookedupSymbol, ModuleId, Symbol};
|
||||||
use roc_parse::ast::{self, Defs, PrecedenceConflict, StrLiteral};
|
use roc_parse::ast::{self, Defs, PrecedenceConflict, StrLiteral};
|
||||||
use roc_parse::ident::Accessor;
|
use roc_parse::ident::Accessor;
|
||||||
use roc_parse::pattern::PatternType::*;
|
use roc_parse::pattern::PatternType::*;
|
||||||
|
@ -183,6 +183,9 @@ pub enum Expr {
|
||||||
elems: Vec<(Variable, Box<Loc<Expr>>)>,
|
elems: Vec<(Variable, Box<Loc<Expr>>)>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// Module params expression in import
|
||||||
|
ImportParams(Box<Loc<Expr>>, ModuleId),
|
||||||
|
|
||||||
/// The "crash" keyword
|
/// The "crash" keyword
|
||||||
Crash {
|
Crash {
|
||||||
msg: Box<Loc<Expr>>,
|
msg: Box<Loc<Expr>>,
|
||||||
|
@ -335,6 +338,7 @@ impl Expr {
|
||||||
Self::RecordAccessor(data) => Category::Accessor(data.field.clone()),
|
Self::RecordAccessor(data) => Category::Accessor(data.field.clone()),
|
||||||
Self::TupleAccess { index, .. } => Category::TupleAccess(*index),
|
Self::TupleAccess { index, .. } => Category::TupleAccess(*index),
|
||||||
Self::RecordUpdate { .. } => Category::Record,
|
Self::RecordUpdate { .. } => Category::Record,
|
||||||
|
Self::ImportParams(loc_expr, _) => loc_expr.value.category(),
|
||||||
Self::Tag {
|
Self::Tag {
|
||||||
name, arguments, ..
|
name, arguments, ..
|
||||||
} => Category::TagApply {
|
} => Category::TagApply {
|
||||||
|
@ -2221,6 +2225,11 @@ pub fn inline_calls(var_store: &mut VarStore, expr: Expr) -> Expr {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImportParams(loc_expr, module_id) => {
|
||||||
|
let loc_expr = Loc::at(loc_expr.region, inline_calls(var_store, loc_expr.value));
|
||||||
|
ImportParams(Box::new(loc_expr), module_id)
|
||||||
|
}
|
||||||
|
|
||||||
RecordAccess {
|
RecordAccess {
|
||||||
record_var,
|
record_var,
|
||||||
ext_var,
|
ext_var,
|
||||||
|
@ -3233,6 +3242,9 @@ pub(crate) fn get_lookup_symbols(expr: &Expr) -> Vec<ExpectLookup> {
|
||||||
Expr::Tuple { elems, .. } => {
|
Expr::Tuple { elems, .. } => {
|
||||||
stack.extend(elems.iter().map(|(_, elem)| &elem.value));
|
stack.extend(elems.iter().map(|(_, elem)| &elem.value));
|
||||||
}
|
}
|
||||||
|
Expr::ImportParams(loc_expr, _) => {
|
||||||
|
stack.push(&loc_expr.value);
|
||||||
|
}
|
||||||
Expr::Expect {
|
Expr::Expect {
|
||||||
loc_continuation, ..
|
loc_continuation, ..
|
||||||
}
|
}
|
||||||
|
|
|
@ -1254,6 +1254,14 @@ fn fix_values_captured_in_closure_expr(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImportParams(loc_expr, _) => {
|
||||||
|
fix_values_captured_in_closure_expr(
|
||||||
|
&mut loc_expr.value,
|
||||||
|
no_capture_symbols,
|
||||||
|
closure_captures,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Tuple { elems, .. } => {
|
Tuple { elems, .. } => {
|
||||||
for (_var, expr) in elems.iter_mut() {
|
for (_var, expr) in elems.iter_mut() {
|
||||||
fix_values_captured_in_closure_expr(
|
fix_values_captured_in_closure_expr(
|
||||||
|
|
|
@ -318,6 +318,7 @@ pub fn walk_expr<V: Visitor>(visitor: &mut V, expr: &Expr, var: Variable) {
|
||||||
.iter()
|
.iter()
|
||||||
.for_each(|(var, elem)| visitor.visit_expr(&elem.value, elem.region, *var)),
|
.for_each(|(var, elem)| visitor.visit_expr(&elem.value, elem.region, *var)),
|
||||||
Expr::EmptyRecord => { /* terminal */ }
|
Expr::EmptyRecord => { /* terminal */ }
|
||||||
|
Expr::ImportParams(expr, _) => visitor.visit_expr(&expr.value, expr.region, var),
|
||||||
Expr::RecordAccess {
|
Expr::RecordAccess {
|
||||||
field_var,
|
field_var,
|
||||||
loc_expr,
|
loc_expr,
|
||||||
|
|
|
@ -577,7 +577,7 @@ pub fn constrain_expr(
|
||||||
}
|
}
|
||||||
ParamsVar {
|
ParamsVar {
|
||||||
symbol,
|
symbol,
|
||||||
params,
|
params: _,
|
||||||
var,
|
var,
|
||||||
} => {
|
} => {
|
||||||
// Save the expectation in the variable, then lookup the symbol's type in the environment
|
// Save the expectation in the variable, then lookup the symbol's type in the environment
|
||||||
|
@ -586,11 +586,12 @@ pub fn constrain_expr(
|
||||||
|
|
||||||
let lookup_constr = constraints.lookup(*symbol, expected, region);
|
let lookup_constr = constraints.lookup(*symbol, expected, region);
|
||||||
|
|
||||||
// todo(agus): check params
|
|
||||||
// let params_constr = constraints.lookup(*params, expected, region);
|
|
||||||
|
|
||||||
constraints.and_constraint([store_expected, lookup_constr])
|
constraints.and_constraint([store_expected, lookup_constr])
|
||||||
}
|
}
|
||||||
|
ImportParams(params, module_id) => {
|
||||||
|
// todo(agus): constrain
|
||||||
|
Constraint::True
|
||||||
|
}
|
||||||
&AbilityMember(symbol, specialization_id, specialization_var) => {
|
&AbilityMember(symbol, specialization_id, specialization_var) => {
|
||||||
// Save the expectation in the `specialization_var` so we know what to specialize, then
|
// Save the expectation in the `specialization_var` so we know what to specialize, then
|
||||||
// lookup the member in the environment.
|
// lookup the member in the environment.
|
||||||
|
@ -4105,6 +4106,7 @@ fn is_generalizable_expr(mut expr: &Expr) -> bool {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
OpaqueRef { argument, .. } => expr = &argument.1.value,
|
OpaqueRef { argument, .. } => expr = &argument.1.value,
|
||||||
|
ImportParams(loc_expr, _) => expr = &loc_expr.value,
|
||||||
Str(_)
|
Str(_)
|
||||||
| IngestedFile(..)
|
| IngestedFile(..)
|
||||||
| List { .. }
|
| List { .. }
|
||||||
|
|
|
@ -4425,6 +4425,15 @@ pub fn with_hole<'a>(
|
||||||
ParamsVar { .. } => {
|
ParamsVar { .. } => {
|
||||||
todo!("agus: handle params var")
|
todo!("agus: handle params var")
|
||||||
}
|
}
|
||||||
|
ImportParams(loc_expr, _) => with_hole(
|
||||||
|
env,
|
||||||
|
loc_expr.value,
|
||||||
|
variable,
|
||||||
|
procs,
|
||||||
|
layout_cache,
|
||||||
|
assigned,
|
||||||
|
hole,
|
||||||
|
),
|
||||||
AbilityMember(member, specialization_id, specialization_var) => {
|
AbilityMember(member, specialization_id, specialization_var) => {
|
||||||
let specialization_symbol = late_resolve_ability_specialization(
|
let specialization_symbol = late_resolve_ability_specialization(
|
||||||
env,
|
env,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue