mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
Move unexpected params warning to solve
This commit is contained in:
parent
63e722f61d
commit
0cbb352a89
18 changed files with 115 additions and 169 deletions
|
@ -297,12 +297,13 @@ fn deep_copy_expr_help<C: CopyEnv>(env: &mut C, copied: &mut Vec<Variable>, expr
|
|||
params: *params,
|
||||
var: sub!(*var),
|
||||
},
|
||||
ImportParams(loc_expr, var, module_id) => ImportParams(
|
||||
Box::new(loc_expr.map(|e| go_help!(e))),
|
||||
sub!(*var),
|
||||
ImportParams(module_id, region, opt_provided) => ImportParams(
|
||||
*module_id,
|
||||
*region,
|
||||
opt_provided
|
||||
.as_ref()
|
||||
.map(|(var, expr)| (sub!(*var), Box::new(go_help!(&expr)))),
|
||||
),
|
||||
MissingImportParams(module_id, region) => MissingImportParams(*module_id, *region),
|
||||
&AbilityMember(sym, specialization, specialization_var) => {
|
||||
AbilityMember(sym, specialization, sub!(specialization_var))
|
||||
}
|
||||
|
|
|
@ -209,9 +209,9 @@ fn expr<'a>(c: &Ctx, p: EPrec, f: &'a Arena<'a>, e: &'a Expr) -> DocBuilder<'a,
|
|||
Var(sym, _) | ParamsVar { symbol: sym, .. } | AbilityMember(sym, _, _) => {
|
||||
pp_sym(c, f, *sym)
|
||||
}
|
||||
ImportParams(loc_expr, _, _) => expr(c, p, f, &loc_expr.value),
|
||||
MissingImportParams(module_id, _) => {
|
||||
text!(f, "<missing params for {:?}>", module_id)
|
||||
ImportParams(_, _, Some((_, params_expr))) => expr(c, p, f, params_expr),
|
||||
ImportParams(module_id, _, None) => {
|
||||
text!(f, "<no params for {:?}>", module_id)
|
||||
}
|
||||
When {
|
||||
loc_cond, branches, ..
|
||||
|
|
|
@ -1153,21 +1153,12 @@ fn canonicalize_value_defs<'a>(
|
|||
exposed_symbols,
|
||||
});
|
||||
|
||||
match params {
|
||||
PendingModuleImportParams::None => {}
|
||||
PendingModuleImportParams::Required {
|
||||
symbol,
|
||||
loc_pattern,
|
||||
opt_provided,
|
||||
} => {
|
||||
pending_value_defs.push(PendingValueDef::ImportParams {
|
||||
symbol,
|
||||
loc_pattern,
|
||||
module_id,
|
||||
opt_provided,
|
||||
});
|
||||
}
|
||||
}
|
||||
pending_value_defs.push(PendingValueDef::ImportParams {
|
||||
symbol: params.symbol,
|
||||
loc_pattern: params.loc_pattern,
|
||||
opt_provided: params.opt_provided,
|
||||
module_id,
|
||||
});
|
||||
}
|
||||
PendingValue::InvalidIngestedFile => { /* skip */ }
|
||||
PendingValue::ImportNameConflict => { /* skip */ }
|
||||
|
@ -2421,7 +2412,7 @@ fn canonicalize_pending_value_def<'a>(
|
|||
.references
|
||||
.insert_value_lookup(symbol, QualifiedReference::Unqualified);
|
||||
|
||||
let (expr, references) = match opt_provided {
|
||||
let (opt_var_record, references) = match opt_provided {
|
||||
Some(params) => {
|
||||
let (record, can_output) =
|
||||
canonicalize_record(env, var_store, scope, loc_pattern.region, params);
|
||||
|
@ -2429,20 +2420,15 @@ fn canonicalize_pending_value_def<'a>(
|
|||
let references = can_output.references.clone();
|
||||
output.union(can_output);
|
||||
|
||||
let loc_record = Loc::at(loc_pattern.region, record);
|
||||
|
||||
let expr =
|
||||
Expr::ImportParams(Box::new(loc_record), var_store.fresh(), module_id);
|
||||
|
||||
(expr, references)
|
||||
(Some((var_store.fresh(), Box::new(record))), references)
|
||||
}
|
||||
None => (
|
||||
Expr::MissingImportParams(module_id, loc_pattern.region),
|
||||
References::new(),
|
||||
),
|
||||
None => (None, References::new()),
|
||||
};
|
||||
|
||||
let loc_expr = Loc::at(loc_pattern.region, expr);
|
||||
let loc_expr = Loc::at(
|
||||
loc_pattern.region,
|
||||
Expr::ImportParams(module_id, loc_pattern.region, opt_var_record),
|
||||
);
|
||||
|
||||
let def = single_can_def(
|
||||
loc_pattern,
|
||||
|
@ -3017,15 +3003,10 @@ struct PendingModuleImport<'a> {
|
|||
params: PendingModuleImportParams<'a>,
|
||||
}
|
||||
|
||||
enum PendingModuleImportParams<'a> {
|
||||
/// The module does not require any params
|
||||
None,
|
||||
/// The module requires params, they may or may not have been provided
|
||||
Required {
|
||||
symbol: Symbol,
|
||||
loc_pattern: Loc<Pattern>,
|
||||
opt_provided: Option<ast::Collection<'a, Loc<AssignedField<'a, ast::Expr<'a>>>>>,
|
||||
},
|
||||
struct PendingModuleImportParams<'a> {
|
||||
symbol: Symbol,
|
||||
loc_pattern: Loc<Pattern>,
|
||||
opt_provided: Option<ast::Collection<'a, Loc<AssignedField<'a, ast::Expr<'a>>>>>,
|
||||
}
|
||||
|
||||
pub struct IntroducedImport {
|
||||
|
@ -3178,45 +3159,27 @@ fn to_pending_value_def<'a>(
|
|||
None => module_name.clone(),
|
||||
};
|
||||
|
||||
let params = if env.modules_expecting_params.contains(&module_id) {
|
||||
let name_str = name_with_alias.as_str();
|
||||
let sym_region = module_import.params.map(|p| p.params.region).unwrap_or(region);
|
||||
|
||||
match scope.introduce_str(format!("#{name_str}").as_str(), sym_region) {
|
||||
Ok(symbol) => {
|
||||
let loc_pattern = Loc::at(sym_region, Pattern::Identifier(symbol));
|
||||
|
||||
PendingModuleImportParams::Required {
|
||||
symbol,
|
||||
loc_pattern,
|
||||
opt_provided: module_import.params.map(|p| p.params.value),
|
||||
}
|
||||
},
|
||||
Err(_) => {
|
||||
// Ignore conflict, it will be handled as a duplicate import
|
||||
PendingModuleImportParams::None
|
||||
},
|
||||
}
|
||||
// Generate a symbol for the module params def
|
||||
// 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 =
|
||||
PendingModuleImportParams {
|
||||
symbol: params_sym,
|
||||
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() {
|
||||
// Only add params to scope if they are provided
|
||||
Some(params_sym)
|
||||
} else {
|
||||
if let Some(params) = module_import.params {
|
||||
env.problems.push(Problem::UnexpectedParams {
|
||||
module_id,
|
||||
region: params.params.region,
|
||||
});
|
||||
}
|
||||
|
||||
PendingModuleImportParams::None
|
||||
};
|
||||
|
||||
let params_sym = match params {
|
||||
PendingModuleImportParams::Required { symbol, .. } => Some(symbol),
|
||||
PendingModuleImportParams::None => None,
|
||||
None
|
||||
};
|
||||
|
||||
if let Err(existing_import) =
|
||||
scope
|
||||
.modules
|
||||
.insert(name_with_alias.clone(), module_id, params_sym, region)
|
||||
.insert(name_with_alias.clone(), module_id, provided_params_sym, region)
|
||||
{
|
||||
env.problems.push(Problem::ImportNameConflict {
|
||||
name: name_with_alias,
|
||||
|
|
|
@ -21,8 +21,6 @@ pub struct Env<'a> {
|
|||
|
||||
pub qualified_module_ids: &'a PackageModuleIds<'a>,
|
||||
|
||||
pub modules_expecting_params: VecSet<ModuleId>,
|
||||
|
||||
/// Problems we've encountered along the way, which will be reported to the user at the end.
|
||||
pub problems: Vec<Problem>,
|
||||
|
||||
|
@ -51,7 +49,6 @@ impl<'a> Env<'a> {
|
|||
home: ModuleId,
|
||||
module_path: &'a Path,
|
||||
dep_idents: &'a IdentIdsByModule,
|
||||
modules_expecting_params: VecSet<ModuleId>,
|
||||
qualified_module_ids: &'a PackageModuleIds<'a>,
|
||||
opt_shorthand: Option<&'a str>,
|
||||
) -> Env<'a> {
|
||||
|
@ -60,7 +57,6 @@ impl<'a> Env<'a> {
|
|||
home,
|
||||
module_path,
|
||||
dep_idents,
|
||||
modules_expecting_params,
|
||||
qualified_module_ids,
|
||||
problems: Vec::new(),
|
||||
closures: MutMap::default(),
|
||||
|
|
|
@ -185,10 +185,7 @@ pub enum Expr {
|
|||
},
|
||||
|
||||
/// Module params expression in import
|
||||
ImportParams(Box<Loc<Expr>>, Variable, ModuleId),
|
||||
/// The imported module requires params but none were provided
|
||||
/// We delay this error until solve, so we can report the expected type
|
||||
MissingImportParams(ModuleId, Region),
|
||||
ImportParams(ModuleId, Region, Option<(Variable, Box<Expr>)>),
|
||||
|
||||
/// The "crash" keyword
|
||||
Crash {
|
||||
|
@ -342,8 +339,8 @@ impl Expr {
|
|||
Self::RecordAccessor(data) => Category::Accessor(data.field.clone()),
|
||||
Self::TupleAccess { index, .. } => Category::TupleAccess(*index),
|
||||
Self::RecordUpdate { .. } => Category::Record,
|
||||
Self::ImportParams(loc_expr, _, _) => loc_expr.value.category(),
|
||||
Self::MissingImportParams(_, _) => Category::Unknown,
|
||||
Self::ImportParams(_, _, Some((_, expr))) => expr.category(),
|
||||
Self::ImportParams(_, _, None) => Category::Unknown,
|
||||
Self::Tag {
|
||||
name, arguments, ..
|
||||
} => Category::TagApply {
|
||||
|
@ -1976,7 +1973,6 @@ pub fn inline_calls(var_store: &mut VarStore, expr: Expr) -> Expr {
|
|||
| other @ TypedHole { .. }
|
||||
| other @ ForeignCall { .. }
|
||||
| other @ OpaqueWrapFunction(_)
|
||||
| other @ MissingImportParams(_, _)
|
||||
| other @ Crash { .. } => other,
|
||||
|
||||
List {
|
||||
|
@ -2235,10 +2231,13 @@ pub fn inline_calls(var_store: &mut VarStore, expr: Expr) -> Expr {
|
|||
);
|
||||
}
|
||||
|
||||
ImportParams(loc_expr, var, module_id) => {
|
||||
let loc_expr = Loc::at(loc_expr.region, inline_calls(var_store, loc_expr.value));
|
||||
ImportParams(Box::new(loc_expr), var, module_id)
|
||||
}
|
||||
ImportParams(module_id, region, Some((var, expr))) => ImportParams(
|
||||
module_id,
|
||||
region,
|
||||
Some((var, Box::new(inline_calls(var_store, *expr)))),
|
||||
),
|
||||
|
||||
ImportParams(module_id, region, None) => ImportParams(module_id, region, None),
|
||||
|
||||
RecordAccess {
|
||||
record_var,
|
||||
|
@ -3252,8 +3251,8 @@ pub(crate) fn get_lookup_symbols(expr: &Expr) -> Vec<ExpectLookup> {
|
|||
Expr::Tuple { elems, .. } => {
|
||||
stack.extend(elems.iter().map(|(_, elem)| &elem.value));
|
||||
}
|
||||
Expr::ImportParams(loc_expr, _, _) => {
|
||||
stack.push(&loc_expr.value);
|
||||
Expr::ImportParams(_, _, Some((_, expr))) => {
|
||||
stack.push(expr);
|
||||
}
|
||||
Expr::Expect {
|
||||
loc_continuation, ..
|
||||
|
@ -3281,7 +3280,7 @@ pub(crate) fn get_lookup_symbols(expr: &Expr) -> Vec<ExpectLookup> {
|
|||
| Expr::EmptyRecord
|
||||
| Expr::TypedHole(_)
|
||||
| Expr::RuntimeError(_)
|
||||
| Expr::MissingImportParams(_, _)
|
||||
| Expr::ImportParams(_, _, None)
|
||||
| Expr::OpaqueWrapFunction(_) => {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -286,7 +286,6 @@ pub fn canonicalize_module_defs<'a>(
|
|||
qualified_module_ids: &'a PackageModuleIds<'a>,
|
||||
exposed_ident_ids: IdentIds,
|
||||
dep_idents: &'a IdentIdsByModule,
|
||||
modules_expecting_params: VecSet<ModuleId>,
|
||||
aliases: MutMap<Symbol, Alias>,
|
||||
imported_abilities_state: PendingAbilitiesStore,
|
||||
initial_scope: MutMap<Ident, (Symbol, Region)>,
|
||||
|
@ -312,7 +311,6 @@ pub fn canonicalize_module_defs<'a>(
|
|||
home,
|
||||
arena.alloc(Path::new(module_path)),
|
||||
dep_idents,
|
||||
modules_expecting_params,
|
||||
qualified_module_ids,
|
||||
opt_shorthand,
|
||||
);
|
||||
|
@ -1153,7 +1151,6 @@ fn fix_values_captured_in_closure_expr(
|
|||
| TypedHole { .. }
|
||||
| RuntimeError(_)
|
||||
| ZeroArgumentTag { .. }
|
||||
| MissingImportParams(_, _)
|
||||
| RecordAccessor { .. } => {}
|
||||
|
||||
List { loc_elems, .. } => {
|
||||
|
@ -1260,14 +1257,12 @@ 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,
|
||||
);
|
||||
ImportParams(_, _, Some((_, expr))) => {
|
||||
fix_values_captured_in_closure_expr(expr, no_capture_symbols, closure_captures);
|
||||
}
|
||||
|
||||
ImportParams(_, _, None) => {}
|
||||
|
||||
Tuple { elems, .. } => {
|
||||
for (_var, expr) in elems.iter_mut() {
|
||||
fix_values_captured_in_closure_expr(
|
||||
|
|
|
@ -318,7 +318,8 @@ pub fn walk_expr<V: Visitor>(visitor: &mut V, expr: &Expr, var: Variable) {
|
|||
.iter()
|
||||
.for_each(|(var, elem)| visitor.visit_expr(&elem.value, elem.region, *var)),
|
||||
Expr::EmptyRecord => { /* terminal */ }
|
||||
Expr::ImportParams(expr, _, _) => visitor.visit_expr(&expr.value, expr.region, var),
|
||||
Expr::ImportParams(_, region, Some((_, expr))) => visitor.visit_expr(expr, *region, var),
|
||||
Expr::ImportParams(_, _, None) => { /* terminal */ }
|
||||
Expr::RecordAccess {
|
||||
field_var,
|
||||
loc_expr,
|
||||
|
@ -404,7 +405,6 @@ pub fn walk_expr<V: Visitor>(visitor: &mut V, expr: &Expr, var: Variable) {
|
|||
}
|
||||
Expr::TypedHole(_) => { /* terminal */ }
|
||||
Expr::RuntimeError(..) => { /* terminal */ }
|
||||
Expr::MissingImportParams(..) => { /* terminal */ }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue