mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-11 18:58:24 +03:00
Merge branch 'main' into inline-imports
This commit is contained in:
commit
a8a829aadd
@ -14,14 +14,17 @@ jobs:
|
||||
test-and-build:
|
||||
name: Rust tests, build and package nightly release
|
||||
runs-on: [self-hosted, macOS, ARM64]
|
||||
env:
|
||||
LIBRARY_PATH: /opt/homebrew/Cellar/zstd/1.5.6/lib
|
||||
timeout-minutes: 90
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- run: zig version
|
||||
- name: Update PATH to use zig 11
|
||||
run: |
|
||||
echo "PATH=/Users/m1ci/Downloads/zig-macos-aarch64-0.11.0:$PATH" >> $GITHUB_ENV
|
||||
|
||||
- name: llvm version
|
||||
run: llc --version | grep LLVM
|
||||
- run: zig version
|
||||
|
||||
- name: run tests
|
||||
run: cargo test --locked --release
|
||||
|
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -2502,12 +2502,14 @@ dependencies = [
|
||||
"roc_module",
|
||||
"roc_packaging",
|
||||
"roc_parse",
|
||||
"roc_problem",
|
||||
"roc_region",
|
||||
"roc_reporting",
|
||||
"roc_solve",
|
||||
"roc_target",
|
||||
"roc_types",
|
||||
"snafu",
|
||||
"ven_pretty",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -54,6 +54,7 @@ mod cli_run {
|
||||
const OPTIMIZE_FLAG: &str = concatcp!("--", roc_cli::FLAG_OPTIMIZE);
|
||||
const LINKER_FLAG: &str = concatcp!("--", roc_cli::FLAG_LINKER);
|
||||
const CHECK_FLAG: &str = concatcp!("--", roc_cli::FLAG_CHECK);
|
||||
#[allow(dead_code)]
|
||||
const PREBUILT_PLATFORM: &str = concatcp!("--", roc_cli::FLAG_PREBUILT);
|
||||
#[allow(dead_code)]
|
||||
const TARGET_FLAG: &str = concatcp!("--", roc_cli::FLAG_TARGET);
|
||||
@ -1025,20 +1026,21 @@ mod cli_run {
|
||||
// TODO not sure if this cfg should still be here: #[cfg(not(debug_assertions))]
|
||||
// this is for testing the benchmarks, to perform proper benchmarks see crates/cli/benches/README.md
|
||||
mod test_benchmarks {
|
||||
#[allow(unused_imports)]
|
||||
use super::{TestCliCommands, UseValgrind};
|
||||
use cli_utils::helpers::cli_testing_dir;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use super::{check_output_with_stdin, OPTIMIZE_FLAG, PREBUILT_PLATFORM};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use std::{path::Path, sync::Once};
|
||||
|
||||
static BENCHMARKS_BUILD_PLATFORM: Once = Once::new();
|
||||
|
||||
fn test_benchmark(
|
||||
roc_filename: &str,
|
||||
stdin: &[&str],
|
||||
expected_ending: &str,
|
||||
use_valgrind: UseValgrind,
|
||||
_use_valgrind: UseValgrind,
|
||||
) {
|
||||
let file_name = cli_testing_dir("benchmarks").join(roc_filename);
|
||||
|
||||
@ -1062,15 +1064,18 @@ mod cli_run {
|
||||
}
|
||||
|
||||
#[cfg(all(not(feature = "wasm32-cli-run"), not(feature = "i386-cli-run")))]
|
||||
check_output_regular(&file_name, stdin, expected_ending, use_valgrind);
|
||||
check_output_regular(&file_name, stdin, expected_ending, _use_valgrind);
|
||||
|
||||
#[cfg(feature = "wasm32-cli-run")]
|
||||
check_output_wasm(&file_name, stdin, expected_ending);
|
||||
|
||||
#[cfg(feature = "i386-cli-run")]
|
||||
check_output_i386(&file_name, stdin, expected_ending, use_valgrind);
|
||||
check_output_i386(&file_name, stdin, expected_ending, _use_valgrind);
|
||||
}
|
||||
|
||||
#[cfg(all(not(feature = "wasm32-cli-run"), not(feature = "i386-cli-run")))]
|
||||
static BENCHMARKS_BUILD_PLATFORM: Once = Once::new();
|
||||
|
||||
#[cfg(all(not(feature = "wasm32-cli-run"), not(feature = "i386-cli-run")))]
|
||||
fn check_output_regular(
|
||||
file_name: &Path,
|
||||
|
@ -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),
|
||||
|
File diff suppressed because one or more lines are too long
@ -9,7 +9,7 @@ use crate::spaces::{
|
||||
use crate::Buf;
|
||||
use roc_module::called_via::{self, BinOp};
|
||||
use roc_parse::ast::{
|
||||
is_loc_expr_suffixed, AssignedField, Base, Collection, CommentOrNewline, Expr, ExtractSpaces,
|
||||
is_expr_suffixed, AssignedField, Base, Collection, CommentOrNewline, Expr, ExtractSpaces,
|
||||
Pattern, RecordBuilderField, WhenBranch,
|
||||
};
|
||||
use roc_parse::ast::{StrLiteral, StrSegment};
|
||||
@ -38,9 +38,7 @@ impl<'a> Formattable for Expr<'a> {
|
||||
| Num(..)
|
||||
| NonBase10Int { .. }
|
||||
| SingleQuote(_)
|
||||
| RecordAccess(_, _)
|
||||
| AccessorFunction(_)
|
||||
| TupleAccess(_, _)
|
||||
| Var { .. }
|
||||
| Underscore { .. }
|
||||
| MalformedIdent(_, _)
|
||||
@ -50,6 +48,10 @@ impl<'a> Formattable for Expr<'a> {
|
||||
| EmptyDefsFinal
|
||||
| Crash => false,
|
||||
|
||||
RecordAccess(inner, _) | TupleAccess(inner, _) | TaskAwaitBang(inner) => {
|
||||
inner.is_multiline()
|
||||
}
|
||||
|
||||
// These expressions always have newlines
|
||||
Defs(_, _) | When(_, _) => true,
|
||||
|
||||
@ -169,11 +171,7 @@ impl<'a> Formattable for Expr<'a> {
|
||||
Str(literal) => {
|
||||
fmt_str_literal(buf, *literal, indent);
|
||||
}
|
||||
Var {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed,
|
||||
} => {
|
||||
Var { module_name, ident } => {
|
||||
buf.indent(indent);
|
||||
if !module_name.is_empty() {
|
||||
buf.push_str(module_name);
|
||||
@ -181,11 +179,6 @@ impl<'a> Formattable for Expr<'a> {
|
||||
}
|
||||
|
||||
buf.push_str(ident);
|
||||
|
||||
let count: u8 = *suffixed;
|
||||
for _ in 0..count {
|
||||
buf.push('!');
|
||||
}
|
||||
}
|
||||
Underscore(name) => {
|
||||
buf.indent(indent);
|
||||
@ -511,60 +504,18 @@ impl<'a> Formattable for Expr<'a> {
|
||||
}
|
||||
}
|
||||
RecordAccess(expr, key) => {
|
||||
// Check for any `!` suffixes and format these at the end of expression
|
||||
let (expr_to_format, suffix_count) = if let Var {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed,
|
||||
} = expr
|
||||
{
|
||||
(
|
||||
Var {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed: 0,
|
||||
},
|
||||
suffixed,
|
||||
)
|
||||
} else {
|
||||
(**expr, &0u8)
|
||||
};
|
||||
|
||||
expr_to_format.format_with_options(buf, Parens::InApply, Newlines::Yes, indent);
|
||||
expr.format_with_options(buf, Parens::InApply, Newlines::Yes, indent);
|
||||
buf.push('.');
|
||||
buf.push_str(key);
|
||||
|
||||
for _ in 0..*suffix_count {
|
||||
buf.push('!');
|
||||
}
|
||||
}
|
||||
TupleAccess(expr, key) => {
|
||||
// Check for any `!` suffixes and format these at the end of expression
|
||||
let (expr_to_format, suffix_count) = if let Var {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed,
|
||||
} = expr
|
||||
{
|
||||
(
|
||||
Var {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed: 0,
|
||||
},
|
||||
suffixed,
|
||||
)
|
||||
} else {
|
||||
(**expr, &0u8)
|
||||
};
|
||||
|
||||
expr_to_format.format_with_options(buf, Parens::InApply, Newlines::Yes, indent);
|
||||
expr.format_with_options(buf, Parens::InApply, Newlines::Yes, indent);
|
||||
buf.push('.');
|
||||
buf.push_str(key);
|
||||
|
||||
for _ in 0..*suffix_count {
|
||||
buf.push('!');
|
||||
}
|
||||
}
|
||||
TaskAwaitBang(expr) => {
|
||||
expr.format_with_options(buf, Parens::InApply, Newlines::Yes, indent);
|
||||
buf.push('!');
|
||||
}
|
||||
MalformedIdent(str, _) => {
|
||||
buf.indent(indent);
|
||||
@ -787,8 +738,8 @@ fn fmt_binops<'a>(
|
||||
|| loc_right_side.value.is_multiline()
|
||||
|| lefts.iter().any(|(expr, _)| expr.value.is_multiline());
|
||||
|
||||
let is_any_lefts_suffixed = lefts.iter().any(|(left, _)| is_loc_expr_suffixed(left));
|
||||
let is_right_suffixed = is_loc_expr_suffixed(loc_right_side);
|
||||
let is_any_lefts_suffixed = lefts.iter().any(|(left, _)| is_expr_suffixed(&left.value));
|
||||
let is_right_suffixed = is_expr_suffixed(&loc_right_side.value);
|
||||
let is_any_suffixed = is_any_lefts_suffixed || is_right_suffixed;
|
||||
|
||||
let mut is_first = false;
|
||||
|
@ -88,16 +88,9 @@ impl<'a> Formattable for Pattern<'a> {
|
||||
use self::Pattern::*;
|
||||
|
||||
match self {
|
||||
Identifier {
|
||||
ident: string,
|
||||
suffixed,
|
||||
} => {
|
||||
Identifier { ident: string } => {
|
||||
buf.indent(indent);
|
||||
buf.push_str(string);
|
||||
|
||||
for _ in 0..*suffixed {
|
||||
buf.push('!');
|
||||
}
|
||||
}
|
||||
Tag(name) | OpaqueRef(name) => {
|
||||
buf.indent(indent);
|
||||
@ -277,21 +270,13 @@ impl<'a> Formattable for Pattern<'a> {
|
||||
buf.indent(indent);
|
||||
buf.push_str(string);
|
||||
}
|
||||
QualifiedIdentifier {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed,
|
||||
} => {
|
||||
QualifiedIdentifier { module_name, ident } => {
|
||||
buf.indent(indent);
|
||||
if !module_name.is_empty() {
|
||||
buf.push_str(module_name);
|
||||
buf.push('.');
|
||||
}
|
||||
|
||||
for _ in 0..*suffixed {
|
||||
buf.push('!');
|
||||
}
|
||||
|
||||
buf.push_str(ident);
|
||||
}
|
||||
}
|
||||
|
@ -738,6 +738,7 @@ impl<'a> RemoveSpaces<'a> for Expr<'a> {
|
||||
Expr::RecordAccess(a, b) => Expr::RecordAccess(arena.alloc(a.remove_spaces(arena)), b),
|
||||
Expr::AccessorFunction(a) => Expr::AccessorFunction(a),
|
||||
Expr::TupleAccess(a, b) => Expr::TupleAccess(arena.alloc(a.remove_spaces(arena)), b),
|
||||
Expr::TaskAwaitBang(a) => Expr::TaskAwaitBang(arena.alloc(a.remove_spaces(arena))),
|
||||
Expr::List(a) => Expr::List(a.remove_spaces(arena)),
|
||||
Expr::RecordUpdate { update, fields } => Expr::RecordUpdate {
|
||||
update: arena.alloc(update.remove_spaces(arena)),
|
||||
@ -746,15 +747,7 @@ impl<'a> RemoveSpaces<'a> for Expr<'a> {
|
||||
Expr::Record(a) => Expr::Record(a.remove_spaces(arena)),
|
||||
Expr::RecordBuilder(a) => Expr::RecordBuilder(a.remove_spaces(arena)),
|
||||
Expr::Tuple(a) => Expr::Tuple(a.remove_spaces(arena)),
|
||||
Expr::Var {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed,
|
||||
} => Expr::Var {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed,
|
||||
},
|
||||
Expr::Var { module_name, ident } => Expr::Var { module_name, ident },
|
||||
Expr::Underscore(a) => Expr::Underscore(a),
|
||||
Expr::Tag(a) => Expr::Tag(a),
|
||||
Expr::OpaqueRef(a) => Expr::OpaqueRef(a),
|
||||
@ -854,7 +847,7 @@ fn remove_spaces_bad_ident(ident: BadIdent) -> BadIdent {
|
||||
impl<'a> RemoveSpaces<'a> for Pattern<'a> {
|
||||
fn remove_spaces(&self, arena: &'a Bump) -> Self {
|
||||
match *self {
|
||||
Pattern::Identifier { ident, suffixed } => Pattern::Identifier { ident, suffixed },
|
||||
Pattern::Identifier { ident } => Pattern::Identifier { ident },
|
||||
Pattern::Tag(a) => Pattern::Tag(a),
|
||||
Pattern::OpaqueRef(a) => Pattern::OpaqueRef(a),
|
||||
Pattern::Apply(a, b) => Pattern::Apply(
|
||||
@ -887,15 +880,9 @@ impl<'a> RemoveSpaces<'a> for Pattern<'a> {
|
||||
Pattern::Underscore(a) => Pattern::Underscore(a),
|
||||
Pattern::Malformed(a) => Pattern::Malformed(a),
|
||||
Pattern::MalformedIdent(a, b) => Pattern::MalformedIdent(a, remove_spaces_bad_ident(b)),
|
||||
Pattern::QualifiedIdentifier {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed,
|
||||
} => Pattern::QualifiedIdentifier {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed,
|
||||
},
|
||||
Pattern::QualifiedIdentifier { module_name, ident } => {
|
||||
Pattern::QualifiedIdentifier { module_name, ident }
|
||||
}
|
||||
Pattern::SpaceBefore(a, _) => a.remove_spaces(arena),
|
||||
Pattern::SpaceAfter(a, _) => a.remove_spaces(arena),
|
||||
Pattern::SingleQuote(a) => Pattern::SingleQuote(a),
|
||||
|
@ -647,7 +647,7 @@ mod test_reporting {
|
||||
if true then 1 else 2
|
||||
"
|
||||
),
|
||||
@r"
|
||||
@r###"
|
||||
── UNRECOGNIZED NAME in /code/proj/Main.roc ────────────────────────────────────
|
||||
|
||||
Nothing is named `true` in this scope.
|
||||
@ -657,11 +657,11 @@ mod test_reporting {
|
||||
|
||||
Did you mean one of these?
|
||||
|
||||
Str
|
||||
Frac
|
||||
Num
|
||||
Str
|
||||
Err
|
||||
"
|
||||
U8
|
||||
"###
|
||||
);
|
||||
|
||||
test_report!(
|
||||
@ -812,10 +812,10 @@ mod test_reporting {
|
||||
|
||||
Did you mean one of these?
|
||||
|
||||
Ok
|
||||
List
|
||||
Err
|
||||
Box
|
||||
Str
|
||||
isDisabled
|
||||
"
|
||||
),
|
||||
);
|
||||
@ -2212,10 +2212,10 @@ mod test_reporting {
|
||||
|
||||
Did you mean one of these?
|
||||
|
||||
Ok
|
||||
U8
|
||||
Box
|
||||
Eq
|
||||
f
|
||||
"
|
||||
);
|
||||
|
||||
@ -5805,9 +5805,9 @@ All branches in an `if` must have the same type!
|
||||
Did you mean one of these?
|
||||
|
||||
Str
|
||||
Err
|
||||
U8
|
||||
F64
|
||||
Box
|
||||
"###
|
||||
);
|
||||
|
||||
|
@ -212,11 +212,7 @@ fn generate_entry_docs(
|
||||
match either_index.split() {
|
||||
Err(value_index) => match &defs.value_defs[value_index.index()] {
|
||||
ValueDef::Annotation(loc_pattern, loc_ann) => {
|
||||
if let Pattern::Identifier {
|
||||
ident: identifier,
|
||||
suffixed: _,
|
||||
} = loc_pattern.value
|
||||
{
|
||||
if let Pattern::Identifier { ident: identifier } = loc_pattern.value {
|
||||
// Check if this module exposes the def
|
||||
if let Some(ident_id) = ident_ids.get_id(identifier) {
|
||||
let name = identifier.to_string();
|
||||
@ -237,11 +233,7 @@ fn generate_entry_docs(
|
||||
ann_type,
|
||||
..
|
||||
} => {
|
||||
if let Pattern::Identifier {
|
||||
ident: identifier,
|
||||
suffixed: _,
|
||||
} = ann_pattern.value
|
||||
{
|
||||
if let Pattern::Identifier { ident: identifier } = ann_pattern.value {
|
||||
// Check if this module exposes the def
|
||||
if let Some(ident_id) = ident_ids.get_id(identifier) {
|
||||
let doc_def = DocDef {
|
||||
@ -257,11 +249,7 @@ fn generate_entry_docs(
|
||||
}
|
||||
|
||||
ValueDef::Body(pattern, _) => {
|
||||
if let Pattern::Identifier {
|
||||
ident: identifier,
|
||||
suffixed: _,
|
||||
} = pattern.value
|
||||
{
|
||||
if let Pattern::Identifier { ident: identifier } = pattern.value {
|
||||
// Check if this module exposes the def
|
||||
if let Some(ident_id) = ident_ids.get_id(identifier) {
|
||||
let doc_def = DocDef {
|
||||
@ -322,11 +310,7 @@ fn generate_entry_docs(
|
||||
let mut type_vars = Vec::new();
|
||||
|
||||
for var in vars.iter() {
|
||||
if let Pattern::Identifier {
|
||||
ident: ident_name,
|
||||
suffixed: _,
|
||||
} = var.value
|
||||
{
|
||||
if let Pattern::Identifier { ident: ident_name } = var.value {
|
||||
type_vars.push(ident_name.to_string());
|
||||
}
|
||||
}
|
||||
@ -360,11 +344,7 @@ fn generate_entry_docs(
|
||||
let mut type_vars = Vec::new();
|
||||
|
||||
for var in vars.iter() {
|
||||
if let Pattern::Identifier {
|
||||
ident: ident_name,
|
||||
suffixed: _,
|
||||
} = var.value
|
||||
{
|
||||
if let Pattern::Identifier { ident: ident_name } = var.value {
|
||||
type_vars.push(ident_name.to_string());
|
||||
}
|
||||
}
|
||||
@ -388,11 +368,7 @@ fn generate_entry_docs(
|
||||
let mut type_vars = Vec::new();
|
||||
|
||||
for var in vars.iter() {
|
||||
if let Pattern::Identifier {
|
||||
ident: ident_name,
|
||||
suffixed: _,
|
||||
} = var.value
|
||||
{
|
||||
if let Pattern::Identifier { ident: ident_name } = var.value {
|
||||
type_vars.push(ident_name.to_string());
|
||||
}
|
||||
}
|
||||
@ -654,7 +630,7 @@ fn type_to_docs(in_func_type_ann: bool, type_annotation: ast::TypeAnnotation) ->
|
||||
.vars
|
||||
.iter()
|
||||
.filter_map(|loc_pattern| match loc_pattern.value {
|
||||
ast::Pattern::Identifier { ident, suffixed: _ } => Some(ident.to_string()),
|
||||
ast::Pattern::Identifier { ident } => Some(ident.to_string()),
|
||||
_ => None,
|
||||
})
|
||||
.collect(),
|
||||
|
@ -3291,6 +3291,7 @@ fn finish(
|
||||
|
||||
LoadedModule {
|
||||
module_id: state.root_id,
|
||||
filename: state.root_path,
|
||||
interns,
|
||||
solved,
|
||||
can_problems: state.module_cache.can_problems,
|
||||
|
@ -30,6 +30,7 @@ use std::time::{Duration, Instant};
|
||||
#[derive(Debug)]
|
||||
pub struct LoadedModule {
|
||||
pub module_id: ModuleId,
|
||||
pub filename: PathBuf,
|
||||
pub interns: Interns,
|
||||
pub solved: Solved<Subs>,
|
||||
pub can_problems: MutMap<ModuleId, Vec<roc_problem::can::Problem>>,
|
||||
@ -54,6 +55,13 @@ pub struct LoadedModule {
|
||||
}
|
||||
|
||||
impl LoadedModule {
|
||||
/// Infer the filename for the given ModuleId, based on this root module's filename.
|
||||
pub fn filename(&self, module_id: ModuleId) -> PathBuf {
|
||||
let module_name = self.interns.module_name(module_id);
|
||||
|
||||
module_name.filename(&self.filename)
|
||||
}
|
||||
|
||||
pub fn total_problems(&self) -> usize {
|
||||
let mut total = 0;
|
||||
|
||||
|
@ -1613,8 +1613,8 @@ fn issue_2863_module_type_does_not_exist() {
|
||||
Did you mean one of these?
|
||||
|
||||
Decoding
|
||||
Dict
|
||||
Result
|
||||
Dict
|
||||
DecodeError
|
||||
"
|
||||
)
|
||||
|
@ -1,5 +1,8 @@
|
||||
pub use roc_ident::IdentStr;
|
||||
use std::fmt::{self, Debug};
|
||||
use std::{
|
||||
fmt::{self, Debug},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use crate::symbol::PQModuleName;
|
||||
|
||||
@ -45,6 +48,19 @@ impl<'a> QualifiedModuleName<'a> {
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct ModuleName(IdentStr);
|
||||
|
||||
impl ModuleName {
|
||||
/// Given the root module's path, infer this module's path based on its name.
|
||||
pub fn filename(&self, root_filename: impl AsRef<Path>) -> PathBuf {
|
||||
let mut answer = root_filename.as_ref().with_file_name("");
|
||||
|
||||
for part in self.split('.') {
|
||||
answer = answer.join(part);
|
||||
}
|
||||
|
||||
answer.with_extension("roc")
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for ModuleName {
|
||||
type Target = str;
|
||||
|
||||
|
@ -968,7 +968,6 @@ macro_rules! define_builtins {
|
||||
module_id.register_debug_idents(&ident_ids);
|
||||
}
|
||||
|
||||
|
||||
exposed_idents_by_module.insert(
|
||||
module_id,
|
||||
ident_ids
|
||||
@ -1134,27 +1133,6 @@ macro_rules! define_builtins {
|
||||
m => roc_error_macros::internal_error!("{:?} is not a builtin module!", m),
|
||||
}
|
||||
}
|
||||
|
||||
/// Symbols that should be added to the default scope, for hints as suggestions of
|
||||
/// names you might want to use.
|
||||
///
|
||||
/// TODO: this is a hack to get tag names to show up in error messages as suggestions,
|
||||
/// really we should be extracting tag names from candidate type aliases in scope.
|
||||
pub fn symbols_in_scope_for_hints() -> VecMap<Ident, (Symbol, Region)> {
|
||||
let mut scope = VecMap::default();
|
||||
|
||||
$(
|
||||
$(
|
||||
$(
|
||||
if $in_scope_for_hints {
|
||||
scope.insert($ident_name.into(), (Symbol::new(ModuleId::$module_const, IdentId($ident_id)), Region::zero()));
|
||||
}
|
||||
)?
|
||||
)*
|
||||
)+
|
||||
|
||||
scope
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -1552,15 +1530,13 @@ define_builtins! {
|
||||
}
|
||||
7 RESULT: "Result" => {
|
||||
0 RESULT_RESULT: "Result" exposed_type=true // the Result.Result type alias
|
||||
1 RESULT_OK: "Ok" in_scope_for_hints=true // Result.Result a e = [Ok a, Err e]
|
||||
2 RESULT_ERR: "Err" in_scope_for_hints=true // Result.Result a e = [Ok a, Err e]
|
||||
1 RESULT_IS_ERR: "isErr"
|
||||
2 RESULT_ON_ERR: "onErr"
|
||||
3 RESULT_MAP: "map"
|
||||
4 RESULT_MAP_ERR: "mapErr"
|
||||
5 RESULT_WITH_DEFAULT: "withDefault"
|
||||
6 RESULT_TRY: "try"
|
||||
7 RESULT_IS_OK: "isOk"
|
||||
8 RESULT_IS_ERR: "isErr"
|
||||
9 RESULT_ON_ERR: "onErr"
|
||||
}
|
||||
8 DICT: "Dict" => {
|
||||
0 DICT_DICT: "Dict" exposed_type=true // the Dict.Dict type alias
|
||||
|
@ -362,7 +362,7 @@ pub enum Expr<'a> {
|
||||
is_negative: bool,
|
||||
},
|
||||
|
||||
// String Literals
|
||||
/// String Literals
|
||||
Str(StrLiteral<'a>), // string without escapes in it
|
||||
/// eg 'b'
|
||||
SingleQuote(&'a str),
|
||||
@ -376,6 +376,9 @@ pub enum Expr<'a> {
|
||||
/// Look up exactly one field on a tuple, e.g. `(x, y).1`.
|
||||
TupleAccess(&'a Expr<'a>, &'a str),
|
||||
|
||||
/// Task await bang - i.e. the ! in `File.readUtf8! path`
|
||||
TaskAwaitBang(&'a Expr<'a>),
|
||||
|
||||
// Collection Literals
|
||||
List(Collection<'a, &'a Loc<Expr<'a>>>),
|
||||
|
||||
@ -395,7 +398,6 @@ pub enum Expr<'a> {
|
||||
Var {
|
||||
module_name: &'a str, // module_name will only be filled if the original Roc code stated something like `5 + SomeModule.myVar`, module_name will be blank if it was `5 + myVar`
|
||||
ident: &'a str,
|
||||
suffixed: u8, // how many `!` suffixes, for example `doTheThing!!` executes a Task that returns a Task
|
||||
},
|
||||
|
||||
Underscore(&'a str),
|
||||
@ -462,17 +464,6 @@ pub enum Expr<'a> {
|
||||
}
|
||||
|
||||
impl Expr<'_> {
|
||||
pub fn increment_var_suffix(&mut self, count: u8) {
|
||||
match self {
|
||||
Expr::Var { suffixed, .. } => {
|
||||
*suffixed += count;
|
||||
}
|
||||
_ => {
|
||||
internal_error!("increment_var_suffix called on non-Var expression");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_region_spanning_binops(&self) -> Region {
|
||||
match self {
|
||||
Expr::BinOps(firsts, last) => {
|
||||
@ -499,45 +490,43 @@ pub fn split_loc_exprs_around<'a>(
|
||||
(before, after)
|
||||
}
|
||||
|
||||
pub fn is_loc_expr_suffixed(loc_expr: &Loc<Expr>) -> bool {
|
||||
match loc_expr.value.extract_spaces().item {
|
||||
pub fn is_expr_suffixed(expr: &Expr) -> bool {
|
||||
match expr {
|
||||
// expression without arguments, `read!`
|
||||
Expr::Var { suffixed, .. } => suffixed > 0,
|
||||
Expr::Var { .. } => false,
|
||||
|
||||
Expr::TaskAwaitBang(..) => true,
|
||||
|
||||
// expression with arguments, `line! "Foo"`
|
||||
Expr::Apply(sub_loc_expr, apply_args, _) => {
|
||||
let is_function_suffixed = is_loc_expr_suffixed(sub_loc_expr);
|
||||
let any_args_suffixed = apply_args.iter().any(|arg| is_loc_expr_suffixed(arg));
|
||||
let is_function_suffixed = is_expr_suffixed(&sub_loc_expr.value);
|
||||
let any_args_suffixed = apply_args.iter().any(|arg| is_expr_suffixed(&arg.value));
|
||||
|
||||
any_args_suffixed || is_function_suffixed
|
||||
}
|
||||
|
||||
// expression in a pipeline, `"hi" |> say!`
|
||||
Expr::BinOps(firsts, last) => {
|
||||
let is_expr_suffixed = is_loc_expr_suffixed(last);
|
||||
let any_chain_suffixed = firsts
|
||||
firsts
|
||||
.iter()
|
||||
.any(|(chain_loc_expr, _)| is_loc_expr_suffixed(chain_loc_expr));
|
||||
|
||||
is_expr_suffixed || any_chain_suffixed
|
||||
.any(|(chain_loc_expr, _)| is_expr_suffixed(&chain_loc_expr.value))
|
||||
|| is_expr_suffixed(&last.value)
|
||||
}
|
||||
|
||||
// expression in a if-then-else, `if isOk! then "ok" else doSomething!`
|
||||
Expr::If(if_thens, final_else) => {
|
||||
let any_if_thens_suffixed = if_thens.iter().any(|(if_then, else_expr)| {
|
||||
is_loc_expr_suffixed(if_then) || is_loc_expr_suffixed(else_expr)
|
||||
is_expr_suffixed(&if_then.value) || is_expr_suffixed(&else_expr.value)
|
||||
});
|
||||
|
||||
is_loc_expr_suffixed(final_else) || any_if_thens_suffixed
|
||||
is_expr_suffixed(&final_else.value) || any_if_thens_suffixed
|
||||
}
|
||||
|
||||
// expression in parens `(read!)`
|
||||
Expr::ParensAround(sub_loc_expr) => {
|
||||
is_loc_expr_suffixed(&Loc::at(loc_expr.region, *sub_loc_expr))
|
||||
}
|
||||
Expr::ParensAround(sub_loc_expr) => is_expr_suffixed(sub_loc_expr),
|
||||
|
||||
// expression in a closure
|
||||
Expr::Closure(_, sub_loc_expr) => is_loc_expr_suffixed(sub_loc_expr),
|
||||
Expr::Closure(_, sub_loc_expr) => is_expr_suffixed(&sub_loc_expr.value),
|
||||
|
||||
// expressions inside a Defs
|
||||
// note we ignore the final expression as it should not be suffixed
|
||||
@ -545,35 +534,81 @@ pub fn is_loc_expr_suffixed(loc_expr: &Loc<Expr>) -> bool {
|
||||
let any_defs_suffixed = defs.tags.iter().any(|tag| match tag.split() {
|
||||
Ok(_) => false,
|
||||
Err(value_index) => match defs.value_defs[value_index.index()] {
|
||||
ValueDef::Body(_, loc_expr) => is_loc_expr_suffixed(loc_expr),
|
||||
ValueDef::AnnotatedBody { body_expr, .. } => is_loc_expr_suffixed(body_expr),
|
||||
ValueDef::Body(_, loc_expr) => is_expr_suffixed(&loc_expr.value),
|
||||
ValueDef::AnnotatedBody { body_expr, .. } => is_expr_suffixed(&body_expr.value),
|
||||
_ => false,
|
||||
},
|
||||
});
|
||||
|
||||
any_defs_suffixed
|
||||
}
|
||||
|
||||
_ => false,
|
||||
Expr::Float(_) => false,
|
||||
Expr::Num(_) => false,
|
||||
Expr::NonBase10Int { .. } => false,
|
||||
Expr::Str(_) => false,
|
||||
Expr::SingleQuote(_) => false,
|
||||
Expr::RecordAccess(a, _) => is_expr_suffixed(a),
|
||||
Expr::AccessorFunction(_) => false,
|
||||
Expr::TupleAccess(a, _) => is_expr_suffixed(a),
|
||||
Expr::List(items) => items.iter().any(|x| is_expr_suffixed(&x.value)),
|
||||
Expr::RecordUpdate { update, fields } => {
|
||||
is_expr_suffixed(&update.value)
|
||||
|| fields
|
||||
.iter()
|
||||
.any(|field| is_assigned_value_suffixed(&field.value))
|
||||
}
|
||||
Expr::Record(items) => items
|
||||
.iter()
|
||||
.any(|field| is_assigned_value_suffixed(&field.value)),
|
||||
Expr::Tuple(items) => items.iter().any(|x| is_expr_suffixed(&x.value)),
|
||||
Expr::RecordBuilder(items) => items
|
||||
.iter()
|
||||
.any(|rbf| is_record_builder_field_suffixed(&rbf.value)),
|
||||
Expr::Underscore(_) => false,
|
||||
Expr::Crash => false,
|
||||
Expr::Tag(_) => false,
|
||||
Expr::OpaqueRef(_) => false,
|
||||
Expr::EmptyDefsFinal => false,
|
||||
Expr::Backpassing(_, _, _) => false, // TODO: we might want to check this?
|
||||
Expr::Expect(a, b) | Expr::Dbg(a, b) => {
|
||||
is_expr_suffixed(&a.value) || is_expr_suffixed(&b.value)
|
||||
}
|
||||
Expr::LowLevelDbg(_, _, _) => todo!(),
|
||||
Expr::UnaryOp(a, _) => is_expr_suffixed(&a.value),
|
||||
Expr::When(a, _) => is_expr_suffixed(&a.value),
|
||||
Expr::SpaceBefore(a, _) => is_expr_suffixed(a),
|
||||
Expr::SpaceAfter(a, _) => is_expr_suffixed(a),
|
||||
Expr::MalformedIdent(_, _) => false,
|
||||
Expr::MalformedClosure => false,
|
||||
Expr::MalformedSuffixed(_) => false,
|
||||
Expr::PrecedenceConflict(_) => false,
|
||||
Expr::MultipleRecordBuilders(_) => false,
|
||||
Expr::UnappliedRecordBuilder(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wrap_in_task_ok<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc<Expr<'a>> {
|
||||
arena.alloc(Loc::at(
|
||||
loc_expr.region,
|
||||
Expr::Apply(
|
||||
arena.alloc(Loc::at(
|
||||
loc_expr.region,
|
||||
Expr::Var {
|
||||
module_name: roc_module::ident::ModuleName::TASK,
|
||||
ident: "ok",
|
||||
suffixed: 0,
|
||||
},
|
||||
)),
|
||||
arena.alloc([loc_expr]),
|
||||
CalledVia::BangSuffix,
|
||||
),
|
||||
))
|
||||
fn is_assigned_value_suffixed<'a>(value: &AssignedField<'a, Expr<'a>>) -> bool {
|
||||
match value {
|
||||
AssignedField::RequiredValue(_, _, a) | AssignedField::OptionalValue(_, _, a) => {
|
||||
is_expr_suffixed(&a.value)
|
||||
}
|
||||
AssignedField::LabelOnly(_) => false,
|
||||
AssignedField::SpaceBefore(a, _) | AssignedField::SpaceAfter(a, _) => {
|
||||
is_assigned_value_suffixed(a)
|
||||
}
|
||||
AssignedField::Malformed(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_record_builder_field_suffixed(field: &RecordBuilderField<'_>) -> bool {
|
||||
match field {
|
||||
RecordBuilderField::Value(_, _, a) => is_expr_suffixed(&a.value),
|
||||
RecordBuilderField::ApplyValue(_, _, _, a) => is_expr_suffixed(&a.value),
|
||||
RecordBuilderField::LabelOnly(_) => false,
|
||||
RecordBuilderField::SpaceBefore(a, _) => is_record_builder_field_suffixed(a),
|
||||
RecordBuilderField::SpaceAfter(a, _) => is_record_builder_field_suffixed(a),
|
||||
RecordBuilderField::Malformed(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn split_around<T>(items: &[T], target: usize) -> (&[T], &[T]) {
|
||||
@ -799,8 +834,6 @@ impl<'a, 'b> RecursiveValueDefIter<'a, 'b> {
|
||||
// gets to their parent def.
|
||||
expr_stack.push(&cont.value);
|
||||
}
|
||||
RecordAccess(expr, _) => expr_stack.push(expr),
|
||||
TupleAccess(expr, _) => expr_stack.push(expr),
|
||||
List(list) => {
|
||||
expr_stack.reserve(list.len());
|
||||
for loc_expr in list.items {
|
||||
@ -899,11 +932,16 @@ impl<'a, 'b> RecursiveValueDefIter<'a, 'b> {
|
||||
}
|
||||
}
|
||||
}
|
||||
SpaceBefore(expr, _) => expr_stack.push(expr),
|
||||
SpaceAfter(expr, _) => expr_stack.push(expr),
|
||||
ParensAround(expr) => expr_stack.push(expr),
|
||||
MultipleRecordBuilders(expr) => expr_stack.push(&expr.value),
|
||||
UnappliedRecordBuilder(expr) => expr_stack.push(&expr.value),
|
||||
RecordAccess(expr, _)
|
||||
| TupleAccess(expr, _)
|
||||
| TaskAwaitBang(expr)
|
||||
| SpaceBefore(expr, _)
|
||||
| SpaceAfter(expr, _)
|
||||
| ParensAround(expr) => expr_stack.push(expr),
|
||||
|
||||
MultipleRecordBuilders(loc_expr) | UnappliedRecordBuilder(loc_expr) => {
|
||||
expr_stack.push(&loc_expr.value)
|
||||
}
|
||||
|
||||
Float(_)
|
||||
| Num(_)
|
||||
@ -1088,13 +1126,13 @@ impl<'a> Defs<'a> {
|
||||
..
|
||||
},
|
||||
loc_expr,
|
||||
) if collection.is_empty() && is_loc_expr_suffixed(loc_expr) => {
|
||||
) if collection.is_empty() && is_expr_suffixed(&loc_expr.value) => {
|
||||
let mut new_defs = self.clone();
|
||||
new_defs.remove_value_def(tag_index);
|
||||
|
||||
return Some((new_defs, loc_expr));
|
||||
}
|
||||
ValueDef::Stmt(loc_expr) if is_loc_expr_suffixed(loc_expr) => {
|
||||
ValueDef::Stmt(loc_expr) if is_expr_suffixed(&loc_expr.value) => {
|
||||
let mut new_defs = self.clone();
|
||||
new_defs.remove_value_def(tag_index);
|
||||
|
||||
@ -1517,12 +1555,10 @@ pub enum Pattern<'a> {
|
||||
// Identifier
|
||||
Identifier {
|
||||
ident: &'a str,
|
||||
suffixed: u8,
|
||||
},
|
||||
QualifiedIdentifier {
|
||||
module_name: &'a str,
|
||||
ident: &'a str,
|
||||
suffixed: u8,
|
||||
},
|
||||
|
||||
Tag(&'a str),
|
||||
@ -1640,21 +1676,11 @@ impl<'a> Pattern<'a> {
|
||||
// { x, y } : { x : Int, y ? Bool }
|
||||
// { x, y ? False } = rec
|
||||
OptionalField(x, _) => match other {
|
||||
Identifier {
|
||||
ident: y,
|
||||
suffixed: 0,
|
||||
}
|
||||
| OptionalField(y, _) => x == y,
|
||||
Identifier { ident: y } | OptionalField(y, _) => x == y,
|
||||
_ => false,
|
||||
},
|
||||
Identifier {
|
||||
ident: x,
|
||||
suffixed: a,
|
||||
} => match other {
|
||||
Identifier {
|
||||
ident: y,
|
||||
suffixed: b,
|
||||
} => x == y && a == b,
|
||||
Identifier { ident: x } => match other {
|
||||
Identifier { ident: y } => x == y,
|
||||
OptionalField(y, _) => x == y,
|
||||
_ => false,
|
||||
},
|
||||
@ -1716,15 +1742,13 @@ impl<'a> Pattern<'a> {
|
||||
QualifiedIdentifier {
|
||||
module_name: a,
|
||||
ident: x,
|
||||
suffixed: i,
|
||||
} => {
|
||||
if let QualifiedIdentifier {
|
||||
module_name: b,
|
||||
ident: y,
|
||||
suffixed: j,
|
||||
} = other
|
||||
{
|
||||
a == b && x == y && i == j
|
||||
a == b && x == y
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@ -1789,15 +1813,6 @@ impl<'a> Pattern<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// used to check if a pattern is suffixed to report as an error
|
||||
pub fn is_suffixed(&self) -> bool {
|
||||
match self {
|
||||
Pattern::Identifier { suffixed, .. } => *suffixed > 0,
|
||||
Pattern::QualifiedIdentifier { suffixed, .. } => *suffixed > 0,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Collection<'a, T> {
|
||||
@ -2054,13 +2069,11 @@ impl<'a> Expr<'a> {
|
||||
pub const REPL_OPAQUE_FUNCTION: Self = Expr::Var {
|
||||
module_name: "",
|
||||
ident: "<function>",
|
||||
suffixed: 0,
|
||||
};
|
||||
|
||||
pub const REPL_RUNTIME_CRASH: Self = Expr::Var {
|
||||
module_name: "",
|
||||
ident: "*",
|
||||
suffixed: 0,
|
||||
};
|
||||
|
||||
pub fn loc_ref(&'a self, region: Region) -> Loc<&'a Self> {
|
||||
@ -2294,7 +2307,8 @@ impl<'a> Malformed for Expr<'a> {
|
||||
Str(inner) => inner.is_malformed(),
|
||||
|
||||
RecordAccess(inner, _) |
|
||||
TupleAccess(inner, _) => inner.is_malformed(),
|
||||
TupleAccess(inner, _) |
|
||||
TaskAwaitBang(inner) => inner.is_malformed(),
|
||||
|
||||
List(items) => items.is_malformed(),
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::ast::{
|
||||
is_loc_expr_suffixed, AssignedField, Collection, CommentOrNewline, Defs, Expr, ExtractSpaces,
|
||||
is_expr_suffixed, AssignedField, Collection, CommentOrNewline, Defs, Expr, ExtractSpaces,
|
||||
Implements, ImplementsAbilities, ImportAlias, ImportAsKeyword, ImportExposingKeyword,
|
||||
ImportedModuleName, IngestedFileImport, ModuleImport, Pattern, RecordBuilderField, Spaceable,
|
||||
Spaced, Spaces, TypeAnnotation, TypeDef, TypeHeader, ValueDef,
|
||||
@ -10,7 +10,7 @@ use crate::blankspace::{
|
||||
};
|
||||
use crate::ident::{
|
||||
integer_ident, lowercase_ident, parse_ident, unqualified_ident, uppercase_ident, Accessor,
|
||||
Ident,
|
||||
Ident, Suffix,
|
||||
};
|
||||
use crate::module::module_name_help;
|
||||
use crate::parser::{
|
||||
@ -140,7 +140,7 @@ fn loc_expr_in_parens_etc_help<'a>() -> impl Parser<'a, Loc<Expr<'a>>, EExpr<'a>
|
||||
specialize_err(EExpr::InParens, loc_expr_in_parens_help()),
|
||||
record_field_access_chain()
|
||||
)),
|
||||
move |arena: &'a Bump, value: Loc<(Loc<Expr<'a>>, Vec<'a, Accessor<'a>>)>| {
|
||||
move |arena: &'a Bump, value: Loc<(Loc<Expr<'a>>, Vec<'a, Suffix<'a>>)>| {
|
||||
let Loc {
|
||||
mut region,
|
||||
value: (loc_expr, field_accesses),
|
||||
@ -161,16 +161,23 @@ fn loc_expr_in_parens_etc_help<'a>() -> impl Parser<'a, Loc<Expr<'a>>, EExpr<'a>
|
||||
)
|
||||
}
|
||||
|
||||
fn record_field_access_chain<'a>() -> impl Parser<'a, Vec<'a, Accessor<'a>>, EExpr<'a>> {
|
||||
zero_or_more!(skip_first!(
|
||||
byte(b'.', EExpr::Access),
|
||||
specialize_err(
|
||||
|_, pos| EExpr::Access(pos),
|
||||
one_of!(
|
||||
map!(lowercase_ident(), Accessor::RecordField),
|
||||
map!(integer_ident(), Accessor::TupleIndex),
|
||||
fn record_field_access_chain<'a>() -> impl Parser<'a, Vec<'a, Suffix<'a>>, EExpr<'a>> {
|
||||
zero_or_more!(one_of!(
|
||||
skip_first!(
|
||||
byte(b'.', EExpr::Access),
|
||||
specialize_err(
|
||||
|_, pos| EExpr::Access(pos),
|
||||
one_of!(
|
||||
map!(lowercase_ident(), |x| Suffix::Accessor(
|
||||
Accessor::RecordField(x)
|
||||
)),
|
||||
map!(integer_ident(), |x| Suffix::Accessor(Accessor::TupleIndex(
|
||||
x
|
||||
))),
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
map!(byte(b'!', EExpr::Access), |_| Suffix::TaskAwaitBang),
|
||||
))
|
||||
}
|
||||
|
||||
@ -193,10 +200,7 @@ fn loc_term_or_underscore_or_conditional<'a>(
|
||||
loc!(underscore_expression()),
|
||||
loc!(record_literal_help()),
|
||||
loc!(specialize_err(EExpr::List, list_literal_help())),
|
||||
loc!(map_with_arena!(
|
||||
assign_or_destructure_identifier(),
|
||||
ident_to_expr
|
||||
)),
|
||||
ident_seq(),
|
||||
)
|
||||
}
|
||||
|
||||
@ -216,10 +220,7 @@ fn loc_term_or_underscore<'a>(
|
||||
loc!(underscore_expression()),
|
||||
loc!(record_literal_help()),
|
||||
loc!(specialize_err(EExpr::List, list_literal_help())),
|
||||
loc!(map_with_arena!(
|
||||
assign_or_destructure_identifier(),
|
||||
ident_to_expr
|
||||
)),
|
||||
ident_seq(),
|
||||
)
|
||||
}
|
||||
|
||||
@ -234,13 +235,31 @@ fn loc_term<'a>(options: ExprParseOptions) -> impl Parser<'a, Loc<Expr<'a>>, EEx
|
||||
loc!(specialize_err(EExpr::Closure, closure_help(options))),
|
||||
loc!(record_literal_help()),
|
||||
loc!(specialize_err(EExpr::List, list_literal_help())),
|
||||
loc!(map_with_arena!(
|
||||
assign_or_destructure_identifier(),
|
||||
ident_to_expr
|
||||
)),
|
||||
ident_seq(),
|
||||
)
|
||||
}
|
||||
|
||||
fn ident_seq<'a>() -> impl Parser<'a, Loc<Expr<'a>>, EExpr<'a>> {
|
||||
(|arena: &'a Bump, state: State<'a>, min_indent: u32| parse_ident_seq(arena, state, min_indent))
|
||||
.trace("ident_seq")
|
||||
}
|
||||
|
||||
fn parse_ident_seq<'a>(
|
||||
arena: &'a Bump,
|
||||
state: State<'a>,
|
||||
min_indent: u32,
|
||||
) -> ParseResult<'a, Loc<Expr<'a>>, EExpr<'a>> {
|
||||
let (_, loc_ident, state) =
|
||||
loc!(assign_or_destructure_identifier()).parse(arena, state, min_indent)?;
|
||||
let expr = ident_to_expr(arena, loc_ident.value);
|
||||
let (_p, suffixes, state) = record_field_access_chain()
|
||||
.trace("record_field_access_chain")
|
||||
.parse(arena, state, min_indent)
|
||||
.map_err(|(_p, e)| (MadeProgress, e))?;
|
||||
let expr = apply_expr_access_chain(arena, expr, suffixes);
|
||||
Ok((MadeProgress, Loc::at(loc_ident.region, expr), state))
|
||||
}
|
||||
|
||||
fn underscore_expression<'a>() -> impl Parser<'a, Expr<'a>, EExpr<'a>> {
|
||||
move |arena: &'a Bump, state: State<'a>, min_indent: u32| {
|
||||
let start = state.pos();
|
||||
@ -347,7 +366,7 @@ fn expr_operator_chain<'a>(options: ExprParseOptions) -> impl Parser<'a, Expr<'a
|
||||
let initial_state = state.clone();
|
||||
let end = state.pos();
|
||||
|
||||
let new_options = if is_loc_expr_suffixed(&expr) {
|
||||
let new_options = if is_expr_suffixed(&expr.value) {
|
||||
options.set_suffixed_found()
|
||||
} else {
|
||||
options
|
||||
@ -376,7 +395,7 @@ fn expr_operator_chain<'a>(options: ExprParseOptions) -> impl Parser<'a, Expr<'a
|
||||
Ok((progress, expr, new_state)) => {
|
||||
// We need to check if we have just parsed a suffixed statement,
|
||||
// if so, this is a defs node.
|
||||
if is_loc_expr_suffixed(&Loc::at_zero(expr)) {
|
||||
if is_expr_suffixed(&expr) {
|
||||
let def_region = Region::new(end, new_state.pos());
|
||||
let value_def = ValueDef::Stmt(arena.alloc(Loc::at(def_region, expr)));
|
||||
|
||||
@ -448,7 +467,7 @@ impl<'a> ExprState<'a> {
|
||||
} else if !self.expr.value.is_tag()
|
||||
&& !self.expr.value.is_opaque()
|
||||
&& !self.arguments.is_empty()
|
||||
&& !is_loc_expr_suffixed(&self.expr)
|
||||
&& !is_expr_suffixed(&self.expr.value)
|
||||
{
|
||||
let region = Region::across_all(self.arguments.iter().map(|v| &v.region));
|
||||
|
||||
@ -688,7 +707,9 @@ pub fn parse_single_def<'a>(
|
||||
|_, loc_def_expr| -> ValueDef<'a> { ValueDef::Stmt(arena.alloc(loc_def_expr)) },
|
||||
) {
|
||||
Ok((_, Some(single_def), state)) => match single_def.type_or_value {
|
||||
Either::Second(ValueDef::Stmt(loc_expr)) if is_loc_expr_suffixed(loc_expr) => {
|
||||
Either::Second(ValueDef::Stmt(loc_expr))
|
||||
if is_expr_suffixed(&loc_expr.value) =>
|
||||
{
|
||||
Ok((MadeProgress, Some(single_def), state))
|
||||
}
|
||||
_ => Ok((NoProgress, None, initial)), // a hacky way to get expression-based error messages. TODO fix this
|
||||
@ -921,7 +942,9 @@ pub fn parse_single_def<'a>(
|
||||
|_, loc_def_expr| -> ValueDef<'a> { ValueDef::Stmt(arena.alloc(loc_def_expr)) },
|
||||
) {
|
||||
Ok((_, Some(single_def), state)) => match single_def.type_or_value {
|
||||
Either::Second(ValueDef::Stmt(loc_expr)) if is_loc_expr_suffixed(loc_expr) => {
|
||||
Either::Second(ValueDef::Stmt(loc_expr))
|
||||
if is_expr_suffixed(&loc_expr.value) =>
|
||||
{
|
||||
Ok((MadeProgress, Some(single_def), state))
|
||||
}
|
||||
_ => Ok((NoProgress, None, initial)),
|
||||
@ -1065,7 +1088,7 @@ pub fn parse_single_def_assignment<'a>(
|
||||
|
||||
// If the expression is actually a suffixed statement, then we need to continue
|
||||
// to parse the rest of the expression
|
||||
if crate::ast::is_loc_expr_suffixed(&first_loc_expr) {
|
||||
if crate::ast::is_expr_suffixed(&first_loc_expr.value) {
|
||||
let mut defs = Defs::default();
|
||||
// Take the suffixed value and make it a e.g. Body(`{}=`, Apply(Var(...)))
|
||||
// we will keep the pattern `def_loc_pattern` for the new Defs
|
||||
@ -1968,7 +1991,7 @@ fn parse_expr_operator<'a>(
|
||||
expr_state.end = new_end;
|
||||
expr_state.spaces_after = spaces;
|
||||
|
||||
let new_options = if is_loc_expr_suffixed(&new_expr) {
|
||||
let new_options = if is_expr_suffixed(&new_expr.value) {
|
||||
options.set_suffixed_found()
|
||||
} else {
|
||||
options
|
||||
@ -1987,7 +2010,7 @@ fn parse_expr_operator<'a>(
|
||||
let def_region = expr.get_region_spanning_binops();
|
||||
let mut new_expr = Loc::at(def_region, expr);
|
||||
|
||||
if is_loc_expr_suffixed(&new_expr) {
|
||||
if is_expr_suffixed(&new_expr.value) {
|
||||
// We have parsed a statement such as `"hello" |> line!`
|
||||
// put the spaces from after the operator in front of the call
|
||||
if !spaces_after_operator.is_empty() {
|
||||
@ -2100,7 +2123,7 @@ fn parse_expr_end<'a>(
|
||||
Ok((_, mut arg, state)) => {
|
||||
let new_end = state.pos();
|
||||
|
||||
let new_options = if is_loc_expr_suffixed(&arg) {
|
||||
let new_options = if is_expr_suffixed(&arg.value) {
|
||||
options.set_suffixed_found()
|
||||
} else {
|
||||
options
|
||||
@ -2290,19 +2313,11 @@ fn expr_to_pattern_help<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result<Pattern<
|
||||
}
|
||||
|
||||
let mut pat = match expr.item {
|
||||
Expr::Var {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed,
|
||||
} => {
|
||||
Expr::Var { module_name, ident } => {
|
||||
if module_name.is_empty() {
|
||||
Pattern::Identifier { ident, suffixed }
|
||||
Pattern::Identifier { ident }
|
||||
} else {
|
||||
Pattern::QualifiedIdentifier {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed,
|
||||
}
|
||||
Pattern::QualifiedIdentifier { module_name, ident }
|
||||
}
|
||||
}
|
||||
Expr::Underscore(opt_name) => Pattern::Underscore(opt_name),
|
||||
@ -2382,6 +2397,7 @@ fn expr_to_pattern_help<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result<Pattern<
|
||||
| Expr::UnappliedRecordBuilder { .. }
|
||||
| Expr::RecordUpdate { .. }
|
||||
| Expr::UnaryOp(_, _)
|
||||
| Expr::TaskAwaitBang(..)
|
||||
| Expr::Crash => return Err(()),
|
||||
|
||||
Expr::Str(string) => Pattern::StrLiteral(string),
|
||||
@ -2436,10 +2452,7 @@ fn assigned_expr_field_to_pattern_help<'a>(
|
||||
)
|
||||
}
|
||||
}
|
||||
AssignedField::LabelOnly(name) => Pattern::Identifier {
|
||||
ident: name.value,
|
||||
suffixed: 0,
|
||||
},
|
||||
AssignedField::LabelOnly(name) => Pattern::Identifier { ident: name.value },
|
||||
AssignedField::SpaceBefore(nested, spaces) => Pattern::SpaceBefore(
|
||||
arena.alloc(assigned_expr_field_to_pattern_help(arena, nested)?),
|
||||
spaces,
|
||||
@ -2944,21 +2957,13 @@ fn ident_to_expr<'a>(arena: &'a Bump, src: Ident<'a>) -> Expr<'a> {
|
||||
match src {
|
||||
Ident::Tag(string) => Expr::Tag(string),
|
||||
Ident::OpaqueRef(string) => Expr::OpaqueRef(string),
|
||||
Ident::Access {
|
||||
module_name,
|
||||
parts,
|
||||
suffixed,
|
||||
} => {
|
||||
Ident::Access { module_name, parts } => {
|
||||
let mut iter = parts.iter();
|
||||
|
||||
// The first value in the iterator is the variable name,
|
||||
// e.g. `foo` in `foo.bar.baz`
|
||||
let mut answer = match iter.next() {
|
||||
Some(Accessor::RecordField(ident)) => Expr::Var {
|
||||
module_name,
|
||||
ident,
|
||||
suffixed,
|
||||
},
|
||||
Some(Accessor::RecordField(ident)) => Expr::Var { module_name, ident },
|
||||
Some(Accessor::TupleIndex(_)) => {
|
||||
// TODO: make this state impossible to represent in Ident::Access,
|
||||
// by splitting out parts[0] into a separate field with a type of `&'a str`,
|
||||
@ -3320,13 +3325,18 @@ fn record_builder_help<'a>(
|
||||
fn apply_expr_access_chain<'a>(
|
||||
arena: &'a Bump,
|
||||
value: Expr<'a>,
|
||||
accessors: Vec<'a, Accessor<'a>>,
|
||||
accessors: Vec<'a, Suffix<'a>>,
|
||||
) -> Expr<'a> {
|
||||
accessors
|
||||
.into_iter()
|
||||
.fold(value, |value, accessor| match accessor {
|
||||
Accessor::RecordField(field) => Expr::RecordAccess(arena.alloc(value), field),
|
||||
Accessor::TupleIndex(field) => Expr::TupleAccess(arena.alloc(value), field),
|
||||
Suffix::Accessor(Accessor::RecordField(field)) => {
|
||||
Expr::RecordAccess(arena.alloc(value), field)
|
||||
}
|
||||
Suffix::Accessor(Accessor::TupleIndex(field)) => {
|
||||
Expr::TupleAccess(arena.alloc(value), field)
|
||||
}
|
||||
Suffix::TaskAwaitBang => Expr::TaskAwaitBang(arena.alloc(value)),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,6 @@ pub enum Ident<'a> {
|
||||
Access {
|
||||
module_name: &'a str,
|
||||
parts: &'a [Accessor<'a>],
|
||||
suffixed: u8,
|
||||
},
|
||||
/// `.foo { foo: 42 }` or `.1 (1, 2, 3)`
|
||||
AccessorFunction(Accessor<'a>),
|
||||
@ -193,12 +192,7 @@ pub fn parse_ident<'a>(
|
||||
match chomp_identifier_chain(arena, state.bytes(), state.pos()) {
|
||||
Ok((width, ident)) => {
|
||||
let state = advance_state!(state, width as usize)?;
|
||||
if let Ident::Access {
|
||||
module_name,
|
||||
parts,
|
||||
suffixed,
|
||||
} = ident
|
||||
{
|
||||
if let Ident::Access { module_name, parts } = ident {
|
||||
if module_name.is_empty() {
|
||||
if let Some(first) = parts.first() {
|
||||
for keyword in crate::keyword::KEYWORDS.iter() {
|
||||
@ -209,15 +203,7 @@ pub fn parse_ident<'a>(
|
||||
}
|
||||
}
|
||||
|
||||
return Ok((
|
||||
MadeProgress,
|
||||
Ident::Access {
|
||||
module_name,
|
||||
parts,
|
||||
suffixed,
|
||||
},
|
||||
state,
|
||||
));
|
||||
return Ok((MadeProgress, Ident::Access { module_name, parts }, state));
|
||||
}
|
||||
|
||||
Ok((MadeProgress, ident, state))
|
||||
@ -388,6 +374,12 @@ impl<'a> Accessor<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum Suffix<'a> {
|
||||
Accessor(Accessor<'a>),
|
||||
TaskAwaitBang,
|
||||
}
|
||||
|
||||
/// a `.foo` or `.1` accessor function
|
||||
fn chomp_accessor(buffer: &[u8], pos: Position) -> Result<Accessor, BadIdent> {
|
||||
// assumes the leading `.` has been chomped already
|
||||
@ -528,22 +520,9 @@ fn chomp_identifier_chain<'a>(
|
||||
|
||||
chomped += width as usize;
|
||||
|
||||
// Parse any `!` suffixes
|
||||
let mut suffixed = 0;
|
||||
while let Ok((ch, width)) = char::from_utf8_slice_start(&buffer[chomped..]) {
|
||||
if ch == '!' {
|
||||
suffixed += 1;
|
||||
chomped += width;
|
||||
} else {
|
||||
// we're done
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let ident = Ident::Access {
|
||||
module_name,
|
||||
parts: parts.into_bump_slice(),
|
||||
suffixed,
|
||||
};
|
||||
|
||||
Ok((chomped as u32, ident))
|
||||
@ -578,22 +557,9 @@ fn chomp_identifier_chain<'a>(
|
||||
// just one segment, starting with a lowercase letter; that's a normal identifier
|
||||
let value = unsafe { std::str::from_utf8_unchecked(&buffer[..chomped]) };
|
||||
|
||||
// Parse any `!` suffixes
|
||||
let mut suffixed = 0;
|
||||
while let Ok((ch, width)) = char::from_utf8_slice_start(&buffer[chomped..]) {
|
||||
if ch == '!' {
|
||||
suffixed += 1;
|
||||
chomped += width;
|
||||
} else {
|
||||
// we're done
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let ident = Ident::Access {
|
||||
module_name: "",
|
||||
parts: arena.alloc([Accessor::RecordField(value)]),
|
||||
suffixed,
|
||||
};
|
||||
|
||||
Ok((chomped as u32, ident))
|
||||
|
@ -12,7 +12,6 @@ use crate::string_literal::StrLikeLiteral;
|
||||
use bumpalo::collections::string::String;
|
||||
use bumpalo::collections::Vec;
|
||||
use bumpalo::Bump;
|
||||
use roc_error_macros::internal_error;
|
||||
use roc_region::all::{Loc, Region};
|
||||
|
||||
/// Different patterns are supported in different circumstances.
|
||||
@ -50,14 +49,6 @@ pub fn loc_pattern_help<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, EPattern<'a>>
|
||||
|
||||
let pattern_state = state.clone();
|
||||
|
||||
// Return early with the suffixed statement
|
||||
match pattern.value {
|
||||
Pattern::Identifier { suffixed, .. } if suffixed > 0 => {
|
||||
return Ok((MadeProgress, pattern, pattern_state))
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let (pattern_spaces, state) =
|
||||
match space0_e(EPattern::AsKeyword).parse(arena, state, min_indent) {
|
||||
Err(_) => return Ok((MadeProgress, pattern, pattern_state)),
|
||||
@ -393,46 +384,6 @@ fn loc_ident_pattern_help<'a>(
|
||||
Ok((MadeProgress, loc_pat, state))
|
||||
}
|
||||
}
|
||||
// Parse a statement that begins with a suffixed identifier, e.g. `Stdout.line! "Hello"`
|
||||
Ident::Access {
|
||||
module_name,
|
||||
parts,
|
||||
suffixed,
|
||||
..
|
||||
} if suffixed > 0 => {
|
||||
if module_name.is_empty() && parts.len() == 1 {
|
||||
if let Accessor::RecordField(var) = &parts[0] {
|
||||
Ok((
|
||||
MadeProgress,
|
||||
Loc {
|
||||
region: loc_ident.region,
|
||||
value: Pattern::Identifier {
|
||||
ident: var,
|
||||
suffixed,
|
||||
},
|
||||
},
|
||||
state,
|
||||
))
|
||||
} else {
|
||||
internal_error!("unexpected suffixed TupleIndex");
|
||||
}
|
||||
} else if let Accessor::RecordField(var) = &parts[0] {
|
||||
return Ok((
|
||||
MadeProgress,
|
||||
Loc {
|
||||
region: loc_ident.region,
|
||||
value: Pattern::QualifiedIdentifier {
|
||||
module_name,
|
||||
ident: var,
|
||||
suffixed,
|
||||
},
|
||||
},
|
||||
state,
|
||||
));
|
||||
} else {
|
||||
internal_error!("unexpected suffixed TupleIndex");
|
||||
}
|
||||
}
|
||||
Ident::Access {
|
||||
module_name, parts, ..
|
||||
} => {
|
||||
@ -451,10 +402,7 @@ fn loc_ident_pattern_help<'a>(
|
||||
MadeProgress,
|
||||
Loc {
|
||||
region: loc_ident.region,
|
||||
value: Pattern::Identifier {
|
||||
ident: var,
|
||||
suffixed: 0,
|
||||
},
|
||||
value: Pattern::Identifier { ident: var },
|
||||
},
|
||||
state,
|
||||
));
|
||||
@ -615,18 +563,9 @@ fn record_pattern_field<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, PRecord<'a>>
|
||||
None => {
|
||||
let Loc { value, region } = loc_label;
|
||||
let value = if !spaces.is_empty() {
|
||||
Pattern::SpaceAfter(
|
||||
arena.alloc(Pattern::Identifier {
|
||||
ident: value,
|
||||
suffixed: 0,
|
||||
}),
|
||||
spaces,
|
||||
)
|
||||
Pattern::SpaceAfter(arena.alloc(Pattern::Identifier { ident: value }), spaces)
|
||||
} else {
|
||||
Pattern::Identifier {
|
||||
ident: value,
|
||||
suffixed: 0,
|
||||
}
|
||||
Pattern::Identifier { ident: value }
|
||||
};
|
||||
|
||||
Ok((MadeProgress, Loc::at(region, value), state))
|
||||
|
@ -70,13 +70,7 @@ fn check_type_alias<'a>(
|
||||
var_names.reserve(vars.len());
|
||||
for var in vars {
|
||||
if let TypeAnnotation::BoundVariable(v) = var.value {
|
||||
var_names.push(Loc::at(
|
||||
var.region,
|
||||
Pattern::Identifier {
|
||||
ident: v,
|
||||
suffixed: 0,
|
||||
},
|
||||
));
|
||||
var_names.push(Loc::at(var.region, Pattern::Identifier { ident: v }));
|
||||
} else {
|
||||
return Err(ETypeInlineAlias::ArgumentNotLowercase(var.region.start()));
|
||||
}
|
||||
|
@ -175,7 +175,6 @@ mod test_parse {
|
||||
let expr = arena.alloc(Var {
|
||||
module_name: "",
|
||||
ident: "name",
|
||||
suffixed: 0,
|
||||
});
|
||||
|
||||
bumpalo::vec![in arena;
|
||||
@ -192,7 +191,6 @@ mod test_parse {
|
||||
let expr = arena.alloc(Var {
|
||||
module_name: "",
|
||||
ident: "name",
|
||||
suffixed: 0,
|
||||
});
|
||||
|
||||
bumpalo::vec![in arena;
|
||||
@ -238,7 +236,6 @@ mod test_parse {
|
||||
let expr = arena.alloc(Var {
|
||||
module_name: "",
|
||||
ident: "name",
|
||||
suffixed: 0,
|
||||
});
|
||||
|
||||
bumpalo::vec![in arena;
|
||||
@ -254,13 +251,11 @@ mod test_parse {
|
||||
let expr1 = arena.alloc(Var {
|
||||
module_name: "",
|
||||
ident: "name",
|
||||
suffixed: 0,
|
||||
});
|
||||
|
||||
let expr2 = arena.alloc(Var {
|
||||
module_name: "",
|
||||
ident: "project",
|
||||
suffixed: 0,
|
||||
});
|
||||
|
||||
bumpalo::vec![in arena;
|
||||
@ -281,13 +276,11 @@ mod test_parse {
|
||||
let expr1 = arena.alloc(Var {
|
||||
module_name: "",
|
||||
ident: "name",
|
||||
suffixed: 0,
|
||||
});
|
||||
|
||||
let expr2 = arena.alloc(Var {
|
||||
module_name: "",
|
||||
ident: "project",
|
||||
suffixed: 0,
|
||||
});
|
||||
|
||||
bumpalo::vec![in arena;
|
||||
|
@ -50,17 +50,17 @@ procedure Num.22 (#Attr.2, #Attr.3):
|
||||
let Num.275 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||
ret Num.275;
|
||||
|
||||
procedure Result.5 (Result.12, Result.13):
|
||||
let Result.39 : U8 = 1i64;
|
||||
let Result.40 : U8 = GetTagId Result.12;
|
||||
let Result.41 : Int1 = lowlevel Eq Result.39 Result.40;
|
||||
if Result.41 then
|
||||
dec Result.13;
|
||||
let Result.14 : Str = UnionAtIndex (Id 1) (Index 0) Result.12;
|
||||
ret Result.14;
|
||||
procedure Result.5 (Result.10, Result.11):
|
||||
let Result.37 : U8 = 1i64;
|
||||
let Result.38 : U8 = GetTagId Result.10;
|
||||
let Result.39 : Int1 = lowlevel Eq Result.37 Result.38;
|
||||
if Result.39 then
|
||||
dec Result.11;
|
||||
let Result.12 : Str = UnionAtIndex (Id 1) (Index 0) Result.10;
|
||||
ret Result.12;
|
||||
else
|
||||
dec Result.12;
|
||||
ret Result.13;
|
||||
dec Result.10;
|
||||
ret Result.11;
|
||||
|
||||
procedure Test.10 (Test.11):
|
||||
let Test.12 : Str = CallByName Test.2 Test.11;
|
||||
|
@ -2,7 +2,6 @@ When(
|
||||
@5-6 Var {
|
||||
module_name: "",
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
WhenBranch {
|
||||
|
@ -2,7 +2,6 @@ When(
|
||||
@5-6 Var {
|
||||
module_name: "",
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
WhenBranch {
|
||||
|
@ -4,7 +4,6 @@ BinOps(
|
||||
@0-1 Var {
|
||||
module_name: "",
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@2-3 Plus,
|
||||
),
|
||||
|
@ -18,7 +18,6 @@ Defs(
|
||||
Annotation(
|
||||
@0-3 Identifier {
|
||||
ident: "foo",
|
||||
suffixed: 0,
|
||||
},
|
||||
@6-27 TagUnion {
|
||||
ext: None,
|
||||
@ -43,7 +42,6 @@ Defs(
|
||||
AnnotatedBody {
|
||||
ann_pattern: @0-3 Identifier {
|
||||
ident: "foo",
|
||||
suffixed: 0,
|
||||
},
|
||||
ann_type: @6-27 TagUnion {
|
||||
ext: None,
|
||||
@ -67,7 +65,6 @@ Defs(
|
||||
comment: None,
|
||||
body_pattern: @28-31 Identifier {
|
||||
ident: "foo",
|
||||
suffixed: 0,
|
||||
},
|
||||
body_expr: @34-38 Tag(
|
||||
"True",
|
||||
|
@ -18,7 +18,6 @@ Defs(
|
||||
Annotation(
|
||||
@0-3 Identifier {
|
||||
ident: "foo",
|
||||
suffixed: 0,
|
||||
},
|
||||
@6-28 TagUnion {
|
||||
ext: Some(
|
||||
@ -45,7 +44,6 @@ Defs(
|
||||
AnnotatedBody {
|
||||
ann_pattern: @0-3 Identifier {
|
||||
ident: "foo",
|
||||
suffixed: 0,
|
||||
},
|
||||
ann_type: @6-28 TagUnion {
|
||||
ext: Some(
|
||||
@ -71,7 +69,6 @@ Defs(
|
||||
comment: None,
|
||||
body_pattern: @29-32 Identifier {
|
||||
ident: "foo",
|
||||
suffixed: 0,
|
||||
},
|
||||
body_expr: @35-39 Tag(
|
||||
"True",
|
||||
|
@ -20,11 +20,9 @@ Defs(
|
||||
[
|
||||
@2-3 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@5-7 Identifier {
|
||||
ident: "y",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
),
|
||||
@ -39,11 +37,9 @@ Defs(
|
||||
[
|
||||
@2-3 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@5-7 Identifier {
|
||||
ident: "y",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
),
|
||||
@ -57,11 +53,9 @@ Defs(
|
||||
[
|
||||
@17-18 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@20-21 Identifier {
|
||||
ident: "y",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
),
|
||||
@ -92,7 +86,6 @@ Defs(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
|
@ -20,7 +20,6 @@ Defs(
|
||||
vars: [
|
||||
@7-8 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -50,7 +49,6 @@ Defs(
|
||||
[
|
||||
@7-8 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
),
|
||||
@ -77,7 +75,6 @@ Defs(
|
||||
[
|
||||
@33-34 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
),
|
||||
@ -99,7 +96,6 @@ Defs(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
|
@ -20,11 +20,9 @@ Defs(
|
||||
[
|
||||
@2-3 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@5-6 Identifier {
|
||||
ident: "y",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
),
|
||||
@ -39,11 +37,9 @@ Defs(
|
||||
[
|
||||
@2-3 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@5-6 Identifier {
|
||||
ident: "y",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
),
|
||||
@ -57,11 +53,9 @@ Defs(
|
||||
[
|
||||
@17-18 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@20-21 Identifier {
|
||||
ident: "y",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
),
|
||||
@ -84,7 +78,6 @@ Defs(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
|
@ -2,23 +2,19 @@ Apply(
|
||||
@0-1 Var {
|
||||
module_name: "",
|
||||
ident: "a",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
@2-3 Var {
|
||||
module_name: "",
|
||||
ident: "b",
|
||||
suffixed: 0,
|
||||
},
|
||||
@4-5 Var {
|
||||
module_name: "",
|
||||
ident: "c",
|
||||
suffixed: 0,
|
||||
},
|
||||
@6-7 Var {
|
||||
module_name: "",
|
||||
ident: "d",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
Space,
|
||||
|
@ -2,7 +2,6 @@ Apply(
|
||||
@0-4 Var {
|
||||
module_name: "",
|
||||
ident: "whee",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
@6-8 Num(
|
||||
|
@ -3,7 +3,6 @@ Apply(
|
||||
@1-5 Var {
|
||||
module_name: "",
|
||||
ident: "whee",
|
||||
suffixed: 0,
|
||||
},
|
||||
@0-1 Negate,
|
||||
),
|
||||
@ -14,7 +13,6 @@ Apply(
|
||||
@10-13 Var {
|
||||
module_name: "",
|
||||
ident: "foo",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
Space,
|
||||
|
@ -3,7 +3,6 @@ Apply(
|
||||
@1-5 Var {
|
||||
module_name: "",
|
||||
ident: "whee",
|
||||
suffixed: 0,
|
||||
},
|
||||
@0-1 Not,
|
||||
),
|
||||
@ -14,7 +13,6 @@ Apply(
|
||||
@10-13 Var {
|
||||
module_name: "",
|
||||
ident: "foo",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
Space,
|
||||
|
@ -2,7 +2,6 @@ Apply(
|
||||
@0-4 Var {
|
||||
module_name: "",
|
||||
ident: "whee",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
@5-6 Num(
|
||||
|
@ -19,7 +19,6 @@ SpaceBefore(
|
||||
Body(
|
||||
@107-108 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@111-112 Num(
|
||||
"5",
|
||||
|
@ -2,7 +2,6 @@ RecordAccess(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "rec",
|
||||
suffixed: 0,
|
||||
},
|
||||
"field",
|
||||
)
|
||||
|
@ -1,5 +1,4 @@
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "whee",
|
||||
suffixed: 0,
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ Defs(
|
||||
Annotation(
|
||||
@0-1 Identifier {
|
||||
ident: "a",
|
||||
suffixed: 0,
|
||||
},
|
||||
@3-4 SpaceBefore(
|
||||
BoundVariable(
|
||||
|
@ -3,7 +3,6 @@ Apply(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "f",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
|
@ -4,7 +4,6 @@ BinOps(
|
||||
@0-1 Var {
|
||||
module_name: "",
|
||||
ident: "a",
|
||||
suffixed: 0,
|
||||
},
|
||||
@2-4 And,
|
||||
),
|
||||
@ -14,13 +13,11 @@ BinOps(
|
||||
[
|
||||
@6-7 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
@9-10 Var {
|
||||
module_name: "",
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
),
|
||||
[
|
||||
|
@ -4,7 +4,6 @@ BinOps(
|
||||
@0-1 Var {
|
||||
module_name: "",
|
||||
ident: "i",
|
||||
suffixed: 0,
|
||||
},
|
||||
@1-2 GreaterThan,
|
||||
),
|
||||
@ -15,13 +14,11 @@ BinOps(
|
||||
[
|
||||
@3-4 Identifier {
|
||||
ident: "s",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
@6-7 Var {
|
||||
module_name: "",
|
||||
ident: "s",
|
||||
suffixed: 0,
|
||||
},
|
||||
),
|
||||
[
|
||||
@ -33,7 +30,6 @@ BinOps(
|
||||
@9-10 Var {
|
||||
module_name: "",
|
||||
ident: "a",
|
||||
suffixed: 0,
|
||||
},
|
||||
@8-9 Negate,
|
||||
),
|
||||
|
@ -30,7 +30,6 @@ Defs(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "q",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
LineComment(
|
||||
|
@ -21,7 +21,6 @@ Defs {
|
||||
Body(
|
||||
@0-3 Identifier {
|
||||
ident: "foo",
|
||||
suffixed: 0,
|
||||
},
|
||||
@6-7 Num(
|
||||
"1",
|
||||
|
@ -3,7 +3,6 @@ ParensAround(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "i",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
LineComment(
|
||||
|
@ -22,7 +22,6 @@ Defs(
|
||||
SpaceBefore(
|
||||
Identifier {
|
||||
ident: "h",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
LineComment(
|
||||
@ -47,7 +46,6 @@ Defs(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "j",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
|
@ -19,7 +19,6 @@ Defs(
|
||||
@0-1 SpaceAfter(
|
||||
Identifier {
|
||||
ident: "w",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
LineComment(
|
||||
|
@ -19,7 +19,6 @@ Defs(
|
||||
@0-1 SpaceAfter(
|
||||
Identifier {
|
||||
ident: "t",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
LineComment(
|
||||
@ -37,7 +36,6 @@ Defs(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "e",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
|
@ -98,13 +98,11 @@ Defs(
|
||||
@50-53 Var {
|
||||
module_name: "",
|
||||
ident: "try",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
@54-57 Var {
|
||||
module_name: "",
|
||||
ident: "foo",
|
||||
suffixed: 0,
|
||||
},
|
||||
@59-73 ParensAround(
|
||||
Closure(
|
||||
|
@ -18,7 +18,6 @@ Defs(
|
||||
Annotation(
|
||||
@0-1 Identifier {
|
||||
ident: "a",
|
||||
suffixed: 0,
|
||||
},
|
||||
@2-3 BoundVariable(
|
||||
"b",
|
||||
@ -29,6 +28,5 @@ Defs(
|
||||
@4-5 Var {
|
||||
module_name: "",
|
||||
ident: "i",
|
||||
suffixed: 0,
|
||||
},
|
||||
)
|
||||
|
@ -23,7 +23,6 @@ Defs(
|
||||
[
|
||||
@6-9 Identifier {
|
||||
ident: "str",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
),
|
||||
@ -47,7 +46,6 @@ Defs(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "str",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
|
@ -19,7 +19,6 @@ SpaceBefore(
|
||||
Body(
|
||||
@48-49 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@52-53 Num(
|
||||
"5",
|
||||
|
@ -2,7 +2,6 @@ RecordUpdate {
|
||||
update: @1-2 Var {
|
||||
module_name: "",
|
||||
ident: "e",
|
||||
suffixed: 0,
|
||||
},
|
||||
fields: [],
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ BinOps(
|
||||
@0-1 Var {
|
||||
module_name: "",
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@1-3 Equals,
|
||||
),
|
||||
@ -12,6 +11,5 @@ BinOps(
|
||||
@3-4 Var {
|
||||
module_name: "",
|
||||
ident: "y",
|
||||
suffixed: 0,
|
||||
},
|
||||
)
|
||||
|
@ -4,7 +4,6 @@ BinOps(
|
||||
@0-1 Var {
|
||||
module_name: "",
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@2-4 Equals,
|
||||
),
|
||||
@ -12,6 +11,5 @@ BinOps(
|
||||
@5-6 Var {
|
||||
module_name: "",
|
||||
ident: "y",
|
||||
suffixed: 0,
|
||||
},
|
||||
)
|
||||
|
@ -33,7 +33,6 @@ Defs(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "a",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
|
@ -18,7 +18,6 @@ Defs(
|
||||
Annotation(
|
||||
@0-5 Identifier {
|
||||
ident: "table",
|
||||
suffixed: 0,
|
||||
},
|
||||
@8-44 Function(
|
||||
[
|
||||
@ -57,7 +56,6 @@ Defs(
|
||||
AnnotatedBody {
|
||||
ann_pattern: @0-5 Identifier {
|
||||
ident: "table",
|
||||
suffixed: 0,
|
||||
},
|
||||
ann_type: @8-44 Function(
|
||||
[
|
||||
@ -95,7 +93,6 @@ Defs(
|
||||
comment: None,
|
||||
body_pattern: @45-50 Identifier {
|
||||
ident: "table",
|
||||
suffixed: 0,
|
||||
},
|
||||
body_expr: @53-89 Closure(
|
||||
[
|
||||
@ -103,7 +100,6 @@ Defs(
|
||||
[
|
||||
@55-61 Identifier {
|
||||
ident: "height",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
),
|
||||
@ -127,7 +123,6 @@ Defs(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "table",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
|
@ -18,7 +18,6 @@ Defs(
|
||||
Annotation(
|
||||
@0-1 Identifier {
|
||||
ident: "f",
|
||||
suffixed: 0,
|
||||
},
|
||||
@4-20 Function(
|
||||
[
|
||||
@ -56,7 +55,6 @@ Defs(
|
||||
AnnotatedBody {
|
||||
ann_pattern: @0-1 Identifier {
|
||||
ident: "f",
|
||||
suffixed: 0,
|
||||
},
|
||||
ann_type: @4-20 Function(
|
||||
[
|
||||
@ -93,19 +91,16 @@ Defs(
|
||||
comment: None,
|
||||
body_pattern: @21-22 Identifier {
|
||||
ident: "f",
|
||||
suffixed: 0,
|
||||
},
|
||||
body_expr: @25-32 Closure(
|
||||
[
|
||||
@26-27 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
@31-32 Var {
|
||||
module_name: "",
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
),
|
||||
},
|
||||
@ -116,7 +111,6 @@ Defs(
|
||||
@34-35 Var {
|
||||
module_name: "",
|
||||
ident: "f",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
@36-47 Tuple(
|
||||
|
@ -18,7 +18,6 @@ Defs(
|
||||
Annotation(
|
||||
@0-1 Identifier {
|
||||
ident: "f",
|
||||
suffixed: 0,
|
||||
},
|
||||
@4-21 Function(
|
||||
[
|
||||
@ -48,7 +47,6 @@ Defs(
|
||||
AnnotatedBody {
|
||||
ann_pattern: @0-1 Identifier {
|
||||
ident: "f",
|
||||
suffixed: 0,
|
||||
},
|
||||
ann_type: @4-21 Function(
|
||||
[
|
||||
@ -77,13 +75,11 @@ Defs(
|
||||
comment: None,
|
||||
body_pattern: @22-23 Identifier {
|
||||
ident: "f",
|
||||
suffixed: 0,
|
||||
},
|
||||
body_expr: @26-42 Closure(
|
||||
[
|
||||
@27-28 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
@32-42 Tuple(
|
||||
@ -91,7 +87,6 @@ Defs(
|
||||
@33-34 Var {
|
||||
module_name: "",
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@36-41 BinOps(
|
||||
[
|
||||
@ -99,7 +94,6 @@ Defs(
|
||||
@36-37 Var {
|
||||
module_name: "",
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@38-39 Plus,
|
||||
),
|
||||
@ -119,7 +113,6 @@ Defs(
|
||||
@44-45 Var {
|
||||
module_name: "",
|
||||
ident: "f",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
@46-48 Num(
|
||||
|
@ -18,7 +18,6 @@ Defs(
|
||||
Body(
|
||||
@0-4 Identifier {
|
||||
ident: "iffy",
|
||||
suffixed: 0,
|
||||
},
|
||||
@5-6 Num(
|
||||
"5",
|
||||
|
@ -78,7 +78,6 @@ Defs(
|
||||
@53-62 Var {
|
||||
module_name: "JE",
|
||||
ident: "encode",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
@64-70 ParensAround(
|
||||
@ -86,7 +85,6 @@ Defs(
|
||||
@64-67 Var {
|
||||
module_name: "",
|
||||
ident: "int",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
@68-70 Num(
|
||||
|
@ -46,13 +46,11 @@ Defs(
|
||||
@35-44 Var {
|
||||
module_name: "",
|
||||
ident: "parseJson",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
@45-49 Var {
|
||||
module_name: "",
|
||||
ident: "data",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
Space,
|
||||
|
@ -18,7 +18,6 @@ BinOps(
|
||||
Var {
|
||||
module_name: "Str",
|
||||
ident: "toUtf8",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
@ -32,14 +31,12 @@ BinOps(
|
||||
@28-36 Var {
|
||||
module_name: "List",
|
||||
ident: "map",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
@37-54 Closure(
|
||||
[
|
||||
@38-42 Identifier {
|
||||
ident: "byte",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
@46-54 BinOps(
|
||||
@ -48,7 +45,6 @@ BinOps(
|
||||
@46-50 Var {
|
||||
module_name: "",
|
||||
ident: "byte",
|
||||
suffixed: 0,
|
||||
},
|
||||
@51-52 Plus,
|
||||
),
|
||||
@ -71,6 +67,5 @@ BinOps(
|
||||
@58-70 Var {
|
||||
module_name: "List",
|
||||
ident: "reverse",
|
||||
suffixed: 0,
|
||||
},
|
||||
)
|
||||
|
@ -2,7 +2,6 @@ Closure(
|
||||
[
|
||||
@1-2 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
@8-9 SpaceBefore(
|
||||
|
@ -18,7 +18,6 @@ Defs(
|
||||
Body(
|
||||
@0-6 Identifier {
|
||||
ident: "myList",
|
||||
suffixed: 0,
|
||||
},
|
||||
@9-57 List(
|
||||
Collection {
|
||||
@ -39,7 +38,6 @@ Defs(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "a",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
@ -49,7 +47,6 @@ Defs(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "b",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
|
@ -18,7 +18,6 @@ Defs(
|
||||
Body(
|
||||
@0-6 Identifier {
|
||||
ident: "myList",
|
||||
suffixed: 0,
|
||||
},
|
||||
@9-25 List(
|
||||
[
|
||||
|
@ -18,7 +18,6 @@ Defs(
|
||||
Body(
|
||||
@0-6 Identifier {
|
||||
ident: "myList",
|
||||
suffixed: 0,
|
||||
},
|
||||
@9-26 List(
|
||||
Collection {
|
||||
|
@ -19,6 +19,5 @@ BinOps(
|
||||
@6-7 Var {
|
||||
module_name: "",
|
||||
ident: "i",
|
||||
suffixed: 0,
|
||||
},
|
||||
)
|
||||
|
@ -75,19 +75,15 @@ When(
|
||||
[
|
||||
@61-62 Identifier {
|
||||
ident: "a",
|
||||
suffixed: 0,
|
||||
},
|
||||
@64-65 Identifier {
|
||||
ident: "b",
|
||||
suffixed: 0,
|
||||
},
|
||||
@67-68 Identifier {
|
||||
ident: "c",
|
||||
suffixed: 0,
|
||||
},
|
||||
@70-71 Identifier {
|
||||
ident: "d",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
),
|
||||
@ -108,11 +104,9 @@ When(
|
||||
[
|
||||
@82-83 Identifier {
|
||||
ident: "a",
|
||||
suffixed: 0,
|
||||
},
|
||||
@85-86 Identifier {
|
||||
ident: "b",
|
||||
suffixed: 0,
|
||||
},
|
||||
@88-90 ListRest(
|
||||
None,
|
||||
@ -139,11 +133,9 @@ When(
|
||||
),
|
||||
@105-106 Identifier {
|
||||
ident: "c",
|
||||
suffixed: 0,
|
||||
},
|
||||
@108-109 Identifier {
|
||||
ident: "d",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
),
|
||||
@ -180,7 +172,6 @@ When(
|
||||
[
|
||||
@132-133 Identifier {
|
||||
ident: "a",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
),
|
||||
@ -218,7 +209,6 @@ When(
|
||||
),
|
||||
@160-161 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
),
|
||||
|
@ -19,7 +19,6 @@ SpaceBefore(
|
||||
Body(
|
||||
@113-114 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@117-118 Num(
|
||||
"5",
|
||||
|
@ -17,7 +17,6 @@ Defs {
|
||||
Body(
|
||||
@0-4 Identifier {
|
||||
ident: "main",
|
||||
suffixed: 0,
|
||||
},
|
||||
@11-24 SpaceBefore(
|
||||
Defs(
|
||||
@ -40,7 +39,6 @@ Defs {
|
||||
Body(
|
||||
@11-12 Identifier {
|
||||
ident: "i",
|
||||
suffixed: 0,
|
||||
},
|
||||
@15-17 Num(
|
||||
"64",
|
||||
@ -52,7 +50,6 @@ Defs {
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "i",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
|
@ -2,18 +2,15 @@ Backpassing(
|
||||
[
|
||||
@0-1 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@3-4 Identifier {
|
||||
ident: "y",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
@8-23 Apply(
|
||||
@8-17 Var {
|
||||
module_name: "List",
|
||||
ident: "map2",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
@18-20 List(
|
||||
@ -32,7 +29,6 @@ Backpassing(
|
||||
@25-26 Var {
|
||||
module_name: "",
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@27-28 Plus,
|
||||
),
|
||||
@ -40,7 +36,6 @@ Backpassing(
|
||||
@29-30 Var {
|
||||
module_name: "",
|
||||
ident: "y",
|
||||
suffixed: 0,
|
||||
},
|
||||
),
|
||||
[
|
||||
|
@ -17,25 +17,21 @@ Defs {
|
||||
Body(
|
||||
@0-4 Identifier {
|
||||
ident: "main",
|
||||
suffixed: 0,
|
||||
},
|
||||
@12-50 SpaceBefore(
|
||||
Backpassing(
|
||||
[
|
||||
@12-16 Identifier {
|
||||
ident: "arg1",
|
||||
suffixed: 0,
|
||||
},
|
||||
@18-22 Identifier {
|
||||
ident: "arg2",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
@26-30 Apply(
|
||||
@26-27 Var {
|
||||
module_name: "",
|
||||
ident: "f",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
@28-30 Record(
|
||||
|
@ -12,13 +12,11 @@ Backpassing(
|
||||
),
|
||||
@5-6 Identifier {
|
||||
ident: "r",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
@10-11 Var {
|
||||
module_name: "",
|
||||
ident: "a",
|
||||
suffixed: 0,
|
||||
},
|
||||
@12-13 SpaceBefore(
|
||||
Tag(
|
||||
|
@ -29,7 +29,6 @@ Defs(
|
||||
Body(
|
||||
@0-1 Identifier {
|
||||
ident: "a",
|
||||
suffixed: 0,
|
||||
},
|
||||
@4-22 Str(
|
||||
Line(
|
||||
@ -53,7 +52,6 @@ Defs(
|
||||
Body(
|
||||
@23-24 Identifier {
|
||||
ident: "b",
|
||||
suffixed: 0,
|
||||
},
|
||||
@27-49 Str(
|
||||
Block(
|
||||
@ -79,7 +77,6 @@ Defs(
|
||||
Body(
|
||||
@50-51 Identifier {
|
||||
ident: "c",
|
||||
suffixed: 0,
|
||||
},
|
||||
@58-92 SpaceBefore(
|
||||
Str(
|
||||
|
@ -2,7 +2,6 @@ Apply(
|
||||
@0-1 Var {
|
||||
module_name: "",
|
||||
ident: "e",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
@1-10 Str(
|
||||
|
@ -18,7 +18,6 @@ Defs(
|
||||
Annotation(
|
||||
@0-1 Identifier {
|
||||
ident: "f",
|
||||
suffixed: 0,
|
||||
},
|
||||
@8-10 SpaceBefore(
|
||||
Record {
|
||||
|
@ -18,7 +18,6 @@ Defs(
|
||||
Annotation(
|
||||
@0-1 Identifier {
|
||||
ident: "f",
|
||||
suffixed: 0,
|
||||
},
|
||||
@17-19 SpaceBefore(
|
||||
Record {
|
||||
|
@ -4,7 +4,6 @@ RecordAccess(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "rec",
|
||||
suffixed: 0,
|
||||
},
|
||||
"abc",
|
||||
),
|
||||
|
@ -2,7 +2,6 @@ UnaryOp(
|
||||
@1-4 Var {
|
||||
module_name: "",
|
||||
ident: "inf",
|
||||
suffixed: 0,
|
||||
},
|
||||
@0-1 Negate,
|
||||
)
|
||||
|
@ -18,7 +18,6 @@ Defs(
|
||||
Body(
|
||||
@0-1 Identifier {
|
||||
ident: "a",
|
||||
suffixed: 0,
|
||||
},
|
||||
@2-9 Apply(
|
||||
@2-3 SpaceAfter(
|
||||
@ -34,14 +33,12 @@ Defs(
|
||||
@6-7 Var {
|
||||
module_name: "",
|
||||
ident: "g",
|
||||
suffixed: 0,
|
||||
},
|
||||
@5-6 Negate,
|
||||
),
|
||||
@8-9 Var {
|
||||
module_name: "",
|
||||
ident: "a",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
Space,
|
||||
@ -53,7 +50,6 @@ Defs(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "a",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
|
@ -18,7 +18,6 @@ Defs(
|
||||
Body(
|
||||
@0-4 Identifier {
|
||||
ident: "main",
|
||||
suffixed: 0,
|
||||
},
|
||||
@11-71 SpaceBefore(
|
||||
Defs(
|
||||
@ -41,20 +40,17 @@ Defs(
|
||||
Body(
|
||||
@11-15 Identifier {
|
||||
ident: "task",
|
||||
suffixed: 0,
|
||||
},
|
||||
@18-62 Backpassing(
|
||||
[
|
||||
@18-22 Identifier {
|
||||
ident: "file",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
@43-46 SpaceBefore(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "foo",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
@ -64,7 +60,6 @@ Defs(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "bar",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
@ -78,7 +73,6 @@ Defs(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "task",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
|
@ -17,7 +17,6 @@ Defs {
|
||||
Body(
|
||||
@0-4 Identifier {
|
||||
ident: "main",
|
||||
suffixed: 0,
|
||||
},
|
||||
@11-115 SpaceBefore(
|
||||
Defs(
|
||||
@ -40,7 +39,6 @@ Defs {
|
||||
Annotation(
|
||||
@11-23 Identifier {
|
||||
ident: "wrappedNotEq",
|
||||
suffixed: 0,
|
||||
},
|
||||
@26-38 Function(
|
||||
[
|
||||
@ -61,7 +59,6 @@ Defs {
|
||||
AnnotatedBody {
|
||||
ann_pattern: @11-23 Identifier {
|
||||
ident: "wrappedNotEq",
|
||||
suffixed: 0,
|
||||
},
|
||||
ann_type: @26-38 Function(
|
||||
[
|
||||
@ -81,17 +78,14 @@ Defs {
|
||||
comment: None,
|
||||
body_pattern: @43-55 Identifier {
|
||||
ident: "wrappedNotEq",
|
||||
suffixed: 0,
|
||||
},
|
||||
body_expr: @58-93 Closure(
|
||||
[
|
||||
@59-63 Identifier {
|
||||
ident: "num1",
|
||||
suffixed: 0,
|
||||
},
|
||||
@65-69 Identifier {
|
||||
ident: "num2",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
@81-93 SpaceBefore(
|
||||
@ -101,7 +95,6 @@ Defs {
|
||||
@81-85 Var {
|
||||
module_name: "",
|
||||
ident: "num1",
|
||||
suffixed: 0,
|
||||
},
|
||||
@86-88 NotEquals,
|
||||
),
|
||||
@ -109,7 +102,6 @@ Defs {
|
||||
@89-93 Var {
|
||||
module_name: "",
|
||||
ident: "num2",
|
||||
suffixed: 0,
|
||||
},
|
||||
),
|
||||
[
|
||||
@ -125,7 +117,6 @@ Defs {
|
||||
@99-111 Var {
|
||||
module_name: "",
|
||||
ident: "wrappedNotEq",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
@112-113 Num(
|
||||
|
@ -18,7 +18,6 @@ Defs(
|
||||
Body(
|
||||
@0-1 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@2-7 Defs(
|
||||
Defs {
|
||||
@ -40,7 +39,6 @@ Defs(
|
||||
Annotation(
|
||||
@2-3 Identifier {
|
||||
ident: "a",
|
||||
suffixed: 0,
|
||||
},
|
||||
@4-5 BoundVariable(
|
||||
"n",
|
||||
|
@ -4,7 +4,6 @@ If(
|
||||
@3-5 Var {
|
||||
module_name: "",
|
||||
ident: "t1",
|
||||
suffixed: 0,
|
||||
},
|
||||
@13-14 SpaceBefore(
|
||||
SpaceAfter(
|
||||
@ -24,7 +23,6 @@ If(
|
||||
@23-25 Var {
|
||||
module_name: "",
|
||||
ident: "t2",
|
||||
suffixed: 0,
|
||||
},
|
||||
@33-34 SpaceBefore(
|
||||
SpaceAfter(
|
||||
|
@ -18,7 +18,6 @@ Defs(
|
||||
Body(
|
||||
@0-1 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@8-9 SpaceBefore(
|
||||
Num(
|
||||
|
@ -18,7 +18,6 @@ Defs(
|
||||
Body(
|
||||
@0-1 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@4-13 BinOps(
|
||||
[
|
||||
|
@ -102,14 +102,12 @@ Full {
|
||||
Body(
|
||||
@199-203 Identifier {
|
||||
ident: "main",
|
||||
suffixed: 0,
|
||||
},
|
||||
@210-246 SpaceBefore(
|
||||
Apply(
|
||||
@210-221 Var {
|
||||
module_name: "Stdout",
|
||||
ident: "line",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
@222-246 Str(
|
||||
|
@ -43,7 +43,6 @@ Defs(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "p",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
|
@ -32,7 +32,6 @@ Defs(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "a",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
|
@ -3,7 +3,6 @@ SpaceBefore(
|
||||
[
|
||||
@18-19 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
@23-32 ParensAround(
|
||||
@ -11,13 +10,11 @@ SpaceBefore(
|
||||
[
|
||||
@25-26 Identifier {
|
||||
ident: "y",
|
||||
suffixed: 0,
|
||||
},
|
||||
],
|
||||
@30-31 Var {
|
||||
module_name: "",
|
||||
ident: "y",
|
||||
suffixed: 0,
|
||||
},
|
||||
),
|
||||
),
|
||||
@ -25,7 +22,6 @@ SpaceBefore(
|
||||
Var {
|
||||
module_name: "",
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
[
|
||||
Newline,
|
||||
|
@ -19,7 +19,6 @@ SpaceBefore(
|
||||
Body(
|
||||
@18-19 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@20-21 Num(
|
||||
"5",
|
||||
|
@ -19,7 +19,6 @@ SpaceBefore(
|
||||
Body(
|
||||
@18-19 Identifier {
|
||||
ident: "x",
|
||||
suffixed: 0,
|
||||
},
|
||||
@22-23 Num(
|
||||
"5",
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user