mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Merge remote-tracking branch 'origin/main' into upgrade-llvm-zig
This commit is contained in:
commit
d74a3c0746
28 changed files with 1040 additions and 166 deletions
|
@ -14,9 +14,9 @@ cd crates/cli && cargo criterion --no-run && cd ../..
|
||||||
mkdir -p bench-folder/crates/cli/tests/benchmarks/
|
mkdir -p bench-folder/crates/cli/tests/benchmarks/
|
||||||
mkdir -p bench-folder/target/release/deps
|
mkdir -p bench-folder/target/release/deps
|
||||||
mkdir -p bench-folder/target/release/lib
|
mkdir -p bench-folder/target/release/lib
|
||||||
cp "crates/cli/tests/benchmarks/"*".roc" bench-folder/crates/cli/tests/benchmarks/
|
cp crates/cli/tests/benchmarks/*.roc bench-folder/crates/cli/tests/benchmarks/
|
||||||
cp -r crates/cli/tests/benchmarks/platform bench-folder/crates/cli/tests/benchmarks/
|
cp -r crates/cli/tests/benchmarks/platform bench-folder/crates/cli/tests/benchmarks/
|
||||||
cp "crates/compiler/builtins/bitcode/src/*.zig" bench-folder/target/release/lib/
|
cp crates/compiler/builtins/bitcode/src/*.zig bench-folder/target/release/lib/
|
||||||
cp target/release/roc bench-folder/target/release
|
cp target/release/roc bench-folder/target/release
|
||||||
|
|
||||||
# copy the most recent time bench to bench-folder
|
# copy the most recent time bench to bench-folder
|
||||||
|
|
|
@ -17,13 +17,14 @@ fn roc_repl_session() -> Result<PtyReplSession, Error> {
|
||||||
|
|
||||||
fn main() -> Result<(), Error> {
|
fn main() -> Result<(), Error> {
|
||||||
let mut repl = roc_repl_session()?;
|
let mut repl = roc_repl_session()?;
|
||||||
|
|
||||||
repl.exp_regex(".*roc repl.*")?;
|
repl.exp_regex(".*roc repl.*")?;
|
||||||
repl.send_line("1+1")?;
|
repl.send_line("1+1")?;
|
||||||
|
|
||||||
thread::sleep(Duration::from_secs(1));
|
thread::sleep(Duration::from_secs(1));
|
||||||
|
|
||||||
match repl.exp_regex(r".*2\u{1b}\[1;32m : \u{1b}\[0mNum *.*") { // 2 : Num
|
match repl.exp_regex(r".*2\u{1b}\[1;32m : \u{1b}\[0mNum *.*") {
|
||||||
|
// 2 : Num
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
println!("Expected output received.");
|
println!("Expected output received.");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -33,4 +34,4 @@ fn main() -> Result<(), Error> {
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -254,7 +254,7 @@ fn main() -> io::Result<()> {
|
||||||
exit_code = problems.exit_code();
|
exit_code = problems.exit_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(LoadingProblem::FormattedReport(report)) => {
|
Err(LoadingProblem::FormattedReport(report, _)) => {
|
||||||
print!("{report}");
|
print!("{report}");
|
||||||
|
|
||||||
exit_code = 1;
|
exit_code = 1;
|
||||||
|
@ -285,7 +285,7 @@ fn main() -> io::Result<()> {
|
||||||
Ok(problems.exit_code())
|
Ok(problems.exit_code())
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(LoadingProblem::FormattedReport(report)) => {
|
Err(LoadingProblem::FormattedReport(report, _)) => {
|
||||||
print!("{report}");
|
print!("{report}");
|
||||||
|
|
||||||
Ok(1)
|
Ok(1)
|
||||||
|
|
|
@ -677,7 +677,7 @@ pub fn handle_error_module(
|
||||||
|
|
||||||
pub fn handle_loading_problem(problem: LoadingProblem) -> std::io::Result<i32> {
|
pub fn handle_loading_problem(problem: LoadingProblem) -> std::io::Result<i32> {
|
||||||
match problem {
|
match problem {
|
||||||
LoadingProblem::FormattedReport(report) => {
|
LoadingProblem::FormattedReport(report, _) => {
|
||||||
print!("{report}");
|
print!("{report}");
|
||||||
Ok(1)
|
Ok(1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ fn write_types_for_module_real(module_id: ModuleId, filename: &str, output_path:
|
||||||
|
|
||||||
let mut module = match res_module {
|
let mut module = match res_module {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(LoadingProblem::FormattedReport(report)) => {
|
Err(LoadingProblem::FormattedReport(report, _)) => {
|
||||||
internal_error!("{}", report);
|
internal_error!("{}", report);
|
||||||
}
|
}
|
||||||
Err(other) => {
|
Err(other) => {
|
||||||
|
|
|
@ -187,7 +187,7 @@ mod test_reporting {
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
|
|
||||||
match infer_expr_help_new(subdir, arena, src) {
|
match infer_expr_help_new(subdir, arena, src) {
|
||||||
Err(LoadingProblem::FormattedReport(fail)) => fail,
|
Err(LoadingProblem::FormattedReport(fail, _)) => fail,
|
||||||
Ok((module_src, type_problems, can_problems, home, interns)) => {
|
Ok((module_src, type_problems, can_problems, home, interns)) => {
|
||||||
let lines = LineInfo::new(&module_src);
|
let lines = LineInfo::new(&module_src);
|
||||||
let src_lines: Vec<&str> = module_src.split('\n').collect();
|
let src_lines: Vec<&str> = module_src.split('\n').collect();
|
||||||
|
|
|
@ -998,13 +998,52 @@ pub enum LoadingProblem<'a> {
|
||||||
TriedToImportAppModule,
|
TriedToImportAppModule,
|
||||||
|
|
||||||
/// a formatted report
|
/// a formatted report
|
||||||
FormattedReport(String),
|
FormattedReport(String, Option<Region>),
|
||||||
|
|
||||||
ImportCycle(PathBuf, Vec<ModuleId>),
|
ImportCycle(PathBuf, Vec<ModuleId>),
|
||||||
IncorrectModuleName(FileError<'a, IncorrectModuleName<'a>>),
|
IncorrectModuleName(FileError<'a, IncorrectModuleName<'a>>),
|
||||||
CouldNotFindCacheDir,
|
CouldNotFindCacheDir,
|
||||||
ChannelProblem(ChannelProblem),
|
ChannelProblem(ChannelProblem),
|
||||||
}
|
}
|
||||||
|
impl<'a> LoadingProblem<'a> {
|
||||||
|
pub fn get_region(&self) -> Option<Region> {
|
||||||
|
match self {
|
||||||
|
LoadingProblem::ParsingFailed(err) => err.problem.problem.get_region(),
|
||||||
|
LoadingProblem::MultiplePlatformPackages {
|
||||||
|
filename: _,
|
||||||
|
module_id: _,
|
||||||
|
source: _,
|
||||||
|
region,
|
||||||
|
} => Some(*region),
|
||||||
|
LoadingProblem::NoPlatformPackage {
|
||||||
|
filename: _,
|
||||||
|
module_id: _,
|
||||||
|
source: _,
|
||||||
|
region,
|
||||||
|
} => Some(*region),
|
||||||
|
LoadingProblem::UnrecognizedPackageShorthand {
|
||||||
|
filename: _,
|
||||||
|
module_id: _,
|
||||||
|
source: _,
|
||||||
|
region,
|
||||||
|
shorthand: _,
|
||||||
|
available: _,
|
||||||
|
} => Some(*region),
|
||||||
|
LoadingProblem::FileProblem {
|
||||||
|
filename: _,
|
||||||
|
error: _,
|
||||||
|
} => None,
|
||||||
|
LoadingProblem::UnexpectedHeader(_) => None,
|
||||||
|
LoadingProblem::ErrJoiningWorkerThreads => None,
|
||||||
|
LoadingProblem::TriedToImportAppModule => None,
|
||||||
|
LoadingProblem::FormattedReport(_, region) => *region,
|
||||||
|
LoadingProblem::ImportCycle(_, _) => None,
|
||||||
|
LoadingProblem::IncorrectModuleName(_) => None,
|
||||||
|
LoadingProblem::CouldNotFindCacheDir => None,
|
||||||
|
LoadingProblem::ChannelProblem(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum AvailableShorthands<'a> {
|
pub enum AvailableShorthands<'a> {
|
||||||
|
@ -1179,12 +1218,12 @@ impl<'a> LoadStart<'a> {
|
||||||
})
|
})
|
||||||
.into_inner()
|
.into_inner()
|
||||||
.into_module_ids();
|
.into_module_ids();
|
||||||
|
let region = problem.get_region();
|
||||||
let report = report_loading_problem(problem, module_ids, render, palette);
|
let report = report_loading_problem(problem, module_ids, render, palette);
|
||||||
|
|
||||||
// TODO try to gracefully recover and continue
|
// TODO try to gracefully recover and continue
|
||||||
// instead of changing the control flow to exit.
|
// instead of changing the control flow to exit.
|
||||||
return Err(LoadingProblem::FormattedReport(report));
|
return Err(LoadingProblem::FormattedReport(report, region));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1672,10 +1711,11 @@ fn state_thread_step<'a>(
|
||||||
}
|
}
|
||||||
Msg::FailedToReadFile { filename, error } => {
|
Msg::FailedToReadFile { filename, error } => {
|
||||||
let buf = to_file_problem_report_string(filename, error, true);
|
let buf = to_file_problem_report_string(filename, error, true);
|
||||||
Err(LoadingProblem::FormattedReport(buf))
|
Err(LoadingProblem::FormattedReport(buf, None))
|
||||||
}
|
}
|
||||||
|
|
||||||
Msg::FailedToParse(problem) => {
|
Msg::FailedToParse(problem) => {
|
||||||
|
let region = problem.problem.problem.get_region();
|
||||||
let module_ids = (*state.arc_modules).lock().clone().into_module_ids();
|
let module_ids = (*state.arc_modules).lock().clone().into_module_ids();
|
||||||
let buf = to_parse_problem_report(
|
let buf = to_parse_problem_report(
|
||||||
problem,
|
problem,
|
||||||
|
@ -1684,14 +1724,14 @@ fn state_thread_step<'a>(
|
||||||
state.render,
|
state.render,
|
||||||
state.palette,
|
state.palette,
|
||||||
);
|
);
|
||||||
Err(LoadingProblem::FormattedReport(buf))
|
Err(LoadingProblem::FormattedReport(buf, region))
|
||||||
}
|
}
|
||||||
Msg::IncorrectModuleName(FileError {
|
Msg::IncorrectModuleName(FileError {
|
||||||
problem: SourceError { problem, bytes },
|
problem: SourceError { problem, bytes },
|
||||||
filename,
|
filename,
|
||||||
}) => {
|
}) => {
|
||||||
let module_ids = (*state.arc_modules).lock().clone().into_module_ids();
|
let module_ids = (*state.arc_modules).lock().clone().into_module_ids();
|
||||||
let buf = to_incorrect_module_name_report(
|
let (buf, region) = to_incorrect_module_name_report(
|
||||||
module_ids,
|
module_ids,
|
||||||
state.constrained_ident_ids,
|
state.constrained_ident_ids,
|
||||||
problem,
|
problem,
|
||||||
|
@ -1699,7 +1739,7 @@ fn state_thread_step<'a>(
|
||||||
bytes,
|
bytes,
|
||||||
state.render,
|
state.render,
|
||||||
);
|
);
|
||||||
Err(LoadingProblem::FormattedReport(buf))
|
Err(LoadingProblem::FormattedReport(buf, Some(region)))
|
||||||
}
|
}
|
||||||
msg => {
|
msg => {
|
||||||
// This is where most of the main thread's work gets done.
|
// This is where most of the main thread's work gets done.
|
||||||
|
@ -1716,6 +1756,7 @@ fn state_thread_step<'a>(
|
||||||
match res_state {
|
match res_state {
|
||||||
Ok(new_state) => Ok(ControlFlow::Continue(new_state)),
|
Ok(new_state) => Ok(ControlFlow::Continue(new_state)),
|
||||||
Err(LoadingProblem::ParsingFailed(problem)) => {
|
Err(LoadingProblem::ParsingFailed(problem)) => {
|
||||||
|
let region = problem.problem.problem.get_region();
|
||||||
let module_ids = Arc::try_unwrap(arc_modules)
|
let module_ids = Arc::try_unwrap(arc_modules)
|
||||||
.unwrap_or_else(|_| {
|
.unwrap_or_else(|_| {
|
||||||
panic!(
|
panic!(
|
||||||
|
@ -1734,7 +1775,7 @@ fn state_thread_step<'a>(
|
||||||
render,
|
render,
|
||||||
palette,
|
palette,
|
||||||
);
|
);
|
||||||
Err(LoadingProblem::FormattedReport(buf))
|
Err(LoadingProblem::FormattedReport(buf, region))
|
||||||
}
|
}
|
||||||
Err(LoadingProblem::ImportCycle(filename, cycle)) => {
|
Err(LoadingProblem::ImportCycle(filename, cycle)) => {
|
||||||
let module_ids = arc_modules.lock().clone().into_module_ids();
|
let module_ids = arc_modules.lock().clone().into_module_ids();
|
||||||
|
@ -1747,7 +1788,7 @@ fn state_thread_step<'a>(
|
||||||
filename,
|
filename,
|
||||||
render,
|
render,
|
||||||
);
|
);
|
||||||
return Err(LoadingProblem::FormattedReport(buf));
|
return Err(LoadingProblem::FormattedReport(buf, None));
|
||||||
}
|
}
|
||||||
Err(LoadingProblem::IncorrectModuleName(FileError {
|
Err(LoadingProblem::IncorrectModuleName(FileError {
|
||||||
problem: SourceError { problem, bytes },
|
problem: SourceError { problem, bytes },
|
||||||
|
@ -1756,7 +1797,7 @@ fn state_thread_step<'a>(
|
||||||
let module_ids = arc_modules.lock().clone().into_module_ids();
|
let module_ids = arc_modules.lock().clone().into_module_ids();
|
||||||
|
|
||||||
let root_exposed_ident_ids = IdentIds::exposed_builtins(0);
|
let root_exposed_ident_ids = IdentIds::exposed_builtins(0);
|
||||||
let buf = to_incorrect_module_name_report(
|
let (buf, region) = to_incorrect_module_name_report(
|
||||||
module_ids,
|
module_ids,
|
||||||
root_exposed_ident_ids,
|
root_exposed_ident_ids,
|
||||||
problem,
|
problem,
|
||||||
|
@ -1764,7 +1805,7 @@ fn state_thread_step<'a>(
|
||||||
bytes,
|
bytes,
|
||||||
render,
|
render,
|
||||||
);
|
);
|
||||||
return Err(LoadingProblem::FormattedReport(buf));
|
return Err(LoadingProblem::FormattedReport(buf, Some(region)));
|
||||||
}
|
}
|
||||||
Err(LoadingProblem::UnrecognizedPackageShorthand {
|
Err(LoadingProblem::UnrecognizedPackageShorthand {
|
||||||
filename,
|
filename,
|
||||||
|
@ -1788,7 +1829,7 @@ fn state_thread_step<'a>(
|
||||||
available,
|
available,
|
||||||
render,
|
render,
|
||||||
);
|
);
|
||||||
return Err(LoadingProblem::FormattedReport(buf));
|
return Err(LoadingProblem::FormattedReport(buf, Some(region)));
|
||||||
}
|
}
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
}
|
}
|
||||||
|
@ -1836,8 +1877,9 @@ pub fn report_loading_problem(
|
||||||
bytes,
|
bytes,
|
||||||
render,
|
render,
|
||||||
)
|
)
|
||||||
|
.0
|
||||||
}
|
}
|
||||||
LoadingProblem::FormattedReport(report) => report,
|
LoadingProblem::FormattedReport(report, _region) => report,
|
||||||
LoadingProblem::FileProblem { filename, error } => {
|
LoadingProblem::FileProblem { filename, error } => {
|
||||||
to_file_problem_report_string(filename, error, true)
|
to_file_problem_report_string(filename, error, true)
|
||||||
}
|
}
|
||||||
|
@ -2085,7 +2127,7 @@ fn load_multi_threaded<'a>(
|
||||||
"command can sometimes give a more helpful error report than other commands.\n\n"
|
"command can sometimes give a more helpful error report than other commands.\n\n"
|
||||||
)
|
)
|
||||||
.to_string(),
|
.to_string(),
|
||||||
))
|
None))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3046,7 +3088,7 @@ fn register_package_shorthands<'a>(
|
||||||
Problem::InvalidUrl(url_err),
|
Problem::InvalidUrl(url_err),
|
||||||
module_path.to_path_buf(),
|
module_path.to_path_buf(),
|
||||||
);
|
);
|
||||||
return Err(LoadingProblem::FormattedReport(buf));
|
return Err(LoadingProblem::FormattedReport(buf, None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3164,7 +3206,7 @@ fn finish_specialization<'a>(
|
||||||
Valid(To::NewPackage(p_or_p)) => PathBuf::from(p_or_p.as_str()),
|
Valid(To::NewPackage(p_or_p)) => PathBuf::from(p_or_p.as_str()),
|
||||||
other => {
|
other => {
|
||||||
let buf = report_cannot_run(state.root_id, state.root_path, other);
|
let buf = report_cannot_run(state.root_id, state.root_path, other);
|
||||||
return Err(LoadingProblem::FormattedReport(buf));
|
return Err(LoadingProblem::FormattedReport(buf, None));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4129,7 +4171,9 @@ fn load_packages<'a>(
|
||||||
Err(problem) => {
|
Err(problem) => {
|
||||||
let buf = to_https_problem_report_string(src, problem, filename);
|
let buf = to_https_problem_report_string(src, problem, filename);
|
||||||
|
|
||||||
load_messages.push(Msg::FailedToLoad(LoadingProblem::FormattedReport(buf)));
|
load_messages.push(Msg::FailedToLoad(LoadingProblem::FormattedReport(
|
||||||
|
buf, None,
|
||||||
|
)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6447,7 +6491,7 @@ fn to_incorrect_module_name_report<'a>(
|
||||||
filename: PathBuf,
|
filename: PathBuf,
|
||||||
src: &'a [u8],
|
src: &'a [u8],
|
||||||
render: RenderTarget,
|
render: RenderTarget,
|
||||||
) -> String {
|
) -> (String, Region) {
|
||||||
use roc_reporting::report::{Report, RocDocAllocator, DEFAULT_PALETTE};
|
use roc_reporting::report::{Report, RocDocAllocator, DEFAULT_PALETTE};
|
||||||
use ven_pretty::DocAllocator;
|
use ven_pretty::DocAllocator;
|
||||||
|
|
||||||
|
@ -6488,7 +6532,7 @@ fn to_incorrect_module_name_report<'a>(
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
let palette = DEFAULT_PALETTE;
|
let palette = DEFAULT_PALETTE;
|
||||||
report.render(render, &mut buf, &alloc, &palette);
|
report.render(render, &mut buf, &alloc, &palette);
|
||||||
buf
|
(buf, found.region)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_no_platform_package_report(
|
fn to_no_platform_package_report(
|
||||||
|
|
|
@ -141,7 +141,7 @@ fn multiple_modules(subdir: &str, files: Vec<(&str, &str)>) -> Result<LoadedModu
|
||||||
|
|
||||||
match multiple_modules_help(subdir, arena, files) {
|
match multiple_modules_help(subdir, arena, files) {
|
||||||
Err(io_error) => panic!("IO trouble: {io_error:?}"),
|
Err(io_error) => panic!("IO trouble: {io_error:?}"),
|
||||||
Ok(Err(LoadingProblem::FormattedReport(buf))) => Err(buf),
|
Ok(Err(LoadingProblem::FormattedReport(buf, _))) => Err(buf),
|
||||||
Ok(Err(loading_problem)) => Err(format!("{loading_problem:?}")),
|
Ok(Err(loading_problem)) => Err(format!("{loading_problem:?}")),
|
||||||
Ok(Ok(mut loaded_module)) => {
|
Ok(Ok(mut loaded_module)) => {
|
||||||
let home = loaded_module.module_id;
|
let home = loaded_module.module_id;
|
||||||
|
@ -247,7 +247,7 @@ fn load_fixture(
|
||||||
);
|
);
|
||||||
let mut loaded_module = match loaded {
|
let mut loaded_module = match loaded {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(roc_load_internal::file::LoadingProblem::FormattedReport(report)) => {
|
Err(roc_load_internal::file::LoadingProblem::FormattedReport(report, _)) => {
|
||||||
println!("{report}");
|
println!("{report}");
|
||||||
panic!("{}", report);
|
panic!("{}", report);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,27 @@ pub enum SyntaxError<'a> {
|
||||||
Space(BadInputError),
|
Space(BadInputError),
|
||||||
NotEndOfFile(Position),
|
NotEndOfFile(Position),
|
||||||
}
|
}
|
||||||
|
impl<'a> SyntaxError<'a> {
|
||||||
|
pub fn get_region(&self) -> Option<Region> {
|
||||||
|
match self {
|
||||||
|
SyntaxError::Unexpected(r) => Some(*r),
|
||||||
|
SyntaxError::Eof(r) => Some(*r),
|
||||||
|
SyntaxError::ReservedKeyword(r) => Some(*r),
|
||||||
|
SyntaxError::ArgumentsBeforeEquals(r) => Some(*r),
|
||||||
|
SyntaxError::Type(e_type) => Some(e_type.get_region()),
|
||||||
|
SyntaxError::Pattern(e_pattern) => Some(e_pattern.get_region()),
|
||||||
|
SyntaxError::NotEndOfFile(pos) => Some(Region::from_pos(*pos)),
|
||||||
|
SyntaxError::Expr(e_expr, _) => Some(e_expr.get_region()),
|
||||||
|
SyntaxError::Header(e_header) => Some(e_header.get_region()),
|
||||||
|
SyntaxError::NotYetImplemented(_) => None,
|
||||||
|
SyntaxError::OutdentedTooFar => None,
|
||||||
|
SyntaxError::Todo => None,
|
||||||
|
SyntaxError::InvalidPattern => None,
|
||||||
|
SyntaxError::BadUtf8 => None,
|
||||||
|
SyntaxError::Space(_bad_input) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
pub trait SpaceProblem: std::fmt::Debug {
|
pub trait SpaceProblem: std::fmt::Debug {
|
||||||
fn space_problem(e: BadInputError, pos: Position) -> Self;
|
fn space_problem(e: BadInputError, pos: Position) -> Self;
|
||||||
}
|
}
|
||||||
|
@ -133,6 +154,27 @@ pub enum EHeader<'a> {
|
||||||
InconsistentModuleName(Region),
|
InconsistentModuleName(Region),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> EHeader<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
EHeader::Provides(provides, _pos) => provides.get_region(),
|
||||||
|
EHeader::Params(params, _pos) => params.get_region(),
|
||||||
|
EHeader::Exposes(_, pos) => Region::from_pos(*pos),
|
||||||
|
EHeader::Imports(_, pos) => Region::from_pos(*pos),
|
||||||
|
EHeader::Requires(requires, _pos) => requires.get_region(),
|
||||||
|
EHeader::Packages(packages, _pos) => packages.get_region(),
|
||||||
|
EHeader::Space(_, pos) => Region::from_pos(*pos),
|
||||||
|
EHeader::Start(pos) => Region::from_pos(*pos),
|
||||||
|
EHeader::ModuleName(pos) => Region::from_pos(*pos),
|
||||||
|
EHeader::AppName(app_name, _pos) => app_name.get_region(),
|
||||||
|
EHeader::PackageName(package_name, _pos) => package_name.get_region(),
|
||||||
|
EHeader::PlatformName(platform_name, _pos) => platform_name.get_region(),
|
||||||
|
EHeader::IndentStart(pos) => Region::from_pos(*pos),
|
||||||
|
EHeader::InconsistentModuleName(region) => *region,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EProvides<'a> {
|
pub enum EProvides<'a> {
|
||||||
Provides(Position),
|
Provides(Position),
|
||||||
|
@ -149,6 +191,26 @@ pub enum EProvides<'a> {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> EProvides<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
let pos = match self {
|
||||||
|
EProvides::Provides(p)
|
||||||
|
| EProvides::Open(p)
|
||||||
|
| EProvides::To(p)
|
||||||
|
| EProvides::IndentProvides(p)
|
||||||
|
| EProvides::IndentTo(p)
|
||||||
|
| EProvides::IndentListStart(p)
|
||||||
|
| EProvides::IndentPackage(p)
|
||||||
|
| EProvides::ListStart(p)
|
||||||
|
| EProvides::ListEnd(p)
|
||||||
|
| EProvides::Identifier(p)
|
||||||
|
| EProvides::Package(_, p)
|
||||||
|
| EProvides::Space(_, p) => p,
|
||||||
|
};
|
||||||
|
Region::from_pos(*pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EParams<'a> {
|
pub enum EParams<'a> {
|
||||||
Pattern(PRecord<'a>, Position),
|
Pattern(PRecord<'a>, Position),
|
||||||
|
@ -158,6 +220,19 @@ pub enum EParams<'a> {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> EParams<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
let pos = match self {
|
||||||
|
EParams::Pattern(_, p)
|
||||||
|
| EParams::BeforeArrow(p)
|
||||||
|
| EParams::Arrow(p)
|
||||||
|
| EParams::AfterArrow(p)
|
||||||
|
| EParams::Space(_, p) => p,
|
||||||
|
};
|
||||||
|
Region::from_pos(*pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum EExposes {
|
pub enum EExposes {
|
||||||
Exposes(Position),
|
Exposes(Position),
|
||||||
|
@ -170,6 +245,22 @@ pub enum EExposes {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EExposes {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
let pos = match self {
|
||||||
|
EExposes::Exposes(p)
|
||||||
|
| EExposes::Open(p)
|
||||||
|
| EExposes::IndentExposes(p)
|
||||||
|
| EExposes::IndentListStart(p)
|
||||||
|
| EExposes::ListStart(p)
|
||||||
|
| EExposes::ListEnd(p)
|
||||||
|
| EExposes::Identifier(p)
|
||||||
|
| EExposes::Space(_, p) => p,
|
||||||
|
};
|
||||||
|
Region::from_pos(*pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum ERequires<'a> {
|
pub enum ERequires<'a> {
|
||||||
Requires(Position),
|
Requires(Position),
|
||||||
|
@ -183,6 +274,23 @@ pub enum ERequires<'a> {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> ERequires<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
let pos = match self {
|
||||||
|
ERequires::Requires(p)
|
||||||
|
| ERequires::Open(p)
|
||||||
|
| ERequires::IndentRequires(p)
|
||||||
|
| ERequires::IndentListStart(p)
|
||||||
|
| ERequires::ListStart(p)
|
||||||
|
| ERequires::ListEnd(p)
|
||||||
|
| ERequires::TypedIdent(_, p)
|
||||||
|
| ERequires::Rigid(p)
|
||||||
|
| ERequires::Space(_, p) => p,
|
||||||
|
};
|
||||||
|
Region::from_pos(*pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum ETypedIdent<'a> {
|
pub enum ETypedIdent<'a> {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
|
@ -194,6 +302,21 @@ pub enum ETypedIdent<'a> {
|
||||||
Identifier(Position),
|
Identifier(Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> ETypedIdent<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
let pos = match self {
|
||||||
|
ETypedIdent::Space(_, p)
|
||||||
|
| ETypedIdent::HasType(p)
|
||||||
|
| ETypedIdent::IndentHasType(p)
|
||||||
|
| ETypedIdent::Name(p)
|
||||||
|
| ETypedIdent::Type(_, p)
|
||||||
|
| ETypedIdent::IndentType(p)
|
||||||
|
| ETypedIdent::Identifier(p) => p,
|
||||||
|
};
|
||||||
|
Region::from_pos(*pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EPackages<'a> {
|
pub enum EPackages<'a> {
|
||||||
Open(Position),
|
Open(Position),
|
||||||
|
@ -207,6 +330,23 @@ pub enum EPackages<'a> {
|
||||||
PackageEntry(EPackageEntry<'a>, Position),
|
PackageEntry(EPackageEntry<'a>, Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> EPackages<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
let pos = match self {
|
||||||
|
EPackages::Open(p)
|
||||||
|
| EPackages::Space(_, p)
|
||||||
|
| EPackages::Packages(p)
|
||||||
|
| EPackages::IndentPackages(p)
|
||||||
|
| EPackages::ListStart(p)
|
||||||
|
| EPackages::ListEnd(p)
|
||||||
|
| EPackages::IndentListStart(p)
|
||||||
|
| EPackages::IndentListEnd(p)
|
||||||
|
| EPackages::PackageEntry(_, p) => p,
|
||||||
|
};
|
||||||
|
Region::from_pos(*pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EPackageName<'a> {
|
pub enum EPackageName<'a> {
|
||||||
BadPath(EString<'a>, Position),
|
BadPath(EString<'a>, Position),
|
||||||
|
@ -214,6 +354,17 @@ pub enum EPackageName<'a> {
|
||||||
Multiline(Position),
|
Multiline(Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> EPackageName<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
let pos = match self {
|
||||||
|
EPackageName::BadPath(_, p) | EPackageName::Escapes(p) | EPackageName::Multiline(p) => {
|
||||||
|
p
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Region::from_pos(*pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EPackageEntry<'a> {
|
pub enum EPackageEntry<'a> {
|
||||||
BadPackage(EPackageName<'a>, Position),
|
BadPackage(EPackageName<'a>, Position),
|
||||||
|
@ -225,6 +376,21 @@ pub enum EPackageEntry<'a> {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> EPackageEntry<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
let pos = match self {
|
||||||
|
EPackageEntry::BadPackage(_, p)
|
||||||
|
| EPackageEntry::Shorthand(p)
|
||||||
|
| EPackageEntry::Colon(p)
|
||||||
|
| EPackageEntry::IndentPackage(p)
|
||||||
|
| EPackageEntry::IndentPlatform(p)
|
||||||
|
| EPackageEntry::Platform(p)
|
||||||
|
| EPackageEntry::Space(_, p) => p,
|
||||||
|
};
|
||||||
|
Region::from_pos(*pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum EImports {
|
pub enum EImports {
|
||||||
Open(Position),
|
Open(Position),
|
||||||
|
@ -248,6 +414,33 @@ pub enum EImports {
|
||||||
StrLiteral(Position),
|
StrLiteral(Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EImports {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
let pos = match self {
|
||||||
|
EImports::Open(p)
|
||||||
|
| EImports::Imports(p)
|
||||||
|
| EImports::IndentImports(p)
|
||||||
|
| EImports::IndentListStart(p)
|
||||||
|
| EImports::IndentListEnd(p)
|
||||||
|
| EImports::ListStart(p)
|
||||||
|
| EImports::ListEnd(p)
|
||||||
|
| EImports::Identifier(p)
|
||||||
|
| EImports::ExposingDot(p)
|
||||||
|
| EImports::ShorthandDot(p)
|
||||||
|
| EImports::Shorthand(p)
|
||||||
|
| EImports::ModuleName(p)
|
||||||
|
| EImports::Space(_, p)
|
||||||
|
| EImports::IndentSetStart(p)
|
||||||
|
| EImports::SetStart(p)
|
||||||
|
| EImports::SetEnd(p)
|
||||||
|
| EImports::TypedIdent(p)
|
||||||
|
| EImports::AsKeyword(p)
|
||||||
|
| EImports::StrLiteral(p) => p,
|
||||||
|
};
|
||||||
|
Region::from_pos(*pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum BadInputError {
|
pub enum BadInputError {
|
||||||
HasTab,
|
HasTab,
|
||||||
|
@ -363,6 +556,69 @@ pub enum EExpr<'a> {
|
||||||
UnexpectedTopLevelExpr(Position),
|
UnexpectedTopLevelExpr(Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> EExpr<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
// Cases with child nodes that have get_region()
|
||||||
|
EExpr::Type(e_type, _) => e_type.get_region(),
|
||||||
|
EExpr::Pattern(e_pattern, _) => e_pattern.get_region(),
|
||||||
|
EExpr::Ability(e_ability, _) => e_ability.get_region(),
|
||||||
|
EExpr::When(e_when, _) => e_when.get_region(),
|
||||||
|
EExpr::If(e_if, _) => e_if.get_region(),
|
||||||
|
EExpr::Expect(e_expect, _) => e_expect.get_region(),
|
||||||
|
EExpr::Dbg(e_expect, _) => e_expect.get_region(),
|
||||||
|
EExpr::Import(e_import, _) => e_import.get_region(),
|
||||||
|
EExpr::Return(e_return, _) => e_return.get_region(),
|
||||||
|
EExpr::Closure(e_closure, _) => e_closure.get_region(),
|
||||||
|
EExpr::InParens(e_in_parens, _) => e_in_parens.get_region(),
|
||||||
|
EExpr::Record(e_record, _) => e_record.get_region(),
|
||||||
|
EExpr::Str(e_string, _) => e_string.get_region(),
|
||||||
|
EExpr::List(e_list, _) => e_list.get_region(),
|
||||||
|
|
||||||
|
// Cases with direct Region values
|
||||||
|
EExpr::RecordUpdateOldBuilderField(r)
|
||||||
|
| EExpr::RecordUpdateIgnoredField(r)
|
||||||
|
| EExpr::RecordBuilderOldBuilderField(r) => *r,
|
||||||
|
|
||||||
|
// Cases with Position values
|
||||||
|
EExpr::TrailingOperator(p)
|
||||||
|
| EExpr::Start(p)
|
||||||
|
| EExpr::End(p)
|
||||||
|
| EExpr::BadExprEnd(p)
|
||||||
|
| EExpr::Space(_, p)
|
||||||
|
| EExpr::Dot(p)
|
||||||
|
| EExpr::Access(p)
|
||||||
|
| EExpr::UnaryNot(p)
|
||||||
|
| EExpr::UnaryNegate(p)
|
||||||
|
| EExpr::BadOperator(_, p)
|
||||||
|
| EExpr::DefMissingFinalExpr(p)
|
||||||
|
| EExpr::DefMissingFinalExpr2(_, p)
|
||||||
|
| EExpr::IndentDefBody(p)
|
||||||
|
| EExpr::IndentEquals(p)
|
||||||
|
| EExpr::IndentAnnotation(p)
|
||||||
|
| EExpr::Equals(p)
|
||||||
|
| EExpr::Colon(p)
|
||||||
|
| EExpr::DoubleColon(p)
|
||||||
|
| EExpr::Ident(p)
|
||||||
|
| EExpr::ElmStyleFunction(_, p)
|
||||||
|
| EExpr::MalformedPattern(p)
|
||||||
|
| EExpr::QualifiedTag(p)
|
||||||
|
| EExpr::BackpassComma(p)
|
||||||
|
| EExpr::BackpassArrow(p)
|
||||||
|
| EExpr::BackpassContinue(p)
|
||||||
|
| EExpr::DbgContinue(p)
|
||||||
|
| EExpr::Underscore(p)
|
||||||
|
| EExpr::Crash(p)
|
||||||
|
| EExpr::Try(p)
|
||||||
|
| EExpr::Number(_, p)
|
||||||
|
| EExpr::IndentStart(p)
|
||||||
|
| EExpr::IndentEnd(p)
|
||||||
|
| EExpr::UnexpectedComma(p)
|
||||||
|
| EExpr::UnexpectedTopLevelExpr(p) => Region::from_pos(*p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum ENumber {
|
pub enum ENumber {
|
||||||
End,
|
End,
|
||||||
|
@ -388,6 +644,29 @@ pub enum EString<'a> {
|
||||||
ExpectedDoubleQuoteGotSingleQuote(Position),
|
ExpectedDoubleQuoteGotSingleQuote(Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> EString<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
// Case with child node that has get_region()
|
||||||
|
EString::Format(expr, _) => expr.get_region(),
|
||||||
|
|
||||||
|
// Cases with Position values
|
||||||
|
EString::Open(p)
|
||||||
|
| EString::CodePtOpen(p)
|
||||||
|
| EString::CodePtEnd(p)
|
||||||
|
| EString::InvalidSingleQuote(_, p)
|
||||||
|
| EString::Space(_, p)
|
||||||
|
| EString::EndlessSingleLine(p)
|
||||||
|
| EString::EndlessMultiLine(p)
|
||||||
|
| EString::EndlessSingleQuote(p)
|
||||||
|
| EString::UnknownEscape(p)
|
||||||
|
| EString::FormatEnd(p)
|
||||||
|
| EString::MultilineInsufficientIndent(p)
|
||||||
|
| EString::ExpectedDoubleQuoteGotSingleQuote(p) => Region::from_pos(*p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum ESingleQuote {
|
pub enum ESingleQuote {
|
||||||
Empty,
|
Empty,
|
||||||
|
@ -414,6 +693,27 @@ pub enum ERecord<'a> {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> ERecord<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
// Cases with child node that has get_region()
|
||||||
|
ERecord::Expr(expr, _) => expr.get_region(),
|
||||||
|
|
||||||
|
// Cases with Position values
|
||||||
|
ERecord::End(p)
|
||||||
|
| ERecord::Open(p)
|
||||||
|
| ERecord::Prefix(p)
|
||||||
|
| ERecord::Field(p)
|
||||||
|
| ERecord::UnderscoreField(p)
|
||||||
|
| ERecord::Colon(p)
|
||||||
|
| ERecord::QuestionMark(p)
|
||||||
|
| ERecord::Arrow(p)
|
||||||
|
| ERecord::Ampersand(p)
|
||||||
|
| ERecord::Space(_, p) => Region::from_pos(*p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EInParens<'a> {
|
pub enum EInParens<'a> {
|
||||||
End(Position),
|
End(Position),
|
||||||
|
@ -429,6 +729,21 @@ pub enum EInParens<'a> {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> EInParens<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
// Cases with child node that has get_region()
|
||||||
|
EInParens::Expr(expr, _) => expr.get_region(),
|
||||||
|
|
||||||
|
// Cases with Position values
|
||||||
|
EInParens::End(p)
|
||||||
|
| EInParens::Open(p)
|
||||||
|
| EInParens::Empty(p)
|
||||||
|
| EInParens::Space(_, p) => Region::from_pos(*p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EClosure<'a> {
|
pub enum EClosure<'a> {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
|
@ -444,6 +759,26 @@ pub enum EClosure<'a> {
|
||||||
IndentArg(Position),
|
IndentArg(Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> EClosure<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
// Cases with child nodes that have get_region()
|
||||||
|
EClosure::Pattern(pattern, _) => pattern.get_region(),
|
||||||
|
EClosure::Body(expr, _) => expr.get_region(),
|
||||||
|
|
||||||
|
// Cases with Position values
|
||||||
|
EClosure::Space(_, p)
|
||||||
|
| EClosure::Start(p)
|
||||||
|
| EClosure::Arrow(p)
|
||||||
|
| EClosure::Comma(p)
|
||||||
|
| EClosure::Arg(p)
|
||||||
|
| EClosure::IndentArrow(p)
|
||||||
|
| EClosure::IndentBody(p)
|
||||||
|
| EClosure::IndentArg(p) => Region::from_pos(*p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EList<'a> {
|
pub enum EList<'a> {
|
||||||
Open(Position),
|
Open(Position),
|
||||||
|
@ -453,6 +788,18 @@ pub enum EList<'a> {
|
||||||
Expr(&'a EExpr<'a>, Position),
|
Expr(&'a EExpr<'a>, Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> EList<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
// Case with child node that has get_region()
|
||||||
|
EList::Expr(expr, _) => expr.get_region(),
|
||||||
|
|
||||||
|
// Cases with Position values
|
||||||
|
EList::Open(p) | EList::End(p) | EList::Space(_, p) => Region::from_pos(*p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EWhen<'a> {
|
pub enum EWhen<'a> {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
|
@ -476,6 +823,32 @@ pub enum EWhen<'a> {
|
||||||
PatternAlignment(u32, Position),
|
PatternAlignment(u32, Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> EWhen<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
// Cases with child nodes that have get_region()
|
||||||
|
EWhen::Pattern(pattern, _) => pattern.get_region(),
|
||||||
|
EWhen::IfGuard(expr, _) => expr.get_region(),
|
||||||
|
EWhen::Condition(expr, _) => expr.get_region(),
|
||||||
|
EWhen::Branch(expr, _) => expr.get_region(),
|
||||||
|
|
||||||
|
// Cases with Position values
|
||||||
|
EWhen::Space(_, p)
|
||||||
|
| EWhen::When(p)
|
||||||
|
| EWhen::Is(p)
|
||||||
|
| EWhen::Arrow(p)
|
||||||
|
| EWhen::Bar(p)
|
||||||
|
| EWhen::IfToken(p)
|
||||||
|
| EWhen::IndentCondition(p)
|
||||||
|
| EWhen::IndentPattern(p)
|
||||||
|
| EWhen::IndentArrow(p)
|
||||||
|
| EWhen::IndentBranch(p)
|
||||||
|
| EWhen::IndentIfGuard(p)
|
||||||
|
| EWhen::PatternAlignment(_, p) => Region::from_pos(*p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EAbility<'a> {
|
pub enum EAbility<'a> {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
|
@ -486,6 +859,21 @@ pub enum EAbility<'a> {
|
||||||
DemandColon(Position),
|
DemandColon(Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> EAbility<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
// Case with child node that has get_region()
|
||||||
|
EAbility::Type(e_type, _) => e_type.get_region(),
|
||||||
|
|
||||||
|
// Cases with Position values
|
||||||
|
EAbility::Space(_, p)
|
||||||
|
| EAbility::DemandAlignment(_, p)
|
||||||
|
| EAbility::DemandName(p)
|
||||||
|
| EAbility::DemandColon(p) => Region::from_pos(*p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EIf<'a> {
|
pub enum EIf<'a> {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
|
@ -505,6 +893,26 @@ pub enum EIf<'a> {
|
||||||
IndentElseBranch(Position),
|
IndentElseBranch(Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> EIf<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
EIf::Condition(expr, _) | EIf::ThenBranch(expr, _) | EIf::ElseBranch(expr, _) => {
|
||||||
|
expr.get_region()
|
||||||
|
}
|
||||||
|
EIf::Space(_, p)
|
||||||
|
| EIf::If(p)
|
||||||
|
| EIf::Then(p)
|
||||||
|
| EIf::Else(p)
|
||||||
|
| EIf::IndentCondition(p)
|
||||||
|
| EIf::IndentIf(p)
|
||||||
|
| EIf::IndentThenToken(p)
|
||||||
|
| EIf::IndentElseToken(p)
|
||||||
|
| EIf::IndentThenBranch(p)
|
||||||
|
| EIf::IndentElseBranch(p) => Region::from_pos(*p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EExpect<'a> {
|
pub enum EExpect<'a> {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
|
@ -515,6 +923,18 @@ pub enum EExpect<'a> {
|
||||||
IndentCondition(Position),
|
IndentCondition(Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> EExpect<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
EExpect::Condition(expr, _) | EExpect::Continuation(expr, _) => expr.get_region(),
|
||||||
|
EExpect::Space(_, p)
|
||||||
|
| EExpect::Dbg(p)
|
||||||
|
| EExpect::Expect(p)
|
||||||
|
| EExpect::IndentCondition(p) => Region::from_pos(*p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EReturn<'a> {
|
pub enum EReturn<'a> {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
|
@ -522,6 +942,16 @@ pub enum EReturn<'a> {
|
||||||
ReturnValue(&'a EExpr<'a>, Position),
|
ReturnValue(&'a EExpr<'a>, Position),
|
||||||
IndentReturnValue(Position),
|
IndentReturnValue(Position),
|
||||||
}
|
}
|
||||||
|
impl<'a> EReturn<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
EReturn::ReturnValue(expr, _) => expr.get_region(),
|
||||||
|
EReturn::Space(_, p) | EReturn::Return(p) | EReturn::IndentReturnValue(p) => {
|
||||||
|
Region::from_pos(*p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EImport<'a> {
|
pub enum EImport<'a> {
|
||||||
|
@ -553,6 +983,44 @@ pub enum EImport<'a> {
|
||||||
EndNewline(Position),
|
EndNewline(Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> EImport<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
// Cases with child nodes that have get_region()
|
||||||
|
EImport::Params(params, _) => params.get_region(),
|
||||||
|
EImport::Annotation(e_type, _) => e_type.get_region(),
|
||||||
|
|
||||||
|
// Case with direct Region value
|
||||||
|
EImport::LowercaseAlias(r) => *r,
|
||||||
|
|
||||||
|
// Cases with Position values
|
||||||
|
EImport::Import(p)
|
||||||
|
| EImport::IndentStart(p)
|
||||||
|
| EImport::PackageShorthand(p)
|
||||||
|
| EImport::PackageShorthandDot(p)
|
||||||
|
| EImport::ModuleName(p)
|
||||||
|
| EImport::IndentAs(p)
|
||||||
|
| EImport::As(p)
|
||||||
|
| EImport::IndentAlias(p)
|
||||||
|
| EImport::Alias(p)
|
||||||
|
| EImport::IndentExposing(p)
|
||||||
|
| EImport::Exposing(p)
|
||||||
|
| EImport::ExposingListStart(p)
|
||||||
|
| EImport::ExposedName(p)
|
||||||
|
| EImport::ExposingListEnd(p)
|
||||||
|
| EImport::IndentIngestedPath(p)
|
||||||
|
| EImport::IngestedPath(p)
|
||||||
|
| EImport::IndentIngestedName(p)
|
||||||
|
| EImport::IngestedName(p)
|
||||||
|
| EImport::IndentColon(p)
|
||||||
|
| EImport::Colon(p)
|
||||||
|
| EImport::IndentAnnotation(p)
|
||||||
|
| EImport::Space(_, p)
|
||||||
|
| EImport::EndNewline(p) => Region::from_pos(*p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EImportParams<'a> {
|
pub enum EImportParams<'a> {
|
||||||
Indent(Position),
|
Indent(Position),
|
||||||
|
@ -563,6 +1031,19 @@ pub enum EImportParams<'a> {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> EImportParams<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
EImportParams::Indent(p) | EImportParams::Record(_, p) | EImportParams::Space(_, p) => {
|
||||||
|
Region::from_pos(*p)
|
||||||
|
}
|
||||||
|
EImportParams::RecordUpdateFound(r)
|
||||||
|
| EImportParams::RecordBuilderFound(r)
|
||||||
|
| EImportParams::RecordIgnoredFieldFound(r) => *r,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EPattern<'a> {
|
pub enum EPattern<'a> {
|
||||||
Record(PRecord<'a>, Position),
|
Record(PRecord<'a>, Position),
|
||||||
|
@ -587,6 +1068,32 @@ pub enum EPattern<'a> {
|
||||||
RecordUpdaterFunction(Position),
|
RecordUpdaterFunction(Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> EPattern<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
// Cases with child nodes that have get_region()
|
||||||
|
EPattern::Record(expr, _) => expr.get_region(),
|
||||||
|
EPattern::List(expr, _) => expr.get_region(),
|
||||||
|
EPattern::PInParens(expr, _) => expr.get_region(),
|
||||||
|
|
||||||
|
// Cases with Position values
|
||||||
|
EPattern::AsKeyword(position)
|
||||||
|
| EPattern::AsIdentifier(position)
|
||||||
|
| EPattern::Underscore(position)
|
||||||
|
| EPattern::NotAPattern(position)
|
||||||
|
| EPattern::Start(position)
|
||||||
|
| EPattern::End(position)
|
||||||
|
| EPattern::Space(_, position)
|
||||||
|
| EPattern::NumLiteral(_, position)
|
||||||
|
| EPattern::IndentStart(position)
|
||||||
|
| EPattern::IndentEnd(position)
|
||||||
|
| EPattern::AsIndentStart(position)
|
||||||
|
| EPattern::AccessorFunction(position)
|
||||||
|
| EPattern::RecordUpdaterFunction(position) => Region::from_pos(*position),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum PRecord<'a> {
|
pub enum PRecord<'a> {
|
||||||
End(Position),
|
End(Position),
|
||||||
|
@ -602,6 +1109,24 @@ pub enum PRecord<'a> {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> PRecord<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
// Cases with child nodes that have get_region()
|
||||||
|
PRecord::Pattern(pattern, _) => pattern.get_region(),
|
||||||
|
PRecord::Expr(expr, _) => expr.get_region(),
|
||||||
|
|
||||||
|
// Cases with Position values
|
||||||
|
PRecord::End(p)
|
||||||
|
| PRecord::Open(p)
|
||||||
|
| PRecord::Field(p)
|
||||||
|
| PRecord::Colon(p)
|
||||||
|
| PRecord::Optional(p)
|
||||||
|
| PRecord::Space(_, p) => Region::from_pos(*p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum PList<'a> {
|
pub enum PList<'a> {
|
||||||
End(Position),
|
End(Position),
|
||||||
|
@ -613,6 +1138,20 @@ pub enum PList<'a> {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> PList<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
// Case with child node that has get_region()
|
||||||
|
PList::Pattern(pattern, _) => pattern.get_region(),
|
||||||
|
|
||||||
|
// Cases with Position values
|
||||||
|
PList::End(p) | PList::Open(p) | PList::Rest(p) | PList::Space(_, p) => {
|
||||||
|
Region::from_pos(*p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum PInParens<'a> {
|
pub enum PInParens<'a> {
|
||||||
Empty(Position),
|
Empty(Position),
|
||||||
|
@ -623,6 +1162,21 @@ pub enum PInParens<'a> {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> PInParens<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
// Case with child node that has get_region()
|
||||||
|
PInParens::Pattern(pattern, _) => pattern.get_region(),
|
||||||
|
|
||||||
|
// Cases with Position values
|
||||||
|
PInParens::Empty(p)
|
||||||
|
| PInParens::End(p)
|
||||||
|
| PInParens::Open(p)
|
||||||
|
| PInParens::Space(_, p) => Region::from_pos(*p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum EType<'a> {
|
pub enum EType<'a> {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
|
@ -648,6 +1202,34 @@ pub enum EType<'a> {
|
||||||
TIndentEnd(Position),
|
TIndentEnd(Position),
|
||||||
TAsIndentStart(Position),
|
TAsIndentStart(Position),
|
||||||
}
|
}
|
||||||
|
impl<'a> EType<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
// Cases with child nodes that have get_region()
|
||||||
|
EType::TRecord(expr, _) => expr.get_region(),
|
||||||
|
EType::TTagUnion(expr, _) => expr.get_region(),
|
||||||
|
EType::TInParens(expr, _) => expr.get_region(),
|
||||||
|
EType::TApply(eapply, _) => eapply.get_region(),
|
||||||
|
EType::TInlineAlias(einline, _) => einline.get_region(),
|
||||||
|
EType::TAbilityImpl(eability, _) => eability.get_region(),
|
||||||
|
|
||||||
|
// Cases with Position values
|
||||||
|
EType::Space(_, p)
|
||||||
|
| EType::UnderscoreSpacing(p)
|
||||||
|
| EType::TBadTypeVariable(p)
|
||||||
|
| EType::TWildcard(p)
|
||||||
|
| EType::TInferred(p)
|
||||||
|
| EType::TStart(p)
|
||||||
|
| EType::TEnd(p)
|
||||||
|
| EType::TFunctionArgument(p)
|
||||||
|
| EType::TWhereBar(p)
|
||||||
|
| EType::TImplementsClause(p)
|
||||||
|
| EType::TIndentStart(p)
|
||||||
|
| EType::TIndentEnd(p)
|
||||||
|
| EType::TAsIndentStart(p) => Region::from_pos(*p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum ETypeRecord<'a> {
|
pub enum ETypeRecord<'a> {
|
||||||
|
@ -667,6 +1249,27 @@ pub enum ETypeRecord<'a> {
|
||||||
IndentEnd(Position),
|
IndentEnd(Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> ETypeRecord<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
// Case with child node that has get_region()
|
||||||
|
ETypeRecord::Type(type_expr, _) => type_expr.get_region(),
|
||||||
|
|
||||||
|
// Cases with Position values
|
||||||
|
ETypeRecord::End(p)
|
||||||
|
| ETypeRecord::Open(p)
|
||||||
|
| ETypeRecord::Field(p)
|
||||||
|
| ETypeRecord::Colon(p)
|
||||||
|
| ETypeRecord::Optional(p)
|
||||||
|
| ETypeRecord::Space(_, p)
|
||||||
|
| ETypeRecord::IndentOpen(p)
|
||||||
|
| ETypeRecord::IndentColon(p)
|
||||||
|
| ETypeRecord::IndentOptional(p)
|
||||||
|
| ETypeRecord::IndentEnd(p) => Region::from_pos(*p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum ETypeTagUnion<'a> {
|
pub enum ETypeTagUnion<'a> {
|
||||||
End(Position),
|
End(Position),
|
||||||
|
@ -677,6 +1280,20 @@ pub enum ETypeTagUnion<'a> {
|
||||||
Space(BadInputError, Position),
|
Space(BadInputError, Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> ETypeTagUnion<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
// Case with child node that has get_region()
|
||||||
|
ETypeTagUnion::Type(type_expr, _) => type_expr.get_region(),
|
||||||
|
|
||||||
|
// Cases with Position values
|
||||||
|
ETypeTagUnion::End(p) | ETypeTagUnion::Open(p) | ETypeTagUnion::Space(_, p) => {
|
||||||
|
Region::from_pos(*p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum ETypeInParens<'a> {
|
pub enum ETypeInParens<'a> {
|
||||||
/// e.g. (), which isn't a valid type
|
/// e.g. (), which isn't a valid type
|
||||||
|
@ -694,6 +1311,23 @@ pub enum ETypeInParens<'a> {
|
||||||
IndentEnd(Position),
|
IndentEnd(Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> ETypeInParens<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
// Cases with child nodes that have get_region()
|
||||||
|
ETypeInParens::Type(type_expr, _) => type_expr.get_region(),
|
||||||
|
|
||||||
|
// Cases with Position values
|
||||||
|
ETypeInParens::Empty(p)
|
||||||
|
| ETypeInParens::End(p)
|
||||||
|
| ETypeInParens::Open(p)
|
||||||
|
| ETypeInParens::Space(_, p)
|
||||||
|
| ETypeInParens::IndentOpen(p)
|
||||||
|
| ETypeInParens::IndentEnd(p) => Region::from_pos(*p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum ETypeApply {
|
pub enum ETypeApply {
|
||||||
///
|
///
|
||||||
|
@ -706,6 +1340,20 @@ pub enum ETypeApply {
|
||||||
StartIsNumber(Position),
|
StartIsNumber(Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ETypeApply {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
let pos = match self {
|
||||||
|
ETypeApply::StartNotUppercase(p)
|
||||||
|
| ETypeApply::End(p)
|
||||||
|
| ETypeApply::Space(_, p)
|
||||||
|
| ETypeApply::DoubleDot(p)
|
||||||
|
| ETypeApply::TrailingDot(p)
|
||||||
|
| ETypeApply::StartIsNumber(p) => p,
|
||||||
|
};
|
||||||
|
Region::from_pos(*pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum ETypeInlineAlias {
|
pub enum ETypeInlineAlias {
|
||||||
NotAnAlias(Position),
|
NotAnAlias(Position),
|
||||||
|
@ -713,6 +1361,17 @@ pub enum ETypeInlineAlias {
|
||||||
ArgumentNotLowercase(Position),
|
ArgumentNotLowercase(Position),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ETypeInlineAlias {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
let pos = match self {
|
||||||
|
ETypeInlineAlias::NotAnAlias(p)
|
||||||
|
| ETypeInlineAlias::Qualified(p)
|
||||||
|
| ETypeInlineAlias::ArgumentNotLowercase(p) => p,
|
||||||
|
};
|
||||||
|
Region::from_pos(*pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum ETypeAbilityImpl<'a> {
|
pub enum ETypeAbilityImpl<'a> {
|
||||||
End(Position),
|
End(Position),
|
||||||
|
@ -734,6 +1393,29 @@ pub enum ETypeAbilityImpl<'a> {
|
||||||
IndentBar(Position),
|
IndentBar(Position),
|
||||||
IndentAmpersand(Position),
|
IndentAmpersand(Position),
|
||||||
}
|
}
|
||||||
|
impl<'a> ETypeAbilityImpl<'a> {
|
||||||
|
pub fn get_region(&self) -> Region {
|
||||||
|
match self {
|
||||||
|
// Case with child node that has get_region()
|
||||||
|
ETypeAbilityImpl::Type(type_expr, _) => type_expr.get_region(),
|
||||||
|
ETypeAbilityImpl::Expr(expr, _) => expr.get_region(),
|
||||||
|
// Cases with Position values
|
||||||
|
ETypeAbilityImpl::End(p)
|
||||||
|
| ETypeAbilityImpl::Open(p)
|
||||||
|
| ETypeAbilityImpl::Field(p)
|
||||||
|
| ETypeAbilityImpl::UnderscoreField(p)
|
||||||
|
| ETypeAbilityImpl::Colon(p)
|
||||||
|
| ETypeAbilityImpl::Arrow(p)
|
||||||
|
| ETypeAbilityImpl::Optional(p)
|
||||||
|
| ETypeAbilityImpl::Space(_, p)
|
||||||
|
| ETypeAbilityImpl::Prefix(p)
|
||||||
|
| ETypeAbilityImpl::QuestionMark(p)
|
||||||
|
| ETypeAbilityImpl::Ampersand(p)
|
||||||
|
| ETypeAbilityImpl::IndentBar(p)
|
||||||
|
| ETypeAbilityImpl::IndentAmpersand(p) => Region::from_pos(*p),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> From<ERecord<'a>> for ETypeAbilityImpl<'a> {
|
impl<'a> From<ERecord<'a>> for ETypeAbilityImpl<'a> {
|
||||||
fn from(e: ERecord<'a>) -> Self {
|
fn from(e: ERecord<'a>) -> Self {
|
||||||
|
|
|
@ -20,5 +20,5 @@ pub use mono_ir::{MonoExpr, MonoExprId, MonoExprs};
|
||||||
pub use mono_module::{InternedStrId, Interns};
|
pub use mono_module::{InternedStrId, Interns};
|
||||||
pub use mono_num::Number;
|
pub use mono_num::Number;
|
||||||
pub use mono_struct::MonoFieldId;
|
pub use mono_struct::MonoFieldId;
|
||||||
pub use mono_type::{MonoType, MonoTypeId, MonoTypes};
|
pub use mono_type::{MonoType, MonoTypeId, MonoTypes, Primitive};
|
||||||
pub use specialize_type::{MonoTypeCache, Problem, RecordFieldIds, TupleElemIds};
|
pub use specialize_type::{MonoTypeCache, Problem, RecordFieldIds, TupleElemIds};
|
||||||
|
|
|
@ -194,6 +194,38 @@ impl<'a, 'c, 'd, 'i, 's, 't, P: Push<Problem>> Env<'a, 'c, 'd, 'i, 's, 't, P> {
|
||||||
|
|
||||||
MonoExpr::Struct(slice)
|
MonoExpr::Struct(slice)
|
||||||
}
|
}
|
||||||
|
Expr::If {
|
||||||
|
cond_var: _,
|
||||||
|
branch_var,
|
||||||
|
branches,
|
||||||
|
final_else,
|
||||||
|
} => {
|
||||||
|
let branch_type = mono_from_var(*branch_var);
|
||||||
|
|
||||||
|
let mono_final_else = self.to_mono_expr(&final_else.value);
|
||||||
|
let final_else = self.mono_exprs.add(mono_final_else, final_else.region);
|
||||||
|
|
||||||
|
let mut branch_pairs: Vec<((MonoExpr, Region), (MonoExpr, Region))> =
|
||||||
|
Vec::with_capacity_in(branches.len(), self.arena);
|
||||||
|
|
||||||
|
for (cond, body) in branches {
|
||||||
|
let mono_cond = self.to_mono_expr(&cond.value);
|
||||||
|
let mono_body = self.to_mono_expr(&body.value);
|
||||||
|
|
||||||
|
branch_pairs.push(((mono_cond, cond.region), (mono_body, body.region)));
|
||||||
|
}
|
||||||
|
|
||||||
|
let branches = self.mono_exprs.extend_pairs(branch_pairs.into_iter());
|
||||||
|
|
||||||
|
MonoExpr::If {
|
||||||
|
branch_type,
|
||||||
|
branches,
|
||||||
|
final_else,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::Var(symbol, var) | Expr::ParamsVar { symbol, var, .. } => {
|
||||||
|
MonoExpr::Lookup(*symbol, mono_from_var(*var))
|
||||||
|
}
|
||||||
// Expr::Call((fn_var, fn_expr, capture_var, ret_var), args, called_via) => {
|
// Expr::Call((fn_var, fn_expr, capture_var, ret_var), args, called_via) => {
|
||||||
// let opt_ret_type = mono_from_var(*var);
|
// let opt_ret_type = mono_from_var(*var);
|
||||||
|
|
||||||
|
@ -258,7 +290,6 @@ impl<'a, 'c, 'd, 'i, 's, 't, P: Push<Problem>> Env<'a, 'c, 'd, 'i, 's, 't, P> {
|
||||||
// })
|
// })
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// Expr::Var(symbol, var) => Some(MonoExpr::Lookup(*symbol, mono_from_var(*var)?)),
|
|
||||||
// Expr::LetNonRec(def, loc) => {
|
// Expr::LetNonRec(def, loc) => {
|
||||||
// let expr = self.to_mono_expr(def.loc_expr.value, stmts)?;
|
// let expr = self.to_mono_expr(def.loc_expr.value, stmts)?;
|
||||||
// let todo = (); // TODO if this is an underscore pattern and we're doing a fn call, convert it to Stmt::CallVoid
|
// let todo = (); // TODO if this is an underscore pattern and we're doing a fn call, convert it to Stmt::CallVoid
|
||||||
|
@ -276,7 +307,7 @@ impl<'a, 'c, 'd, 'i, 's, 't, P: Push<Problem>> Env<'a, 'c, 'd, 'i, 's, 't, P> {
|
||||||
// todo!("split up the pattern into various Assign statements.");
|
// todo!("split up the pattern into various Assign statements.");
|
||||||
// }
|
// }
|
||||||
// Expr::LetRec(vec, loc, illegal_cycle_mark) => todo!(),
|
// Expr::LetRec(vec, loc, illegal_cycle_mark) => todo!(),
|
||||||
_ => todo!(),
|
_ => todo!("{:?}", can_expr),
|
||||||
// Expr::List {
|
// Expr::List {
|
||||||
// elem_var,
|
// elem_var,
|
||||||
// loc_elems,
|
// loc_elems,
|
||||||
|
@ -298,12 +329,6 @@ impl<'a, 'c, 'd, 'i, 's, 't, P: Push<Problem>> Env<'a, 'c, 'd, 'i, 's, 't, P> {
|
||||||
// branches_cond_var,
|
// branches_cond_var,
|
||||||
// exhaustive,
|
// exhaustive,
|
||||||
// } => todo!(),
|
// } => todo!(),
|
||||||
// Expr::If {
|
|
||||||
// cond_var,
|
|
||||||
// branch_var,
|
|
||||||
// branches,
|
|
||||||
// final_else,
|
|
||||||
// } => todo!(),
|
|
||||||
// Expr::Call(_, vec, called_via) => todo!(),
|
// Expr::Call(_, vec, called_via) => todo!(),
|
||||||
// Expr::RunLowLevel { op, args, ret_var } => todo!(),
|
// Expr::RunLowLevel { op, args, ret_var } => todo!(),
|
||||||
// Expr::ForeignCall {
|
// Expr::ForeignCall {
|
||||||
|
@ -405,7 +430,7 @@ fn to_num(primitive: Primitive, val: IntValue, problems: &mut impl Push<Problem>
|
||||||
})),
|
})),
|
||||||
Primitive::U128 => MonoExpr::Number(Number::U128(val.as_u128())),
|
Primitive::U128 => MonoExpr::Number(Number::U128(val.as_u128())),
|
||||||
Primitive::I128 => MonoExpr::Number(Number::I128(val.as_i128())),
|
Primitive::I128 => MonoExpr::Number(Number::I128(val.as_i128())),
|
||||||
Primitive::Str | Primitive::Crash => {
|
Primitive::Str | Primitive::Crash | Primitive::Bool => {
|
||||||
let problem = Problem::NumSpecializedToWrongType(Some(MonoType::Primitive(primitive)));
|
let problem = Problem::NumSpecializedToWrongType(Some(MonoType::Primitive(primitive)));
|
||||||
problems.push(problem);
|
problems.push(problem);
|
||||||
MonoExpr::CompilerBug(problem)
|
MonoExpr::CompilerBug(problem)
|
||||||
|
@ -432,7 +457,8 @@ fn to_frac(primitive: Primitive, val: f64, problems: &mut impl Push<Problem>) ->
|
||||||
| Primitive::U128
|
| Primitive::U128
|
||||||
| Primitive::I128
|
| Primitive::I128
|
||||||
| Primitive::Str
|
| Primitive::Str
|
||||||
| Primitive::Crash => {
|
| Primitive::Crash
|
||||||
|
| Primitive::Bool => {
|
||||||
let problem = Problem::NumSpecializedToWrongType(Some(MonoType::Primitive(primitive)));
|
let problem = Problem::NumSpecializedToWrongType(Some(MonoType::Primitive(primitive)));
|
||||||
problems.push(problem);
|
problems.push(problem);
|
||||||
MonoExpr::CompilerBug(problem)
|
MonoExpr::CompilerBug(problem)
|
||||||
|
@ -455,7 +481,12 @@ fn char_to_int(primitive: Primitive, ch: char, problems: &mut impl Push<Problem>
|
||||||
Primitive::I128 => MonoExpr::Number(Number::I128(ch as i128)),
|
Primitive::I128 => MonoExpr::Number(Number::I128(ch as i128)),
|
||||||
Primitive::I16 => MonoExpr::Number(Number::I16(ch as i16)),
|
Primitive::I16 => MonoExpr::Number(Number::I16(ch as i16)),
|
||||||
Primitive::I8 => MonoExpr::Number(Number::I8(ch as i8)),
|
Primitive::I8 => MonoExpr::Number(Number::I8(ch as i8)),
|
||||||
Primitive::Str | Primitive::Dec | Primitive::F32 | Primitive::F64 | Primitive::Crash => {
|
Primitive::Str
|
||||||
|
| Primitive::Dec
|
||||||
|
| Primitive::F32
|
||||||
|
| Primitive::F64
|
||||||
|
| Primitive::Crash
|
||||||
|
| Primitive::Bool => {
|
||||||
let problem = Problem::CharSpecializedToWrongType(Some(MonoType::Primitive(primitive)));
|
let problem = Problem::CharSpecializedToWrongType(Some(MonoType::Primitive(primitive)));
|
||||||
problems.push(problem);
|
problems.push(problem);
|
||||||
MonoExpr::CompilerBug(problem)
|
MonoExpr::CompilerBug(problem)
|
||||||
|
|
|
@ -6,7 +6,7 @@ use roc_can::expr::Recursive;
|
||||||
use roc_module::low_level::LowLevel;
|
use roc_module::low_level::LowLevel;
|
||||||
use roc_module::symbol::Symbol;
|
use roc_module::symbol::Symbol;
|
||||||
use roc_region::all::Region;
|
use roc_region::all::Region;
|
||||||
use soa::{Index, NonEmptySlice, Slice, Slice2, Slice3};
|
use soa::{Index, NonEmptySlice, PairSlice, Slice, Slice2, Slice3};
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
|
@ -146,6 +146,50 @@ impl MonoExprs {
|
||||||
|
|
||||||
Slice::new(start as u32, len as u16)
|
Slice::new(start as u32, len as u16)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn iter_pair_slice(
|
||||||
|
&self,
|
||||||
|
exprs: PairSlice<MonoExpr>,
|
||||||
|
) -> impl Iterator<Item = (&MonoExpr, &MonoExpr)> {
|
||||||
|
exprs.indices_iter().map(|(index_a, index_b)| {
|
||||||
|
debug_assert!(
|
||||||
|
self.exprs.len() > index_a && self.exprs.len() > index_b,
|
||||||
|
"A Slice index was not found in MonoExprs. This should never happen!"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Safety: we should only ever hand out MonoExprId slices that are valid indices into here.
|
||||||
|
unsafe {
|
||||||
|
(
|
||||||
|
self.exprs.get_unchecked(index_a),
|
||||||
|
self.exprs.get_unchecked(index_b),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn extend_pairs(
|
||||||
|
&mut self,
|
||||||
|
exprs: impl Iterator<Item = ((MonoExpr, Region), (MonoExpr, Region))>,
|
||||||
|
) -> PairSlice<MonoExpr> {
|
||||||
|
let start = self.exprs.len();
|
||||||
|
|
||||||
|
let additional = exprs.size_hint().0 * 2;
|
||||||
|
self.exprs.reserve(additional);
|
||||||
|
self.regions.reserve(additional);
|
||||||
|
|
||||||
|
let mut pairs = 0;
|
||||||
|
|
||||||
|
for ((expr_a, region_a), (expr_b, region_b)) in exprs {
|
||||||
|
self.exprs.push(expr_a);
|
||||||
|
self.exprs.push(expr_b);
|
||||||
|
self.regions.push(region_a);
|
||||||
|
self.regions.push(region_b);
|
||||||
|
|
||||||
|
pairs += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PairSlice::new(start as u32, pairs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
@ -159,82 +203,6 @@ impl MonoExprId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
||||||
pub struct MonoStmtId {
|
|
||||||
inner: Index<MonoStmt>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MonoStmtId {
|
|
||||||
pub(crate) unsafe fn new_unchecked(inner: Index<MonoStmt>) -> Self {
|
|
||||||
Self { inner }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
|
||||||
pub enum MonoStmt {
|
|
||||||
/// Assign to a variable.
|
|
||||||
Assign(IdentId, MonoExprId),
|
|
||||||
AssignRec(IdentId, MonoExprId),
|
|
||||||
|
|
||||||
/// Introduce a variable, e.g. `var foo_` (we'll MonoStmt::Assign to it later.)
|
|
||||||
Declare(IdentId),
|
|
||||||
|
|
||||||
/// The `return` statement
|
|
||||||
Return(MonoExprId),
|
|
||||||
|
|
||||||
/// The "crash" keyword. Importantly, during code gen we must mark this as "nothing happens after this"
|
|
||||||
Crash {
|
|
||||||
msg: MonoExprId,
|
|
||||||
/// The type of the `crash` expression (which will have unified to whatever's around it)
|
|
||||||
expr_type: MonoTypeId,
|
|
||||||
},
|
|
||||||
|
|
||||||
Expect {
|
|
||||||
condition: MonoExprId,
|
|
||||||
/// If the expectation fails, we print the values of all the named variables
|
|
||||||
/// in the final expr. These are those values.
|
|
||||||
lookups_in_cond: Slice2<MonoTypeId, IdentId>,
|
|
||||||
},
|
|
||||||
|
|
||||||
Dbg {
|
|
||||||
source_location: InternedStrId,
|
|
||||||
source: InternedStrId,
|
|
||||||
expr: MonoExprId,
|
|
||||||
expr_type: MonoTypeId,
|
|
||||||
name: IdentId,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Call a function that has no return value (or which we are discarding due to an underscore pattern).
|
|
||||||
CallVoid {
|
|
||||||
fn_type: MonoTypeId,
|
|
||||||
fn_expr: MonoExprId,
|
|
||||||
args: Slice2<MonoTypeId, MonoExprId>,
|
|
||||||
/// This is the type of the closure based only on canonical IR info,
|
|
||||||
/// not considering what other closures might later influence it.
|
|
||||||
/// Lambda set specialization may change this type later!
|
|
||||||
capture_type: MonoTypeId,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Branching
|
|
||||||
When {
|
|
||||||
/// The actual condition of the when expression.
|
|
||||||
cond: MonoExprId,
|
|
||||||
cond_type: MonoTypeId,
|
|
||||||
/// Type of each branch (and therefore the type of the entire `when` expression)
|
|
||||||
branch_type: MonoTypeId,
|
|
||||||
/// Note: if the branches weren't exhaustive, we will have already generated a default
|
|
||||||
/// branch which crashes if it's reached. (The compiler will have reported an error already;
|
|
||||||
/// this is for if you want to run anyway.)
|
|
||||||
branches: NonEmptySlice<WhenBranch>,
|
|
||||||
},
|
|
||||||
If {
|
|
||||||
/// Type of each branch (and therefore the type of the entire `if` expression)
|
|
||||||
branch_type: MonoTypeId,
|
|
||||||
branches: Slice<(MonoStmtId, MonoStmtId)>,
|
|
||||||
final_else: Option<MonoTypeId>,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
pub enum MonoExpr {
|
pub enum MonoExpr {
|
||||||
Str(InternedStrId),
|
Str(InternedStrId),
|
||||||
|
@ -324,21 +292,15 @@ pub enum MonoExpr {
|
||||||
args: Slice2<MonoTypeId, MonoExprId>,
|
args: Slice2<MonoTypeId, MonoExprId>,
|
||||||
},
|
},
|
||||||
|
|
||||||
Block {
|
If {
|
||||||
stmts: Slice<MonoStmtId>,
|
branch_type: MonoTypeId,
|
||||||
final_expr: MonoExprId,
|
branches: PairSlice<MonoExpr>,
|
||||||
|
final_else: MonoExprId,
|
||||||
},
|
},
|
||||||
|
|
||||||
CompilerBug(Problem),
|
CompilerBug(Problem),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
|
||||||
pub struct WhenBranch {
|
|
||||||
pub patterns: Slice<MonoPatternId>,
|
|
||||||
pub body: Slice<MonoStmtId>,
|
|
||||||
pub guard: Option<MonoExprId>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum MonoPattern {
|
pub enum MonoPattern {
|
||||||
Identifier(IdentId),
|
Identifier(IdentId),
|
||||||
|
|
|
@ -66,6 +66,10 @@ impl MonoTypeId {
|
||||||
inner: Index::new(14),
|
inner: Index::new(14),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const BOOL: Self = Self {
|
||||||
|
inner: Index::new(15),
|
||||||
|
};
|
||||||
|
|
||||||
pub const DEFAULT_INT: Self = Self::I64; // TODO change this to I128
|
pub const DEFAULT_INT: Self = Self::I64; // TODO change this to I128
|
||||||
pub const DEFAULT_FRAC: Self = Self::DEC;
|
pub const DEFAULT_FRAC: Self = Self::DEC;
|
||||||
|
|
||||||
|
@ -100,6 +104,7 @@ impl MonoTypes {
|
||||||
MonoType::Primitive(Primitive::F32),
|
MonoType::Primitive(Primitive::F32),
|
||||||
MonoType::Primitive(Primitive::F64),
|
MonoType::Primitive(Primitive::F64),
|
||||||
MonoType::Primitive(Primitive::Dec),
|
MonoType::Primitive(Primitive::Dec),
|
||||||
|
MonoType::Primitive(Primitive::Bool),
|
||||||
],
|
],
|
||||||
ids: Vec::new(),
|
ids: Vec::new(),
|
||||||
slices: Vec::new(),
|
slices: Vec::new(),
|
||||||
|
@ -232,6 +237,7 @@ pub enum Primitive {
|
||||||
F32,
|
F32,
|
||||||
F64,
|
F64,
|
||||||
Dec,
|
Dec,
|
||||||
|
Bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
|
|
@ -114,6 +114,8 @@ impl<'a, 'c, 'd, 'e, 'f, 'm, 'p, P: Push<Problem>> Env<'a, 'c, 'd, 'e, 'f, 'm, '
|
||||||
// .flat_map(|var_index| self.lower_var( subs, subs[var_index]));
|
// .flat_map(|var_index| self.lower_var( subs, subs[var_index]));
|
||||||
|
|
||||||
// let arg = new_args.next();
|
// let arg = new_args.next();
|
||||||
|
} else if symbol == Symbol::BOOL_BOOL {
|
||||||
|
MonoTypeId::BOOL
|
||||||
} else {
|
} else {
|
||||||
todo!("implement lower_builtin for symbol {symbol:?} - or, if all the builtins are already in here, report a compiler bug instead of panicking like this.");
|
todo!("implement lower_builtin for symbol {symbol:?} - or, if all the builtins are already in here, report a compiler bug instead of panicking like this.");
|
||||||
}
|
}
|
||||||
|
@ -476,7 +478,24 @@ fn number_args_to_mono_id(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Content::RangedNumber(_numeric_range) => todo!(),
|
Content::RangedNumber(range) => {
|
||||||
|
use roc_types::num::NumericRange::*;
|
||||||
|
|
||||||
|
return match *range {
|
||||||
|
IntAtLeastSigned(int_lit_width) => {
|
||||||
|
int_lit_width_to_mono_type_id(int_lit_width)
|
||||||
|
}
|
||||||
|
IntAtLeastEitherSign(int_lit_width) => {
|
||||||
|
int_lit_width_to_mono_type_id(int_lit_width)
|
||||||
|
}
|
||||||
|
NumAtLeastSigned(int_lit_width) => {
|
||||||
|
int_lit_width_to_mono_type_id(int_lit_width)
|
||||||
|
}
|
||||||
|
NumAtLeastEitherSign(int_lit_width) => {
|
||||||
|
int_lit_width_to_mono_type_id(int_lit_width)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// This is an invalid number type, so break out of
|
// This is an invalid number type, so break out of
|
||||||
// the alias-unrolling loop in order to return an error.
|
// the alias-unrolling loop in order to return an error.
|
||||||
|
|
|
@ -132,7 +132,7 @@ fn dbg_mono_expr<'a>(
|
||||||
) -> &'a str {
|
) -> &'a str {
|
||||||
let mut buf = bumpalo::collections::String::new_in(arena);
|
let mut buf = bumpalo::collections::String::new_in(arena);
|
||||||
|
|
||||||
dbg_mono_expr_help(arena, mono_exprs, interns, expr, &mut buf);
|
dbg_mono_expr_help(arena, mono_exprs, interns, expr, &mut buf).unwrap();
|
||||||
|
|
||||||
buf.into_bump_str()
|
buf.into_bump_str()
|
||||||
}
|
}
|
||||||
|
@ -143,32 +143,62 @@ fn dbg_mono_expr_help<'a>(
|
||||||
interns: &Interns<'a>,
|
interns: &Interns<'a>,
|
||||||
expr: &MonoExpr,
|
expr: &MonoExpr,
|
||||||
buf: &mut impl Write,
|
buf: &mut impl Write,
|
||||||
) {
|
) -> Result<(), core::fmt::Error> {
|
||||||
match expr {
|
match expr {
|
||||||
MonoExpr::Str(interned_str_id) => {
|
MonoExpr::Str(interned_str_id) => {
|
||||||
write!(buf, "Str({:?})", interns.get_str(arena, *interned_str_id)).unwrap();
|
write!(buf, "Str({:?})", interns.get_str(arena, *interned_str_id))
|
||||||
}
|
}
|
||||||
MonoExpr::Number(number) => {
|
MonoExpr::Number(number) => {
|
||||||
write!(buf, "Number({:?})", number).unwrap();
|
write!(buf, "Number({:?})", number)
|
||||||
}
|
}
|
||||||
MonoExpr::Struct(field_exprs) => {
|
MonoExpr::Struct(field_exprs) => {
|
||||||
write!(buf, "Struct([").unwrap();
|
write!(buf, "Struct([")?;
|
||||||
|
|
||||||
for (index, expr) in mono_exprs.iter_slice(field_exprs.as_slice()).enumerate() {
|
for (index, expr) in mono_exprs.iter_slice(field_exprs.as_slice()).enumerate() {
|
||||||
if index > 0 {
|
if index > 0 {
|
||||||
write!(buf, ", ").unwrap();
|
write!(buf, ", ")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg_mono_expr_help(arena, mono_exprs, interns, expr, buf);
|
dbg_mono_expr_help(arena, mono_exprs, interns, expr, buf)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(buf, "])").unwrap();
|
write!(buf, "])")
|
||||||
}
|
}
|
||||||
MonoExpr::Unit => {
|
MonoExpr::Unit => {
|
||||||
write!(buf, "{{}}").unwrap();
|
write!(buf, "{{}}")
|
||||||
|
}
|
||||||
|
MonoExpr::If {
|
||||||
|
branch_type: _,
|
||||||
|
branches,
|
||||||
|
final_else,
|
||||||
|
} => {
|
||||||
|
write!(buf, "If(",)?;
|
||||||
|
|
||||||
|
for (index, (cond, branch)) in mono_exprs.iter_pair_slice(*branches).enumerate() {
|
||||||
|
if index > 0 {
|
||||||
|
write!(buf, ", ")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbg_mono_expr_help(arena, mono_exprs, interns, cond, buf)?;
|
||||||
|
write!(buf, " -> ")?;
|
||||||
|
dbg_mono_expr_help(arena, mono_exprs, interns, branch, buf)?;
|
||||||
|
write!(buf, ")")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
write!(buf, ", ")?;
|
||||||
|
dbg_mono_expr_help(
|
||||||
|
arena,
|
||||||
|
mono_exprs,
|
||||||
|
interns,
|
||||||
|
mono_exprs.get_expr(*final_else),
|
||||||
|
buf,
|
||||||
|
)?;
|
||||||
|
write!(buf, ")")
|
||||||
|
}
|
||||||
|
MonoExpr::Lookup(ident, _mono_type_id) => {
|
||||||
|
write!(buf, "{:?}", ident)
|
||||||
}
|
}
|
||||||
// MonoExpr::List { elem_type, elems } => todo!(),
|
// MonoExpr::List { elem_type, elems } => todo!(),
|
||||||
// MonoExpr::Lookup(symbol, mono_type_id) => todo!(),
|
|
||||||
// MonoExpr::ParameterizedLookup {
|
// MonoExpr::ParameterizedLookup {
|
||||||
// name,
|
// name,
|
||||||
// lookup_type,
|
// lookup_type,
|
||||||
|
@ -243,7 +273,7 @@ fn dbg_mono_expr_help<'a>(
|
||||||
// name,
|
// name,
|
||||||
// } => todo!(),
|
// } => todo!(),
|
||||||
MonoExpr::CompilerBug(problem) => {
|
MonoExpr::CompilerBug(problem) => {
|
||||||
write!(buf, "CompilerBug({:?})", problem).unwrap();
|
write!(buf, "CompilerBug({:?})", problem)
|
||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
todo!("Implement dbg_mono_expr for {:?}", other)
|
todo!("Implement dbg_mono_expr for {:?}", other)
|
||||||
|
|
36
crates/compiler/specialize_types/tests/specialize_if.rs
Normal file
36
crates/compiler/specialize_types/tests/specialize_if.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#[macro_use]
|
||||||
|
extern crate pretty_assertions;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod helpers;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod specialize_structs {
|
||||||
|
use crate::helpers::expect_mono_expr_str;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn single_branch() {
|
||||||
|
let cond = "Bool.true";
|
||||||
|
let then = 42;
|
||||||
|
let else_ = 0;
|
||||||
|
|
||||||
|
expect_mono_expr_str(
|
||||||
|
format!("if {cond} then {then} else {else_}"),
|
||||||
|
format!("If(`{cond}` -> Number(I8({then}))), Number(I8({else_})))"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn multiple_branches() {
|
||||||
|
let cond1 = "Bool.false";
|
||||||
|
let then1 = 256;
|
||||||
|
let cond2 = "Bool.true";
|
||||||
|
let then2 = 24;
|
||||||
|
let then_else = 0;
|
||||||
|
|
||||||
|
expect_mono_expr_str(
|
||||||
|
format!("if {cond1} then {then1} else if {cond2} then {then2} else {then_else}"),
|
||||||
|
format!("If(`{cond1}` -> Number(I16({then1}))), `{cond2}` -> Number(I16({then2}))), Number(I16({then_else})))"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,7 +6,8 @@ mod helpers;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod specialize_primitives {
|
mod specialize_primitives {
|
||||||
use roc_specialize_types::{MonoExpr, Number};
|
use roc_module::symbol::Symbol;
|
||||||
|
use roc_specialize_types::{MonoExpr, MonoTypeId, Number};
|
||||||
|
|
||||||
use super::helpers::{expect_mono_expr, expect_mono_expr_with_interns};
|
use super::helpers::{expect_mono_expr, expect_mono_expr_with_interns};
|
||||||
|
|
||||||
|
@ -170,4 +171,22 @@ mod specialize_primitives {
|
||||||
MonoExpr::Number(Number::Dec(expected)),
|
MonoExpr::Number(Number::Dec(expected)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bool_true() {
|
||||||
|
let expected = "Bool.true";
|
||||||
|
expect_mono_expr(
|
||||||
|
expected,
|
||||||
|
MonoExpr::Lookup(Symbol::BOOL_TRUE, MonoTypeId::BOOL),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bool_false() {
|
||||||
|
let expected = "Bool.false";
|
||||||
|
expect_mono_expr(
|
||||||
|
expected,
|
||||||
|
MonoExpr::Lookup(Symbol::BOOL_FALSE, MonoTypeId::BOOL),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,7 @@ fn create_llvm_module<'a>(
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(LoadMonomorphizedError::LoadingProblem(roc_load::LoadingProblem::FormattedReport(
|
Err(LoadMonomorphizedError::LoadingProblem(roc_load::LoadingProblem::FormattedReport(
|
||||||
report,
|
report,
|
||||||
|
_,
|
||||||
))) => {
|
))) => {
|
||||||
println!("{report}");
|
println!("{report}");
|
||||||
panic!();
|
panic!();
|
||||||
|
|
|
@ -173,6 +173,7 @@ fn compiles_to_ir(test_name: &str, src: &str, mode: &str, allow_type_errors: boo
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(LoadMonomorphizedError::LoadingProblem(roc_load::LoadingProblem::FormattedReport(
|
Err(LoadMonomorphizedError::LoadingProblem(roc_load::LoadingProblem::FormattedReport(
|
||||||
report,
|
report,
|
||||||
|
_,
|
||||||
))) => {
|
))) => {
|
||||||
println!("{report}");
|
println!("{report}");
|
||||||
panic!();
|
panic!();
|
||||||
|
|
|
@ -64,6 +64,7 @@ pub(crate) fn write_compiled_ir<'a>(
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(LoadMonomorphizedError::LoadingProblem(roc_load::LoadingProblem::FormattedReport(
|
Err(LoadMonomorphizedError::LoadingProblem(roc_load::LoadingProblem::FormattedReport(
|
||||||
report,
|
report,
|
||||||
|
_,
|
||||||
))) => {
|
))) => {
|
||||||
println!("{report}");
|
println!("{report}");
|
||||||
panic!();
|
panic!();
|
||||||
|
|
|
@ -674,7 +674,7 @@ pub fn load_module_for_docs(filename: PathBuf) -> LoadedModule {
|
||||||
load_config,
|
load_config,
|
||||||
) {
|
) {
|
||||||
Ok(loaded) => loaded,
|
Ok(loaded) => loaded,
|
||||||
Err(LoadingProblem::FormattedReport(report)) => {
|
Err(LoadingProblem::FormattedReport(report, _)) => {
|
||||||
eprintln!("{report}");
|
eprintln!("{report}");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -437,7 +437,7 @@ pub fn load_types(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap_or_else(|problem| match problem {
|
.unwrap_or_else(|problem| match problem {
|
||||||
LoadingProblem::FormattedReport(report) => {
|
LoadingProblem::FormattedReport(report, _) => {
|
||||||
eprintln!("{report}");
|
eprintln!("{report}");
|
||||||
|
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
|
|
|
@ -122,7 +122,7 @@ pub(crate) fn global_analysis(doc_info: DocInfo) -> Vec<AnalyzedDocument> {
|
||||||
Ok(module) => module,
|
Ok(module) => module,
|
||||||
Err(problem) => {
|
Err(problem) => {
|
||||||
let all_problems = problem
|
let all_problems = problem
|
||||||
.into_lsp_diagnostic(&())
|
.into_lsp_diagnostic(&doc_info.line_info)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ pub(crate) mod diag {
|
||||||
|
|
||||||
use roc_problem::Severity;
|
use roc_problem::Severity;
|
||||||
use roc_reporting::report::RocDocAllocator;
|
use roc_reporting::report::RocDocAllocator;
|
||||||
use tower_lsp::lsp_types::{Diagnostic, DiagnosticSeverity, Position, Range};
|
use tower_lsp::lsp_types::{Diagnostic, DiagnosticSeverity};
|
||||||
|
|
||||||
use super::ToRange;
|
use super::ToRange;
|
||||||
|
|
||||||
|
@ -102,19 +102,16 @@ pub(crate) mod diag {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoLspDiagnostic<'_> for &LoadingProblem<'_> {
|
impl IntoLspDiagnostic<'_> for &LoadingProblem<'_> {
|
||||||
type Feed = ();
|
type Feed = LineInfo;
|
||||||
|
|
||||||
fn into_lsp_diagnostic(self, _feed: &()) -> Option<Diagnostic> {
|
fn into_lsp_diagnostic(self, line_info: &LineInfo) -> Option<Diagnostic> {
|
||||||
let range = Range {
|
let range = self
|
||||||
start: Position {
|
.get_region()
|
||||||
line: 0,
|
.unwrap_or(Region::new(
|
||||||
character: 0,
|
roc_region::all::Position::new(0),
|
||||||
},
|
roc_region::all::Position::new(10_000_000),
|
||||||
end: Position {
|
))
|
||||||
line: 0,
|
.to_range(line_info);
|
||||||
character: 1,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let msg = match self {
|
let msg = match self {
|
||||||
LoadingProblem::FileProblem { filename, error } => {
|
LoadingProblem::FileProblem { filename, error } => {
|
||||||
|
@ -152,7 +149,7 @@ pub(crate) mod diag {
|
||||||
LoadingProblem::TriedToImportAppModule => {
|
LoadingProblem::TriedToImportAppModule => {
|
||||||
"Attempted to import app module".to_string()
|
"Attempted to import app module".to_string()
|
||||||
}
|
}
|
||||||
LoadingProblem::FormattedReport(report) => report.clone(),
|
LoadingProblem::FormattedReport(report, _region) => report.clone(),
|
||||||
LoadingProblem::ImportCycle(_, _) => {
|
LoadingProblem::ImportCycle(_, _) => {
|
||||||
"Circular dependency between modules".to_string()
|
"Circular dependency between modules".to_string()
|
||||||
}
|
}
|
||||||
|
@ -194,7 +191,10 @@ pub(crate) mod diag {
|
||||||
fn into_lsp_diagnostic(self, fmt: &'a ProblemFmt<'a>) -> Option<Diagnostic> {
|
fn into_lsp_diagnostic(self, fmt: &'a ProblemFmt<'a>) -> Option<Diagnostic> {
|
||||||
let range = self
|
let range = self
|
||||||
.region()
|
.region()
|
||||||
.unwrap_or_else(Region::zero)
|
.unwrap_or(Region::new(
|
||||||
|
roc_region::all::Position::new(0),
|
||||||
|
roc_region::all::Position::new(10000000),
|
||||||
|
))
|
||||||
.to_range(fmt.line_info);
|
.to_range(fmt.line_info);
|
||||||
|
|
||||||
let report = roc_reporting::report::can_problem(
|
let report = roc_reporting::report::can_problem(
|
||||||
|
@ -228,7 +228,10 @@ pub(crate) mod diag {
|
||||||
fn into_lsp_diagnostic(self, fmt: &'a ProblemFmt<'a>) -> Option<Diagnostic> {
|
fn into_lsp_diagnostic(self, fmt: &'a ProblemFmt<'a>) -> Option<Diagnostic> {
|
||||||
let range = self
|
let range = self
|
||||||
.region()
|
.region()
|
||||||
.unwrap_or_else(Region::zero)
|
.unwrap_or(Region::new(
|
||||||
|
roc_region::all::Position::new(0),
|
||||||
|
roc_region::all::Position::new(10000000),
|
||||||
|
))
|
||||||
.to_range(fmt.line_info);
|
.to_range(fmt.line_info);
|
||||||
|
|
||||||
let report = roc_reporting::report::type_problem(
|
let report = roc_reporting::report::type_problem(
|
||||||
|
|
|
@ -80,7 +80,7 @@ pub fn compile_to_mono<'a, 'i, I: Iterator<Item = &'i str>>(
|
||||||
(m.can_problems, m.type_problems)
|
(m.can_problems, m.type_problems)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Err(LoadMonomorphizedError::LoadingProblem(LoadingProblem::FormattedReport(report))) => {
|
Err(LoadMonomorphizedError::LoadingProblem(LoadingProblem::FormattedReport(report, _))) => {
|
||||||
return (
|
return (
|
||||||
None,
|
None,
|
||||||
Problems {
|
Problems {
|
||||||
|
|
|
@ -8,6 +8,6 @@ mod soa_slice3;
|
||||||
|
|
||||||
pub use either_index::*;
|
pub use either_index::*;
|
||||||
pub use soa_index::*;
|
pub use soa_index::*;
|
||||||
pub use soa_slice::{NonEmptySlice, Slice};
|
pub use soa_slice::{NonEmptySlice, PairSlice, Slice};
|
||||||
pub use soa_slice2::Slice2;
|
pub use soa_slice2::Slice2;
|
||||||
pub use soa_slice3::Slice3;
|
pub use soa_slice3::Slice3;
|
||||||
|
|
|
@ -274,3 +274,41 @@ impl<T> IntoIterator for NonEmptySlice<T> {
|
||||||
self.inner.into_iter()
|
self.inner.into_iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Like `Slice`, but for pairs of `T`
|
||||||
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Copy, Clone)]
|
||||||
|
pub struct PairSlice<T>(Slice<T>);
|
||||||
|
|
||||||
|
impl<T> PairSlice<T> {
|
||||||
|
pub const fn start(self) -> u32 {
|
||||||
|
self.0.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn empty() -> Self {
|
||||||
|
Self(Slice::empty())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn len(&self) -> usize {
|
||||||
|
self.0.len() / 2
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn is_empty(&self) -> bool {
|
||||||
|
self.0.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn indices_iter(&self) -> impl Iterator<Item = (usize, usize)> {
|
||||||
|
(self.0.start as usize..(self.0.start as usize + self.0.length as usize))
|
||||||
|
.step_by(2)
|
||||||
|
.map(|i| (i, i + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn new(start: u32, length: u16) -> Self {
|
||||||
|
Self(Slice::new(start, length * 2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Default for PairSlice<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self(Slice::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -166,7 +166,7 @@ fn valgrind_test_linux(source: &str) {
|
||||||
run_with_valgrind(&binary_path);
|
run_with_valgrind(&binary_path);
|
||||||
}
|
}
|
||||||
Err(roc_build::program::BuildFileError::LoadingProblem(
|
Err(roc_build::program::BuildFileError::LoadingProblem(
|
||||||
roc_load::LoadingProblem::FormattedReport(report),
|
roc_load::LoadingProblem::FormattedReport(report, _),
|
||||||
)) => {
|
)) => {
|
||||||
eprintln!("{report}");
|
eprintln!("{report}");
|
||||||
panic!("");
|
panic!("");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue