mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Merge branch 'main' into inline-imports
This commit is contained in:
commit
a8a829aadd
201 changed files with 1128 additions and 1523 deletions
|
@ -752,10 +752,11 @@ fn can_annotation_help(
|
|||
|
||||
for loc_var in *loc_vars {
|
||||
let var = match loc_var.value {
|
||||
Pattern::Identifier {
|
||||
ident: name,
|
||||
suffixed: _,
|
||||
} if name.chars().next().unwrap().is_lowercase() => name,
|
||||
Pattern::Identifier { ident: name, .. }
|
||||
if name.chars().next().unwrap().is_lowercase() =>
|
||||
{
|
||||
name
|
||||
}
|
||||
_ => unreachable!("I thought this was validated during parsing"),
|
||||
};
|
||||
let var_name = Lowercase::from(var);
|
||||
|
|
|
@ -558,11 +558,7 @@ fn canonicalize_claimed_ability_impl<'a>(
|
|||
}
|
||||
AssignedField::RequiredValue(label, _spaces, value) => {
|
||||
let impl_ident = match value.value {
|
||||
ast::Expr::Var {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed: _,
|
||||
} => {
|
||||
ast::Expr::Var { module_name, ident } => {
|
||||
if module_name.is_empty() {
|
||||
ident
|
||||
} else {
|
||||
|
@ -2612,14 +2608,15 @@ pub fn report_unused_imports(
|
|||
) {
|
||||
for import in imports_introduced {
|
||||
if references.has_module_lookup(import.module_id) {
|
||||
for (symbol, region) in import.exposed_symbols {
|
||||
if !references.has_unqualified_type_or_value_lookup(symbol)
|
||||
&& !scope.abilities_store.is_specialization_name(symbol)
|
||||
for (symbol, region) in &import.exposed_symbols {
|
||||
if !references.has_unqualified_type_or_value_lookup(*symbol)
|
||||
&& !scope.abilities_store.is_specialization_name(*symbol)
|
||||
&& !import.is_task(env)
|
||||
{
|
||||
env.problem(Problem::UnusedImport(symbol, region));
|
||||
env.problem(Problem::UnusedImport(*symbol, *region));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if !import.is_task(env) {
|
||||
env.problem(Problem::UnusedModuleImport(import.module_id, import.region));
|
||||
}
|
||||
}
|
||||
|
@ -2692,10 +2689,9 @@ fn to_pending_alias_or_opaque<'a>(
|
|||
|
||||
for loc_var in vars.iter() {
|
||||
match loc_var.value {
|
||||
ast::Pattern::Identifier {
|
||||
ident: name,
|
||||
suffixed: _,
|
||||
} if name.chars().next().unwrap().is_lowercase() => {
|
||||
ast::Pattern::Identifier { ident: name, .. }
|
||||
if name.chars().next().unwrap().is_lowercase() =>
|
||||
{
|
||||
let lowercase = Lowercase::from(name);
|
||||
can_rigids.push(Loc {
|
||||
value: lowercase,
|
||||
|
@ -2890,6 +2886,16 @@ pub struct IntroducedImport {
|
|||
exposed_symbols: Vec<(Symbol, Region)>,
|
||||
}
|
||||
|
||||
impl IntroducedImport {
|
||||
pub fn is_task(&self, env: &Env<'_>) -> bool {
|
||||
// Temporarily needed for `!` convenience. Can be removed when Task becomes a builtin.
|
||||
match env.qualified_module_ids.get_name(self.module_id) {
|
||||
Some(name) => name.as_inner().as_str() == "Task",
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn to_pending_value_def<'a>(
|
||||
env: &mut Env<'a>,
|
||||
|
|
|
@ -25,10 +25,7 @@ fn to_encoder<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
|||
opaque_ref,
|
||||
&*env.arena.alloc([Loc::at(
|
||||
DERIVED_REGION,
|
||||
ast::Pattern::Identifier {
|
||||
ident: payload,
|
||||
suffixed: 0,
|
||||
},
|
||||
ast::Pattern::Identifier { ident: payload },
|
||||
)]),
|
||||
);
|
||||
|
||||
|
@ -37,12 +34,10 @@ fn to_encoder<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
|||
alloc_expr(ast::Expr::Var {
|
||||
module_name: "Encode",
|
||||
ident: "toEncoder",
|
||||
suffixed: 0,
|
||||
}),
|
||||
&*env.arena.alloc([&*alloc_expr(ast::Expr::Var {
|
||||
module_name: "",
|
||||
ident: payload,
|
||||
suffixed: 0,
|
||||
})]),
|
||||
roc_module::called_via::CalledVia::Space,
|
||||
));
|
||||
|
@ -67,23 +62,19 @@ fn decoder<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
|||
alloc_expr(ast::Expr::Var {
|
||||
module_name: "Decode",
|
||||
ident: "decodeWith",
|
||||
suffixed: 0,
|
||||
}),
|
||||
env.arena.alloc([
|
||||
&*alloc_expr(ast::Expr::Var {
|
||||
module_name: "",
|
||||
ident: bytes,
|
||||
suffixed: 0,
|
||||
}),
|
||||
alloc_expr(ast::Expr::Var {
|
||||
module_name: "Decode",
|
||||
ident: "decoder",
|
||||
suffixed: 0,
|
||||
}),
|
||||
alloc_expr(ast::Expr::Var {
|
||||
module_name: "",
|
||||
ident: fmt,
|
||||
suffixed: 0,
|
||||
}),
|
||||
]),
|
||||
CalledVia::Space,
|
||||
|
@ -94,7 +85,6 @@ fn decoder<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
|||
alloc_expr(ast::Expr::Var {
|
||||
module_name: "Decode",
|
||||
ident: "mapResult",
|
||||
suffixed: 0,
|
||||
}),
|
||||
env.arena.alloc([
|
||||
&*alloc_expr(call_decode_with),
|
||||
|
@ -107,20 +97,8 @@ fn decoder<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
|||
// Decode.mapResult (Decode.decodeWith bytes Decode.decoder fmt) @Opaq
|
||||
let custom_closure = ast::Expr::Closure(
|
||||
env.arena.alloc([
|
||||
Loc::at(
|
||||
DERIVED_REGION,
|
||||
ast::Pattern::Identifier {
|
||||
ident: bytes,
|
||||
suffixed: 0,
|
||||
},
|
||||
),
|
||||
Loc::at(
|
||||
DERIVED_REGION,
|
||||
ast::Pattern::Identifier {
|
||||
ident: fmt,
|
||||
suffixed: 0,
|
||||
},
|
||||
),
|
||||
Loc::at(DERIVED_REGION, ast::Pattern::Identifier { ident: bytes }),
|
||||
Loc::at(DERIVED_REGION, ast::Pattern::Identifier { ident: fmt }),
|
||||
]),
|
||||
alloc_expr(call_map_result),
|
||||
);
|
||||
|
@ -130,7 +108,6 @@ fn decoder<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
|||
alloc_expr(ast::Expr::Var {
|
||||
module_name: "Decode",
|
||||
ident: "custom",
|
||||
suffixed: 0,
|
||||
}),
|
||||
env.arena.alloc([&*alloc_expr(custom_closure)]),
|
||||
CalledVia::Space,
|
||||
|
@ -153,10 +130,7 @@ fn hash<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
|||
opaque_ref,
|
||||
&*env.arena.alloc([Loc::at(
|
||||
DERIVED_REGION,
|
||||
ast::Pattern::Identifier {
|
||||
ident: payload,
|
||||
suffixed: 0,
|
||||
},
|
||||
ast::Pattern::Identifier { ident: payload },
|
||||
)]),
|
||||
);
|
||||
|
||||
|
@ -165,18 +139,15 @@ fn hash<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
|||
alloc_expr(ast::Expr::Var {
|
||||
module_name: "Hash",
|
||||
ident: "hash",
|
||||
suffixed: 0,
|
||||
}),
|
||||
&*env.arena.alloc([
|
||||
&*alloc_expr(ast::Expr::Var {
|
||||
module_name: "",
|
||||
ident: hasher,
|
||||
suffixed: 0,
|
||||
}),
|
||||
&*alloc_expr(ast::Expr::Var {
|
||||
module_name: "",
|
||||
ident: payload,
|
||||
suffixed: 0,
|
||||
}),
|
||||
]),
|
||||
roc_module::called_via::CalledVia::Space,
|
||||
|
@ -185,13 +156,7 @@ fn hash<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
|||
// \hasher, @Opaq payload -> Hash.hash hasher payload
|
||||
ast::Expr::Closure(
|
||||
env.arena.alloc([
|
||||
Loc::at(
|
||||
DERIVED_REGION,
|
||||
ast::Pattern::Identifier {
|
||||
ident: hasher,
|
||||
suffixed: 0,
|
||||
},
|
||||
),
|
||||
Loc::at(DERIVED_REGION, ast::Pattern::Identifier { ident: hasher }),
|
||||
Loc::at(DERIVED_REGION, opaque_apply_pattern),
|
||||
]),
|
||||
call_member,
|
||||
|
@ -211,10 +176,7 @@ fn is_eq<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
|||
opaque_ref,
|
||||
&*env.arena.alloc([Loc::at(
|
||||
DERIVED_REGION,
|
||||
ast::Pattern::Identifier {
|
||||
ident: payload1,
|
||||
suffixed: 0,
|
||||
},
|
||||
ast::Pattern::Identifier { ident: payload1 },
|
||||
)]),
|
||||
);
|
||||
// \@Opaq payload2
|
||||
|
@ -222,10 +184,7 @@ fn is_eq<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
|||
opaque_ref,
|
||||
&*env.arena.alloc([Loc::at(
|
||||
DERIVED_REGION,
|
||||
ast::Pattern::Identifier {
|
||||
ident: payload2,
|
||||
suffixed: 0,
|
||||
},
|
||||
ast::Pattern::Identifier { ident: payload2 },
|
||||
)]),
|
||||
);
|
||||
|
||||
|
@ -234,18 +193,15 @@ fn is_eq<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
|||
alloc_expr(ast::Expr::Var {
|
||||
module_name: "Bool",
|
||||
ident: "isEq",
|
||||
suffixed: 0,
|
||||
}),
|
||||
&*env.arena.alloc([
|
||||
&*alloc_expr(ast::Expr::Var {
|
||||
module_name: "",
|
||||
ident: payload1,
|
||||
suffixed: 0,
|
||||
}),
|
||||
&*alloc_expr(ast::Expr::Var {
|
||||
module_name: "",
|
||||
ident: payload2,
|
||||
suffixed: 0,
|
||||
}),
|
||||
]),
|
||||
roc_module::called_via::CalledVia::Space,
|
||||
|
@ -274,10 +230,7 @@ fn to_inspector<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
|||
opaque_ref,
|
||||
&*env.arena.alloc([Loc::at(
|
||||
DERIVED_REGION,
|
||||
ast::Pattern::Identifier {
|
||||
ident: payload,
|
||||
suffixed: 0,
|
||||
},
|
||||
ast::Pattern::Identifier { ident: payload },
|
||||
)]),
|
||||
);
|
||||
|
||||
|
@ -286,12 +239,10 @@ fn to_inspector<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
|||
alloc_expr(ast::Expr::Var {
|
||||
module_name: "Inspect",
|
||||
ident: "toInspector",
|
||||
suffixed: 0,
|
||||
}),
|
||||
&*env.arena.alloc([&*alloc_expr(ast::Expr::Var {
|
||||
module_name: "",
|
||||
ident: payload,
|
||||
suffixed: 0,
|
||||
})]),
|
||||
roc_module::called_via::CalledVia::Space,
|
||||
));
|
||||
|
@ -306,7 +257,6 @@ fn to_inspector<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
|||
alloc_expr(ast::Expr::Var {
|
||||
module_name: "Inspect",
|
||||
ident: "tag",
|
||||
suffixed: 0,
|
||||
}),
|
||||
&*env.arena.alloc([&*opaque_name, &*to_inspector_list]),
|
||||
roc_module::called_via::CalledVia::Space,
|
||||
|
@ -319,14 +269,12 @@ fn to_inspector<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
|||
alloc_expr(ast::Expr::Var {
|
||||
module_name: "Inspect",
|
||||
ident: "apply",
|
||||
suffixed: 0,
|
||||
}),
|
||||
&*env.arena.alloc([
|
||||
&*opaque_inspector,
|
||||
&*alloc_expr(ast::Expr::Var {
|
||||
module_name: "",
|
||||
ident: fmt,
|
||||
suffixed: 0,
|
||||
}),
|
||||
]),
|
||||
roc_module::called_via::CalledVia::Space,
|
||||
|
@ -335,10 +283,7 @@ fn to_inspector<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
|||
let custom_closure = alloc_expr(ast::Expr::Closure(
|
||||
env.arena.alloc([Loc::at(
|
||||
DERIVED_REGION,
|
||||
ast::Pattern::Identifier {
|
||||
ident: fmt,
|
||||
suffixed: 0,
|
||||
},
|
||||
ast::Pattern::Identifier { ident: fmt },
|
||||
)]),
|
||||
apply_opaque_inspector,
|
||||
));
|
||||
|
@ -348,7 +293,6 @@ fn to_inspector<'a>(env: &mut Env<'a>, at_opaque: &'a str) -> ast::Expr<'a> {
|
|||
alloc_expr(ast::Expr::Var {
|
||||
module_name: "Inspect",
|
||||
ident: "custom",
|
||||
suffixed: 0,
|
||||
}),
|
||||
env.arena.alloc([&*custom_closure]),
|
||||
CalledVia::Space,
|
||||
|
|
|
@ -9,8 +9,8 @@ use roc_module::called_via::{BinOp, CalledVia};
|
|||
use roc_module::ident::ModuleName;
|
||||
use roc_parse::ast::Expr::{self, *};
|
||||
use roc_parse::ast::{
|
||||
wrap_in_task_ok, AssignedField, Collection, Pattern, RecordBuilderField, StrLiteral,
|
||||
StrSegment, ValueDef, WhenBranch,
|
||||
AssignedField, Collection, Pattern, RecordBuilderField, StrLiteral, StrSegment, ValueDef,
|
||||
WhenBranch,
|
||||
};
|
||||
use roc_region::all::{LineInfo, Loc, Region};
|
||||
|
||||
|
@ -57,11 +57,7 @@ fn new_op_call_expr<'a>(
|
|||
let args = arena.alloc([left, right]);
|
||||
|
||||
let loc_expr = arena.alloc(Loc {
|
||||
value: Expr::Var {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed: 0,
|
||||
},
|
||||
value: Expr::Var { module_name, ident },
|
||||
region: loc_op.region,
|
||||
});
|
||||
|
||||
|
@ -200,13 +196,7 @@ pub fn desugar_value_def_suffixed<'a>(arena: &'a Bump, value_def: ValueDef<'a>)
|
|||
arena,
|
||||
Body(
|
||||
loc_pattern,
|
||||
apply_task_await(
|
||||
arena,
|
||||
loc_expr.region,
|
||||
sub_arg,
|
||||
sub_pat,
|
||||
wrap_in_task_ok(arena, sub_new),
|
||||
),
|
||||
apply_task_await(arena, loc_expr.region, sub_arg, sub_pat, sub_new),
|
||||
),
|
||||
),
|
||||
Err(..) => Body(
|
||||
|
@ -248,7 +238,7 @@ pub fn desugar_value_def_suffixed<'a>(arena: &'a Bump, value_def: ValueDef<'a>)
|
|||
body_expr.region,
|
||||
sub_arg,
|
||||
sub_pat,
|
||||
wrap_in_task_ok(arena, sub_new),
|
||||
sub_new,
|
||||
),
|
||||
},
|
||||
),
|
||||
|
@ -349,6 +339,15 @@ pub fn desugar_expr<'a>(
|
|||
|
||||
arena.alloc(Loc { region, value })
|
||||
}
|
||||
// desugar the sub_expression, but leave the TaskAwaitBang as this will
|
||||
// be unwrapped later in desugar_value_def_suffixed
|
||||
TaskAwaitBang(sub_expr) => {
|
||||
let intermediate = arena.alloc(Loc::at(loc_expr.region, **sub_expr));
|
||||
let new_sub_loc_expr = desugar_expr(arena, intermediate, src, line_info, module_path);
|
||||
let new_sub_expr = arena.alloc(new_sub_loc_expr.value);
|
||||
|
||||
arena.alloc(Loc::at(loc_expr.region, TaskAwaitBang(new_sub_expr)))
|
||||
}
|
||||
RecordAccess(sub_expr, paths) => {
|
||||
let region = loc_expr.region;
|
||||
let loc_sub_expr = Loc {
|
||||
|
@ -608,12 +607,10 @@ pub fn desugar_expr<'a>(
|
|||
Negate => Var {
|
||||
module_name: ModuleName::NUM,
|
||||
ident: "neg",
|
||||
suffixed: 0,
|
||||
},
|
||||
Not => Var {
|
||||
module_name: ModuleName::BOOL,
|
||||
ident: "not",
|
||||
suffixed: 0,
|
||||
},
|
||||
};
|
||||
let loc_fn_var = arena.alloc(Loc { region, value });
|
||||
|
@ -711,7 +708,6 @@ pub fn desugar_expr<'a>(
|
|||
let inspect_fn = Var {
|
||||
module_name: ModuleName::INSPECT,
|
||||
ident: "toStr",
|
||||
suffixed: 0,
|
||||
};
|
||||
let loc_inspect_fn_var = arena.alloc(Loc {
|
||||
value: inspect_fn,
|
||||
|
@ -766,7 +762,6 @@ pub fn desugar_expr<'a>(
|
|||
Expr::Var {
|
||||
module_name: ModuleName::TASK,
|
||||
ident: "ok",
|
||||
suffixed: 0,
|
||||
},
|
||||
)),
|
||||
arena.alloc(apply_args),
|
||||
|
@ -862,7 +857,6 @@ fn desugar_field<'a>(
|
|||
value: Var {
|
||||
module_name: "",
|
||||
ident: loc_str.value,
|
||||
suffixed: 0,
|
||||
},
|
||||
region: loc_str.region,
|
||||
};
|
||||
|
@ -1043,7 +1037,6 @@ fn record_builder_arg<'a>(
|
|||
value: Expr::Var {
|
||||
module_name: "",
|
||||
ident: arena.alloc("#".to_owned() + label.value),
|
||||
suffixed: 0,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -1083,10 +1076,7 @@ fn record_builder_arg<'a>(
|
|||
|
||||
for label in apply_field_names.iter().rev() {
|
||||
let name = arena.alloc("#".to_owned() + label.value);
|
||||
let ident = roc_parse::ast::Pattern::Identifier {
|
||||
ident: name,
|
||||
suffixed: 0,
|
||||
};
|
||||
let ident = roc_parse::ast::Pattern::Identifier { ident: name };
|
||||
|
||||
let arg_pattern = arena.alloc(Loc {
|
||||
value: ident,
|
||||
|
|
|
@ -977,11 +977,9 @@ pub fn canonicalize_expr<'a>(
|
|||
(expr, output)
|
||||
}
|
||||
}
|
||||
ast::Expr::Var {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed: _, // TODO should we use suffixed here?
|
||||
} => canonicalize_var_lookup(env, var_store, scope, module_name, ident, region),
|
||||
ast::Expr::Var { module_name, ident } => {
|
||||
canonicalize_var_lookup(env, var_store, scope, module_name, ident, region)
|
||||
}
|
||||
ast::Expr::Underscore(name) => {
|
||||
// we parse underscores, but they are not valid expression syntax
|
||||
|
||||
|
@ -1129,6 +1127,7 @@ pub fn canonicalize_expr<'a>(
|
|||
output,
|
||||
)
|
||||
}
|
||||
ast::Expr::TaskAwaitBang(..) => internal_error!("a Expr::TaskAwaitBang expression was not completed removed in desugar_value_def_suffixed"),
|
||||
ast::Expr::Tag(tag) => {
|
||||
let variant_var = var_store.fresh();
|
||||
let ext_var = var_store.fresh();
|
||||
|
@ -2427,7 +2426,8 @@ pub fn is_valid_interpolation(expr: &ast::Expr<'_>) -> bool {
|
|||
| ast::Expr::Closure(_, loc_expr) => is_valid_interpolation(&loc_expr.value),
|
||||
ast::Expr::TupleAccess(sub_expr, _)
|
||||
| ast::Expr::ParensAround(sub_expr)
|
||||
| ast::Expr::RecordAccess(sub_expr, _) => is_valid_interpolation(sub_expr),
|
||||
| ast::Expr::RecordAccess(sub_expr, _)
|
||||
| ast::Expr::TaskAwaitBang(sub_expr) => is_valid_interpolation(sub_expr),
|
||||
ast::Expr::Apply(loc_expr, args, _called_via) => {
|
||||
is_valid_interpolation(&loc_expr.value)
|
||||
&& args
|
||||
|
|
|
@ -265,10 +265,7 @@ pub fn canonicalize_def_header_pattern<'a>(
|
|||
|
||||
match pattern {
|
||||
// Identifiers that shadow ability members may appear (and may only appear) at the header of a def.
|
||||
Identifier {
|
||||
ident: name,
|
||||
suffixed: _,
|
||||
} => {
|
||||
Identifier { ident: name } => {
|
||||
match scope.introduce_or_shadow_ability_member(
|
||||
pending_abilities_in_scope,
|
||||
(*name).into(),
|
||||
|
@ -376,13 +373,12 @@ pub fn canonicalize_pattern<'a>(
|
|||
use PatternType::*;
|
||||
|
||||
let can_pattern = match pattern {
|
||||
Identifier {
|
||||
ident: name,
|
||||
suffixed: _,
|
||||
} => match canonicalize_pattern_symbol(env, scope, output, region, permit_shadows, name) {
|
||||
Ok(symbol) => Pattern::Identifier(symbol),
|
||||
Err(pattern) => pattern,
|
||||
},
|
||||
Identifier { ident: name } => {
|
||||
match canonicalize_pattern_symbol(env, scope, output, region, permit_shadows, name) {
|
||||
Ok(symbol) => Pattern::Identifier(symbol),
|
||||
Err(pattern) => pattern,
|
||||
}
|
||||
}
|
||||
Underscore(name) => {
|
||||
// An underscored identifier can't be used, but we'll still add it to the scope
|
||||
// for better error messages if someone tries to use it.
|
||||
|
@ -635,10 +631,7 @@ pub fn canonicalize_pattern<'a>(
|
|||
|
||||
for loc_pattern in patterns.iter() {
|
||||
match loc_pattern.value {
|
||||
Identifier {
|
||||
ident: label,
|
||||
suffixed: _,
|
||||
} => {
|
||||
Identifier { ident: label } => {
|
||||
match scope.introduce(label.into(), region) {
|
||||
Ok(symbol) => {
|
||||
output.references.insert_bound(symbol);
|
||||
|
|
|
@ -57,13 +57,11 @@ impl Scope {
|
|||
initial_ident_ids: IdentIds,
|
||||
starting_abilities_store: PendingAbilitiesStore,
|
||||
) -> Scope {
|
||||
let default_imports =
|
||||
// Add all `Apply` types.
|
||||
(Symbol::apply_types_in_scope().into_iter())
|
||||
// Add all tag names we might want to suggest as hints in error messages.
|
||||
.chain(Symbol::symbols_in_scope_for_hints());
|
||||
|
||||
let default_imports = default_imports.map(|(a, (b, c))| (a, b, c)).collect();
|
||||
// Add all `Apply` types.
|
||||
let default_imports = Symbol::apply_types_in_scope()
|
||||
.into_iter()
|
||||
.map(|(a, (b, c))| (a, b, c))
|
||||
.collect();
|
||||
|
||||
Scope {
|
||||
home,
|
||||
|
@ -742,13 +740,7 @@ mod test {
|
|||
|
||||
assert_eq!(
|
||||
&idents,
|
||||
&[
|
||||
Ident::from("Str"),
|
||||
Ident::from("List"),
|
||||
Ident::from("Box"),
|
||||
Ident::from("Ok"),
|
||||
Ident::from("Err"),
|
||||
]
|
||||
&[Ident::from("Str"), Ident::from("List"), Ident::from("Box"),]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -766,13 +758,7 @@ mod test {
|
|||
|
||||
assert_eq!(
|
||||
&idents,
|
||||
&[
|
||||
Ident::from("Str"),
|
||||
Ident::from("List"),
|
||||
Ident::from("Box"),
|
||||
Ident::from("Ok"),
|
||||
Ident::from("Err"),
|
||||
]
|
||||
&[Ident::from("Str"), Ident::from("List"), Ident::from("Box"),]
|
||||
);
|
||||
|
||||
let builtin_count = idents.len();
|
||||
|
|
|
@ -6,7 +6,7 @@ use roc_error_macros::internal_error;
|
|||
use roc_module::called_via::CalledVia;
|
||||
use roc_module::ident::ModuleName;
|
||||
use roc_parse::ast::Expr::{self, *};
|
||||
use roc_parse::ast::{is_loc_expr_suffixed, wrap_in_task_ok, Pattern, ValueDef, WhenBranch};
|
||||
use roc_parse::ast::{is_expr_suffixed, Pattern, ValueDef, WhenBranch};
|
||||
use roc_region::all::{Loc, Region};
|
||||
use std::cell::Cell;
|
||||
|
||||
|
@ -31,11 +31,9 @@ fn next_suffixed_answer_pattern(arena: &Bump) -> (Expr, Pattern) {
|
|||
Expr::Var {
|
||||
module_name: "",
|
||||
ident: answer_ident,
|
||||
suffixed: 0,
|
||||
},
|
||||
Pattern::Identifier {
|
||||
ident: answer_ident.as_str(),
|
||||
suffixed: 0,
|
||||
},
|
||||
)
|
||||
})
|
||||
|
@ -95,63 +93,10 @@ pub fn unwrap_suffixed_expression<'a>(
|
|||
) -> Result<&'a Loc<Expr<'a>>, EUnwrapped<'a>> {
|
||||
let unwrapped_expression = {
|
||||
match loc_expr.value {
|
||||
Expr::Var {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed,
|
||||
} => {
|
||||
match suffixed {
|
||||
0 => Ok(loc_expr),
|
||||
1 => {
|
||||
let unwrapped_var = arena.alloc(Loc::at(
|
||||
loc_expr.region,
|
||||
Expr::Var {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed: suffixed.saturating_sub(1),
|
||||
},
|
||||
));
|
||||
Expr::TaskAwaitBang(sub_expr) => {
|
||||
let unwrapped_sub_expr = arena.alloc(Loc::at(loc_expr.region, *sub_expr));
|
||||
|
||||
init_unwrapped_err(arena, unwrapped_var, maybe_def_pat)
|
||||
}
|
||||
_ => {
|
||||
let unwrapped_var = arena.alloc(Loc::at(
|
||||
loc_expr.region,
|
||||
Expr::Var {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed: 0,
|
||||
},
|
||||
));
|
||||
|
||||
// we generate an intermediate pattern `#!a0` etc
|
||||
// so we dont unwrap the definition pattern
|
||||
let (mut answer_var, answer_pat) = next_suffixed_answer_pattern(arena);
|
||||
|
||||
// we transfer the suffix from the Var to the intermediate answer Var
|
||||
// as that will need to be unwrapped in a future call
|
||||
if let Expr::Var {
|
||||
module_name: "",
|
||||
ident: answer_ident,
|
||||
suffixed: 0,
|
||||
} = answer_var
|
||||
{
|
||||
answer_var = Expr::Var {
|
||||
module_name: "",
|
||||
ident: answer_ident,
|
||||
suffixed: suffixed.saturating_sub(1),
|
||||
}
|
||||
} else {
|
||||
internal_error!("expected a suffixed Var to be generated");
|
||||
}
|
||||
|
||||
Err(EUnwrapped::UnwrappedSubExpr {
|
||||
sub_arg: unwrapped_var,
|
||||
sub_pat: arena.alloc(Loc::at(unwrapped_var.region, answer_pat)),
|
||||
sub_new: arena.alloc(Loc::at(unwrapped_var.region, answer_var)),
|
||||
})
|
||||
}
|
||||
}
|
||||
init_unwrapped_err(arena, unwrapped_sub_expr, maybe_def_pat)
|
||||
}
|
||||
|
||||
Expr::Defs(..) => unwrap_suffixed_expression_defs_help(arena, loc_expr, maybe_def_pat),
|
||||
|
@ -192,8 +137,8 @@ pub fn unwrap_suffixed_expression<'a>(
|
|||
// KEEP THIS HERE FOR DEBUGGING
|
||||
// USEFUL TO SEE THE UNWRAPPING
|
||||
// OF AST NODES AS THEY DESCEND
|
||||
// if is_loc_expr_suffixed(loc_expr) {
|
||||
// dbg!(&loc_expr, &unwrapped_expression);
|
||||
// if is_expr_suffixed(&loc_expr.value) {
|
||||
// dbg!(&maybe_def_pat, &loc_expr, &unwrapped_expression);
|
||||
// }
|
||||
|
||||
unwrapped_expression
|
||||
|
@ -248,18 +193,6 @@ pub fn unwrap_suffixed_expression_closure_help<'a>(
|
|||
) -> Result<&'a Loc<Expr<'a>>, EUnwrapped<'a>> {
|
||||
match loc_expr.value {
|
||||
Expr::Closure(closure_args, closure_loc_ret) => {
|
||||
|
||||
// Check to make sure that arguments are not suffixed
|
||||
let suffixed_arg_count = closure_args
|
||||
.iter()
|
||||
.filter(|loc_pat| loc_pat.value.is_suffixed())
|
||||
.count();
|
||||
|
||||
if suffixed_arg_count > 0 {
|
||||
debug_assert!(false,"closure arguments should not be suffixed");
|
||||
return Err(EUnwrapped::Malformed);
|
||||
}
|
||||
|
||||
// note we use `None` here as we don't want to pass a DefExpr up and
|
||||
// unwrap the definition pattern for the closure
|
||||
match unwrap_suffixed_expression(arena, closure_loc_ret, None) {
|
||||
|
@ -316,21 +249,15 @@ pub fn unwrap_suffixed_expression_apply_help<'a>(
|
|||
}
|
||||
|
||||
// special case for when our Apply function is a suffixed Var (but not multiple suffixed)
|
||||
if let Expr::Var { module_name, ident, suffixed } = function.value {
|
||||
if suffixed == 1 {
|
||||
let unwrapped_function = arena.alloc(Loc::at(
|
||||
loc_expr.region,
|
||||
Expr::Var {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed: suffixed - 1,
|
||||
},
|
||||
));
|
||||
if let Expr::TaskAwaitBang(sub_expr) = function.value {
|
||||
let unwrapped_function = arena.alloc(Loc::at(
|
||||
loc_expr.region,
|
||||
*sub_expr,
|
||||
));
|
||||
|
||||
let new_apply = arena.alloc(Loc::at(loc_expr.region, Expr::Apply(unwrapped_function, local_args, called_via)));
|
||||
let new_apply = arena.alloc(Loc::at(loc_expr.region, Expr::Apply(unwrapped_function, local_args, called_via)));
|
||||
|
||||
return init_unwrapped_err(arena, new_apply, maybe_def_pat);
|
||||
}
|
||||
return init_unwrapped_err(arena, new_apply, maybe_def_pat);
|
||||
}
|
||||
|
||||
// function is another expression
|
||||
|
@ -368,7 +295,7 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>(
|
|||
let (current_if_then_statement, current_if_then_expression) = if_then;
|
||||
|
||||
// unwrap suffixed (innermost) expressions e.g. `if true then doThing! then ...`
|
||||
if is_loc_expr_suffixed(current_if_then_expression) {
|
||||
if is_expr_suffixed(¤t_if_then_expression.value) {
|
||||
// split if_thens around the current index
|
||||
let (before, after) = roc_parse::ast::split_around(if_thens, index);
|
||||
|
||||
|
@ -398,13 +325,8 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>(
|
|||
sub_pat,
|
||||
sub_new,
|
||||
}) => {
|
||||
let unwrapped_expression = apply_task_await(
|
||||
arena,
|
||||
sub_arg.region,
|
||||
sub_arg,
|
||||
sub_pat,
|
||||
wrap_in_task_ok(arena, sub_new),
|
||||
);
|
||||
let unwrapped_expression =
|
||||
apply_task_await(arena, sub_arg.region, sub_arg, sub_pat, sub_new);
|
||||
|
||||
let mut new_if_thens = Vec::new_in(arena);
|
||||
|
||||
|
@ -429,7 +351,7 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>(
|
|||
// unwrap suffixed statements e.g. `if isThing! then ...`
|
||||
// note we want to split and nest if-then's so we only run Task's
|
||||
// that are required
|
||||
if is_loc_expr_suffixed(current_if_then_statement) {
|
||||
if is_expr_suffixed(¤t_if_then_statement.value) {
|
||||
// split if_thens around the current index
|
||||
let (before, after) = roc_parse::ast::split_around(if_thens, index);
|
||||
|
||||
|
@ -541,13 +463,8 @@ pub fn unwrap_suffixed_expression_if_then_else_help<'a>(
|
|||
sub_pat,
|
||||
sub_new,
|
||||
}) => {
|
||||
let unwrapped_final_else = apply_task_await(
|
||||
arena,
|
||||
sub_arg.region,
|
||||
sub_arg,
|
||||
sub_pat,
|
||||
wrap_in_task_ok(arena, sub_new),
|
||||
);
|
||||
let unwrapped_final_else =
|
||||
apply_task_await(arena, sub_arg.region, sub_arg, sub_pat, sub_new);
|
||||
|
||||
let new_if = arena.alloc(Loc::at(
|
||||
loc_expr.region,
|
||||
|
@ -579,7 +496,7 @@ pub fn unwrap_suffixed_expression_when_help<'a>(
|
|||
for (branch_index, WhenBranch{value: branch_loc_expr,patterns, guard}) in branches.iter().enumerate() {
|
||||
|
||||
// if the branch isn't suffixed we can leave it alone
|
||||
if is_loc_expr_suffixed(branch_loc_expr) {
|
||||
if is_expr_suffixed(&branch_loc_expr.value) {
|
||||
let unwrapped_branch_value = match unwrap_suffixed_expression(arena, branch_loc_expr, None) {
|
||||
Ok(unwrapped_branch_value) => unwrapped_branch_value,
|
||||
Err(EUnwrapped::UnwrappedSubExpr { sub_arg, sub_pat, sub_new }) => apply_task_await(arena, branch_loc_expr.region, sub_arg, sub_pat, sub_new),
|
||||
|
@ -670,7 +587,7 @@ pub fn unwrap_suffixed_expression_defs_help<'a>(
|
|||
Ok(next_expr) => next_expr,
|
||||
Err(EUnwrapped::UnwrappedSubExpr { sub_arg, sub_pat, sub_new }) => {
|
||||
// We need to apply Task.ok here as the defs final expression was unwrapped
|
||||
apply_task_await(arena,def_expr.region,sub_arg,sub_pat,wrap_in_task_ok(arena, sub_new))
|
||||
apply_task_await(arena,def_expr.region,sub_arg,sub_pat,sub_new)
|
||||
}
|
||||
Err(EUnwrapped::UnwrappedDefExpr(..)) | Err(EUnwrapped::Malformed) => {
|
||||
// TODO handle case when we have maybe_def_pat so can return an unwrapped up
|
||||
|
@ -816,7 +733,6 @@ pub fn apply_task_await<'a>(
|
|||
value: Var {
|
||||
module_name: ModuleName::TASK,
|
||||
ident: "await",
|
||||
suffixed: 0,
|
||||
},
|
||||
}),
|
||||
arena.alloc(task_await_apply_args),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue