mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
Introduce LineColumnRegion and force conversion
This commit is contained in:
parent
721233f9c8
commit
82d2be0635
11 changed files with 507 additions and 287 deletions
|
@ -12,6 +12,7 @@ use roc_gen_llvm::llvm::externs::add_default_roc_externs;
|
||||||
use roc_load::file::LoadingProblem;
|
use roc_load::file::LoadingProblem;
|
||||||
use roc_mono::ir::OptLevel;
|
use roc_mono::ir::OptLevel;
|
||||||
use roc_parse::parser::SyntaxError;
|
use roc_parse::parser::SyntaxError;
|
||||||
|
use roc_region::all::LineInfo;
|
||||||
use roc_types::pretty_print::{content_to_string, name_all_type_vars};
|
use roc_types::pretty_print::{content_to_string, name_all_type_vars};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::str::from_utf8_unchecked;
|
use std::str::from_utf8_unchecked;
|
||||||
|
@ -91,6 +92,7 @@ pub fn gen_and_eval<'a>(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let line_info = LineInfo::new(&src);
|
||||||
let src_lines: Vec<&str> = src.split('\n').collect();
|
let src_lines: Vec<&str> = src.split('\n').collect();
|
||||||
let palette = DEFAULT_PALETTE;
|
let palette = DEFAULT_PALETTE;
|
||||||
|
|
||||||
|
@ -98,7 +100,7 @@ pub fn gen_and_eval<'a>(
|
||||||
let alloc = RocDocAllocator::new(&src_lines, home, &interns);
|
let alloc = RocDocAllocator::new(&src_lines, home, &interns);
|
||||||
|
|
||||||
for problem in can_problems.into_iter() {
|
for problem in can_problems.into_iter() {
|
||||||
let report = can_problem(&alloc, module_path.clone(), problem);
|
let report = can_problem(&alloc, &line_info, module_path.clone(), problem);
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
|
|
||||||
report.render_color_terminal(&mut buf, &alloc, &palette);
|
report.render_color_terminal(&mut buf, &alloc, &palette);
|
||||||
|
@ -107,7 +109,7 @@ pub fn gen_and_eval<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
for problem in type_problems {
|
for problem in type_problems {
|
||||||
if let Some(report) = type_problem(&alloc, module_path.clone(), problem) {
|
if let Some(report) = type_problem(&alloc, &line_info, module_path.clone(), problem) {
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
|
|
||||||
report.render_color_terminal(&mut buf, &alloc, &palette);
|
report.render_color_terminal(&mut buf, &alloc, &palette);
|
||||||
|
@ -117,7 +119,7 @@ pub fn gen_and_eval<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
for problem in mono_problems {
|
for problem in mono_problems {
|
||||||
let report = mono_problem(&alloc, module_path.clone(), problem);
|
let report = mono_problem(&alloc, &line_info, module_path.clone(), problem);
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
|
|
||||||
report.render_color_terminal(&mut buf, &alloc, &palette);
|
report.render_color_terminal(&mut buf, &alloc, &palette);
|
||||||
|
|
|
@ -5,6 +5,7 @@ pub use roc_gen_llvm::llvm::build::FunctionIterator;
|
||||||
use roc_load::file::{LoadedModule, MonomorphizedModule};
|
use roc_load::file::{LoadedModule, MonomorphizedModule};
|
||||||
use roc_module::symbol::{Interns, ModuleId};
|
use roc_module::symbol::{Interns, ModuleId};
|
||||||
use roc_mono::ir::OptLevel;
|
use roc_mono::ir::OptLevel;
|
||||||
|
use roc_region::all::LineInfo;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
@ -81,13 +82,15 @@ fn report_problems_help(
|
||||||
src_lines.extend(src.split('\n'));
|
src_lines.extend(src.split('\n'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let lines = LineInfo::new(src);
|
||||||
|
|
||||||
// Report parsing and canonicalization problems
|
// Report parsing and canonicalization problems
|
||||||
let alloc = RocDocAllocator::new(&src_lines, *home, interns);
|
let alloc = RocDocAllocator::new(&src_lines, *home, interns);
|
||||||
|
|
||||||
let problems = can_problems.remove(home).unwrap_or_default();
|
let problems = can_problems.remove(home).unwrap_or_default();
|
||||||
|
|
||||||
for problem in problems.into_iter() {
|
for problem in problems.into_iter() {
|
||||||
let report = can_problem(&alloc, module_path.clone(), problem);
|
let report = can_problem(&alloc, &lines, module_path.clone(), problem);
|
||||||
let severity = report.severity;
|
let severity = report.severity;
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
|
|
||||||
|
@ -106,7 +109,7 @@ fn report_problems_help(
|
||||||
let problems = type_problems.remove(home).unwrap_or_default();
|
let problems = type_problems.remove(home).unwrap_or_default();
|
||||||
|
|
||||||
for problem in problems {
|
for problem in problems {
|
||||||
if let Some(report) = type_problem(&alloc, module_path.clone(), problem) {
|
if let Some(report) = type_problem(&alloc, &lines, module_path.clone(), problem) {
|
||||||
let severity = report.severity;
|
let severity = report.severity;
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
|
|
||||||
|
@ -126,7 +129,7 @@ fn report_problems_help(
|
||||||
let problems = mono_problems.remove(home).unwrap_or_default();
|
let problems = mono_problems.remove(home).unwrap_or_default();
|
||||||
|
|
||||||
for problem in problems {
|
for problem in problems {
|
||||||
let report = mono_problem(&alloc, module_path.clone(), problem);
|
let report = mono_problem(&alloc, &lines, module_path.clone(), problem);
|
||||||
let severity = report.severity;
|
let severity = report.severity;
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ use roc_parse::header::PackageName;
|
||||||
use roc_parse::header::{ExposedName, ImportsEntry, PackageEntry, PlatformHeader, To, TypedIdent};
|
use roc_parse::header::{ExposedName, ImportsEntry, PackageEntry, PlatformHeader, To, TypedIdent};
|
||||||
use roc_parse::module::module_defs;
|
use roc_parse::module::module_defs;
|
||||||
use roc_parse::parser::{ParseProblem, Parser, SyntaxError};
|
use roc_parse::parser::{ParseProblem, Parser, SyntaxError};
|
||||||
use roc_region::all::{Loc, Region};
|
use roc_region::all::{Loc, Region, LineInfo};
|
||||||
use roc_solve::module::SolvedModule;
|
use roc_solve::module::SolvedModule;
|
||||||
use roc_solve::solve;
|
use roc_solve::solve;
|
||||||
use roc_types::solved_types::Solved;
|
use roc_types::solved_types::Solved;
|
||||||
|
@ -4331,7 +4331,10 @@ fn to_parse_problem_report<'a>(
|
||||||
let alloc = RocDocAllocator::new(&src_lines, module_id, &interns);
|
let alloc = RocDocAllocator::new(&src_lines, module_id, &interns);
|
||||||
|
|
||||||
let starting_line = 0;
|
let starting_line = 0;
|
||||||
let report = parse_problem(&alloc, problem.filename.clone(), starting_line, problem);
|
|
||||||
|
let lines = LineInfo::new(src);
|
||||||
|
|
||||||
|
let report = parse_problem(&alloc, &lines, problem.filename.clone(), starting_line, problem);
|
||||||
|
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
let palette = DEFAULT_PALETTE;
|
let palette = DEFAULT_PALETTE;
|
||||||
|
|
|
@ -205,6 +205,96 @@ pub struct LineColumn {
|
||||||
pub column: u16,
|
pub column: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl LineColumn {
|
||||||
|
pub const fn zero() -> Self {
|
||||||
|
LineColumn {
|
||||||
|
line: 0,
|
||||||
|
column: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash, Default)]
|
||||||
|
pub struct LineColumnRegion {
|
||||||
|
pub start: LineColumn,
|
||||||
|
pub end: LineColumn,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LineColumnRegion {
|
||||||
|
pub const fn zero() -> Self {
|
||||||
|
LineColumnRegion {
|
||||||
|
start: LineColumn::zero(),
|
||||||
|
end: LineColumn::zero(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn contains(&self, other: &Self) -> bool {
|
||||||
|
use std::cmp::Ordering::*;
|
||||||
|
match self.start.line.cmp(&other.start.line) {
|
||||||
|
Greater => false,
|
||||||
|
Equal => match self.end.line.cmp(&other.end.line) {
|
||||||
|
Less => false,
|
||||||
|
Equal => self.start.column <= other.start.column && self.end.column >= other.end.column,
|
||||||
|
Greater => self.start.column >= other.start.column,
|
||||||
|
},
|
||||||
|
Less => match self.end.line.cmp(&other.end.line) {
|
||||||
|
Less => false,
|
||||||
|
Equal => self.end.column >= other.end.column,
|
||||||
|
Greater => true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.end.line == self.start.line && self.start.column == self.end.column
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn span_across(start: &LineColumnRegion, end: &LineColumnRegion) -> Self {
|
||||||
|
LineColumnRegion {
|
||||||
|
start: start.start,
|
||||||
|
end: end.end,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn across_all<'a, I>(regions: I) -> Self
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = &'a LineColumnRegion>,
|
||||||
|
{
|
||||||
|
let mut it = regions.into_iter();
|
||||||
|
|
||||||
|
if let Some(first) = it.next() {
|
||||||
|
let mut result = *first;
|
||||||
|
|
||||||
|
for r in it {
|
||||||
|
result = Self::span_across(&result, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
} else {
|
||||||
|
Self::zero()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lines_between(&self, other: &LineColumnRegion) -> u32 {
|
||||||
|
if self.end.line <= other.start.line {
|
||||||
|
other.start.line - self.end.line
|
||||||
|
} else if self.start.line >= other.end.line {
|
||||||
|
self.start.line - other.end.line
|
||||||
|
} else {
|
||||||
|
// intersection
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn start(&self) -> LineColumn {
|
||||||
|
self.start
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn end(&self) -> LineColumn {
|
||||||
|
self.end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Eq, Copy, PartialEq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Eq, Copy, PartialEq, PartialOrd, Ord, Hash)]
|
||||||
pub struct Loc<T> {
|
pub struct Loc<T> {
|
||||||
pub region: Region,
|
pub region: Region,
|
||||||
|
@ -269,3 +359,29 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct LineInfo {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LineInfo {
|
||||||
|
pub fn new(_text: &str) -> LineInfo {
|
||||||
|
// TODO
|
||||||
|
LineInfo {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn convert_pos(&self, pos: Position) -> LineColumn {
|
||||||
|
// TODO
|
||||||
|
LineColumn {
|
||||||
|
line: pos.line,
|
||||||
|
column: pos.column,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn convert_region(&self, region: Region) -> LineColumnRegion {
|
||||||
|
LineColumnRegion {
|
||||||
|
start: self.convert_pos(region.start()),
|
||||||
|
end: self.convert_pos(region.end()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ use roc_collections::all::{MutMap, MutSet};
|
||||||
use roc_gen_llvm::llvm::externs::add_default_roc_externs;
|
use roc_gen_llvm::llvm::externs::add_default_roc_externs;
|
||||||
use roc_module::symbol::Symbol;
|
use roc_module::symbol::Symbol;
|
||||||
use roc_mono::ir::OptLevel;
|
use roc_mono::ir::OptLevel;
|
||||||
|
use roc_region::all::LineInfo;
|
||||||
use roc_types::subs::VarStore;
|
use roc_types::subs::VarStore;
|
||||||
use target_lexicon::Triple;
|
use target_lexicon::Triple;
|
||||||
|
|
||||||
|
@ -105,6 +106,7 @@ fn create_llvm_module<'a>(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let line_info = LineInfo::new(&src);
|
||||||
let src_lines: Vec<&str> = src.split('\n').collect();
|
let src_lines: Vec<&str> = src.split('\n').collect();
|
||||||
let palette = DEFAULT_PALETTE;
|
let palette = DEFAULT_PALETTE;
|
||||||
|
|
||||||
|
@ -121,7 +123,7 @@ fn create_llvm_module<'a>(
|
||||||
| RuntimeError(_)
|
| RuntimeError(_)
|
||||||
| UnsupportedPattern(_, _)
|
| UnsupportedPattern(_, _)
|
||||||
| ExposedButNotDefined(_) => {
|
| ExposedButNotDefined(_) => {
|
||||||
let report = can_problem(&alloc, module_path.clone(), problem);
|
let report = can_problem(&alloc, &line_info, module_path.clone(), problem);
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
|
|
||||||
report.render_color_terminal(&mut buf, &alloc, &palette);
|
report.render_color_terminal(&mut buf, &alloc, &palette);
|
||||||
|
@ -130,7 +132,7 @@ fn create_llvm_module<'a>(
|
||||||
lines.push(buf);
|
lines.push(buf);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let report = can_problem(&alloc, module_path.clone(), problem);
|
let report = can_problem(&alloc, &line_info, module_path.clone(), problem);
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
|
|
||||||
report.render_color_terminal(&mut buf, &alloc, &palette);
|
report.render_color_terminal(&mut buf, &alloc, &palette);
|
||||||
|
@ -141,7 +143,7 @@ fn create_llvm_module<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
for problem in type_problems {
|
for problem in type_problems {
|
||||||
if let Some(report) = type_problem(&alloc, module_path.clone(), problem) {
|
if let Some(report) = type_problem(&alloc, &line_info, module_path.clone(), problem) {
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
|
|
||||||
report.render_color_terminal(&mut buf, &alloc, &palette);
|
report.render_color_terminal(&mut buf, &alloc, &palette);
|
||||||
|
@ -151,7 +153,7 @@ fn create_llvm_module<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
for problem in mono_problems {
|
for problem in mono_problems {
|
||||||
let report = mono_problem(&alloc, module_path.clone(), problem);
|
let report = mono_problem(&alloc, &line_info, module_path.clone(), problem);
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
|
|
||||||
report.render_color_terminal(&mut buf, &alloc, &palette);
|
report.render_color_terminal(&mut buf, &alloc, &palette);
|
||||||
|
|
|
@ -2,7 +2,7 @@ use roc_collections::all::MutSet;
|
||||||
use roc_module::ident::{Ident, Lowercase, ModuleName};
|
use roc_module::ident::{Ident, Lowercase, ModuleName};
|
||||||
use roc_problem::can::PrecedenceProblem::BothNonAssociative;
|
use roc_problem::can::PrecedenceProblem::BothNonAssociative;
|
||||||
use roc_problem::can::{BadPattern, FloatErrorKind, IntErrorKind, Problem, RuntimeError};
|
use roc_problem::can::{BadPattern, FloatErrorKind, IntErrorKind, Problem, RuntimeError};
|
||||||
use roc_region::all::{Loc, Position, Region};
|
use roc_region::all::{Loc, Position, Region, LineInfo};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::error::r#type::suggest;
|
use crate::error::r#type::suggest;
|
||||||
|
@ -27,6 +27,7 @@ const MODULE_NOT_IMPORTED: &str = "MODULE NOT IMPORTED";
|
||||||
|
|
||||||
pub fn can_problem<'b>(
|
pub fn can_problem<'b>(
|
||||||
alloc: &'b RocDocAllocator<'b>,
|
alloc: &'b RocDocAllocator<'b>,
|
||||||
|
lines: &LineInfo,
|
||||||
filename: PathBuf,
|
filename: PathBuf,
|
||||||
problem: Problem,
|
problem: Problem,
|
||||||
) -> Report<'b> {
|
) -> Report<'b> {
|
||||||
|
@ -43,7 +44,7 @@ pub fn can_problem<'b>(
|
||||||
alloc
|
alloc
|
||||||
.symbol_unqualified(symbol)
|
.symbol_unqualified(symbol)
|
||||||
.append(alloc.reflow(" is not used anywhere in your code.")),
|
.append(alloc.reflow(" is not used anywhere in your code.")),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc
|
alloc
|
||||||
.reflow("If you didn't intend on using ")
|
.reflow("If you didn't intend on using ")
|
||||||
.append(alloc.symbol_unqualified(symbol))
|
.append(alloc.symbol_unqualified(symbol))
|
||||||
|
@ -60,7 +61,7 @@ pub fn can_problem<'b>(
|
||||||
alloc.module(module_id),
|
alloc.module(module_id),
|
||||||
alloc.reflow(" is used in this module."),
|
alloc.reflow(" is used in this module."),
|
||||||
]),
|
]),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow("Since "),
|
alloc.reflow("Since "),
|
||||||
alloc.module(module_id),
|
alloc.module(module_id),
|
||||||
|
@ -97,7 +98,7 @@ pub fn can_problem<'b>(
|
||||||
alloc.symbol_unqualified(argument_symbol),
|
alloc.symbol_unqualified(argument_symbol),
|
||||||
alloc.text("."),
|
alloc.text("."),
|
||||||
]),
|
]),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow("If you don't need "),
|
alloc.reflow("If you don't need "),
|
||||||
alloc.symbol_unqualified(argument_symbol),
|
alloc.symbol_unqualified(argument_symbol),
|
||||||
|
@ -137,7 +138,7 @@ pub fn can_problem<'b>(
|
||||||
)),
|
)),
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
title = SYNTAX_PROBLEM.to_string();
|
title = SYNTAX_PROBLEM.to_string();
|
||||||
|
@ -146,7 +147,7 @@ pub fn can_problem<'b>(
|
||||||
Problem::UnsupportedPattern(BadPattern::UnderscoreInDef, region) => {
|
Problem::UnsupportedPattern(BadPattern::UnderscoreInDef, region) => {
|
||||||
doc = alloc.stack(vec![
|
doc = alloc.stack(vec![
|
||||||
alloc.reflow("Underscore patterns are not allowed in definitions"),
|
alloc.reflow("Underscore patterns are not allowed in definitions"),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
title = SYNTAX_PROBLEM.to_string();
|
title = SYNTAX_PROBLEM.to_string();
|
||||||
|
@ -176,7 +177,7 @@ pub fn can_problem<'b>(
|
||||||
alloc
|
alloc
|
||||||
.reflow("This pattern is not allowed in ")
|
.reflow("This pattern is not allowed in ")
|
||||||
.append(alloc.reflow(this_thing)),
|
.append(alloc.reflow(this_thing)),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc.concat(suggestion),
|
alloc.concat(suggestion),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -187,13 +188,13 @@ pub fn can_problem<'b>(
|
||||||
original_region,
|
original_region,
|
||||||
shadow,
|
shadow,
|
||||||
} => {
|
} => {
|
||||||
doc = report_shadowing(alloc, original_region, shadow);
|
doc = report_shadowing(alloc, lines, original_region, shadow);
|
||||||
|
|
||||||
title = DUPLICATE_NAME.to_string();
|
title = DUPLICATE_NAME.to_string();
|
||||||
severity = Severity::RuntimeError;
|
severity = Severity::RuntimeError;
|
||||||
}
|
}
|
||||||
Problem::CyclicAlias(symbol, region, others) => {
|
Problem::CyclicAlias(symbol, region, others) => {
|
||||||
let answer = crate::error::r#type::cyclic_alias(alloc, symbol, region, others);
|
let answer = crate::error::r#type::cyclic_alias(alloc, lines, symbol, region, others);
|
||||||
|
|
||||||
doc = answer.0;
|
doc = answer.0;
|
||||||
title = answer.1;
|
title = answer.1;
|
||||||
|
@ -212,7 +213,7 @@ pub fn can_problem<'b>(
|
||||||
alloc.symbol_unqualified(alias),
|
alloc.symbol_unqualified(alias),
|
||||||
alloc.reflow(" alias definition:"),
|
alloc.reflow(" alias definition:"),
|
||||||
]),
|
]),
|
||||||
alloc.region(variable_region),
|
alloc.region(lines.convert_region(variable_region)),
|
||||||
alloc.reflow("Roc does not allow unused type alias parameters!"),
|
alloc.reflow("Roc does not allow unused type alias parameters!"),
|
||||||
// TODO add link to this guide section
|
// TODO add link to this guide section
|
||||||
alloc.tip().append(alloc.reflow(
|
alloc.tip().append(alloc.reflow(
|
||||||
|
@ -225,7 +226,7 @@ pub fn can_problem<'b>(
|
||||||
severity = Severity::RuntimeError;
|
severity = Severity::RuntimeError;
|
||||||
}
|
}
|
||||||
Problem::BadRecursion(entries) => {
|
Problem::BadRecursion(entries) => {
|
||||||
doc = to_circular_def_doc(alloc, &entries);
|
doc = to_circular_def_doc(alloc, lines, &entries);
|
||||||
title = CIRCULAR_DEF.to_string();
|
title = CIRCULAR_DEF.to_string();
|
||||||
severity = Severity::RuntimeError;
|
severity = Severity::RuntimeError;
|
||||||
}
|
}
|
||||||
|
@ -242,16 +243,16 @@ pub fn can_problem<'b>(
|
||||||
alloc.reflow(" field twice!"),
|
alloc.reflow(" field twice!"),
|
||||||
]),
|
]),
|
||||||
alloc.region_all_the_things(
|
alloc.region_all_the_things(
|
||||||
record_region,
|
lines.convert_region(record_region),
|
||||||
replaced_region,
|
lines.convert_region(replaced_region),
|
||||||
field_region,
|
lines.convert_region(field_region),
|
||||||
Annotation::Error,
|
Annotation::Error,
|
||||||
),
|
),
|
||||||
alloc.reflow(r"In the rest of the program, I will only use the latter definition:"),
|
alloc.reflow(r"In the rest of the program, I will only use the latter definition:"),
|
||||||
alloc.region_all_the_things(
|
alloc.region_all_the_things(
|
||||||
record_region,
|
lines.convert_region(record_region),
|
||||||
field_region,
|
lines.convert_region(field_region),
|
||||||
field_region,
|
lines.convert_region(field_region),
|
||||||
Annotation::TypoSuggestion,
|
Annotation::TypoSuggestion,
|
||||||
),
|
),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
|
@ -271,6 +272,7 @@ pub fn can_problem<'b>(
|
||||||
} => {
|
} => {
|
||||||
return to_invalid_optional_value_report(
|
return to_invalid_optional_value_report(
|
||||||
alloc,
|
alloc,
|
||||||
|
lines,
|
||||||
filename,
|
filename,
|
||||||
field_name,
|
field_name,
|
||||||
field_region,
|
field_region,
|
||||||
|
@ -290,16 +292,16 @@ pub fn can_problem<'b>(
|
||||||
alloc.reflow(" field twice!"),
|
alloc.reflow(" field twice!"),
|
||||||
]),
|
]),
|
||||||
alloc.region_all_the_things(
|
alloc.region_all_the_things(
|
||||||
record_region,
|
lines.convert_region(record_region),
|
||||||
replaced_region,
|
lines.convert_region(replaced_region),
|
||||||
field_region,
|
lines.convert_region(field_region),
|
||||||
Annotation::Error,
|
Annotation::Error,
|
||||||
),
|
),
|
||||||
alloc.reflow("In the rest of the program, I will only use the latter definition:"),
|
alloc.reflow("In the rest of the program, I will only use the latter definition:"),
|
||||||
alloc.region_all_the_things(
|
alloc.region_all_the_things(
|
||||||
record_region,
|
lines.convert_region(record_region),
|
||||||
field_region,
|
lines.convert_region(field_region),
|
||||||
field_region,
|
lines.convert_region(field_region),
|
||||||
Annotation::TypoSuggestion,
|
Annotation::TypoSuggestion,
|
||||||
),
|
),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
|
@ -325,16 +327,16 @@ pub fn can_problem<'b>(
|
||||||
alloc.reflow(" tag twice!"),
|
alloc.reflow(" tag twice!"),
|
||||||
]),
|
]),
|
||||||
alloc.region_all_the_things(
|
alloc.region_all_the_things(
|
||||||
tag_union_region,
|
lines.convert_region(tag_union_region),
|
||||||
replaced_region,
|
lines.convert_region(replaced_region),
|
||||||
tag_region,
|
lines.convert_region(tag_region),
|
||||||
Annotation::Error,
|
Annotation::Error,
|
||||||
),
|
),
|
||||||
alloc.reflow("In the rest of the program, I will only use the latter definition:"),
|
alloc.reflow("In the rest of the program, I will only use the latter definition:"),
|
||||||
alloc.region_all_the_things(
|
alloc.region_all_the_things(
|
||||||
tag_union_region,
|
lines.convert_region(tag_union_region),
|
||||||
tag_region,
|
lines.convert_region(tag_region),
|
||||||
tag_region,
|
lines.convert_region(tag_region),
|
||||||
Annotation::TypoSuggestion,
|
Annotation::TypoSuggestion,
|
||||||
),
|
),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
|
@ -355,7 +357,8 @@ pub fn can_problem<'b>(
|
||||||
alloc.reflow(
|
alloc.reflow(
|
||||||
"This annotation does not match the definition immediately following it:",
|
"This annotation does not match the definition immediately following it:",
|
||||||
),
|
),
|
||||||
alloc.region(Region::span_across(annotation_pattern, def_pattern)),
|
alloc.region(lines.convert_region(
|
||||||
|
Region::span_across(annotation_pattern, def_pattern))),
|
||||||
alloc.reflow("Is it a typo? If not, put either a newline or comment between them."),
|
alloc.reflow("Is it a typo? If not, put either a newline or comment between them."),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -369,7 +372,7 @@ pub fn can_problem<'b>(
|
||||||
alloc.symbol_unqualified(alias_name),
|
alloc.symbol_unqualified(alias_name),
|
||||||
alloc.reflow(" is not what I expect:"),
|
alloc.reflow(" is not what I expect:"),
|
||||||
]),
|
]),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow("Only type variables like "),
|
alloc.reflow("Only type variables like "),
|
||||||
alloc.type_variable("a".into()),
|
alloc.type_variable("a".into()),
|
||||||
|
@ -385,7 +388,7 @@ pub fn can_problem<'b>(
|
||||||
Problem::InvalidHexadecimal(region) => {
|
Problem::InvalidHexadecimal(region) => {
|
||||||
doc = alloc.stack(vec![
|
doc = alloc.stack(vec![
|
||||||
alloc.reflow("This unicode code point is invalid:"),
|
alloc.reflow("This unicode code point is invalid:"),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow(r"I was expecting a hexadecimal number, like "),
|
alloc.reflow(r"I was expecting a hexadecimal number, like "),
|
||||||
alloc.parser_suggestion("\\u(1100)"),
|
alloc.parser_suggestion("\\u(1100)"),
|
||||||
|
@ -402,7 +405,7 @@ pub fn can_problem<'b>(
|
||||||
Problem::InvalidUnicodeCodePt(region) => {
|
Problem::InvalidUnicodeCodePt(region) => {
|
||||||
doc = alloc.stack(vec![
|
doc = alloc.stack(vec![
|
||||||
alloc.reflow("This unicode code point is invalid:"),
|
alloc.reflow("This unicode code point is invalid:"),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc.reflow("Learn more about working with unicode in roc at TODO"),
|
alloc.reflow("Learn more about working with unicode in roc at TODO"),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -412,7 +415,7 @@ pub fn can_problem<'b>(
|
||||||
Problem::InvalidInterpolation(region) => {
|
Problem::InvalidInterpolation(region) => {
|
||||||
doc = alloc.stack(vec![
|
doc = alloc.stack(vec![
|
||||||
alloc.reflow("This string interpolation is invalid:"),
|
alloc.reflow("This string interpolation is invalid:"),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow(r"I was expecting an identifier, like "),
|
alloc.reflow(r"I was expecting an identifier, like "),
|
||||||
alloc.parser_suggestion("\\u(message)"),
|
alloc.parser_suggestion("\\u(message)"),
|
||||||
|
@ -427,7 +430,7 @@ pub fn can_problem<'b>(
|
||||||
severity = Severity::RuntimeError;
|
severity = Severity::RuntimeError;
|
||||||
}
|
}
|
||||||
Problem::RuntimeError(runtime_error) => {
|
Problem::RuntimeError(runtime_error) => {
|
||||||
let answer = pretty_runtime_error(alloc, runtime_error);
|
let answer = pretty_runtime_error(alloc, lines, runtime_error);
|
||||||
|
|
||||||
doc = answer.0;
|
doc = answer.0;
|
||||||
title = answer.1.to_string();
|
title = answer.1.to_string();
|
||||||
|
@ -445,12 +448,13 @@ pub fn can_problem<'b>(
|
||||||
|
|
||||||
fn to_invalid_optional_value_report<'b>(
|
fn to_invalid_optional_value_report<'b>(
|
||||||
alloc: &'b RocDocAllocator<'b>,
|
alloc: &'b RocDocAllocator<'b>,
|
||||||
|
lines: &LineInfo,
|
||||||
filename: PathBuf,
|
filename: PathBuf,
|
||||||
field_name: Lowercase,
|
field_name: Lowercase,
|
||||||
field_region: Region,
|
field_region: Region,
|
||||||
record_region: Region,
|
record_region: Region,
|
||||||
) -> Report {
|
) -> Report<'b> {
|
||||||
let doc = to_invalid_optional_value_report_help(alloc, field_name, field_region, record_region);
|
let doc = to_invalid_optional_value_report_help(alloc, lines, field_name, field_region, record_region);
|
||||||
|
|
||||||
Report {
|
Report {
|
||||||
title: "BAD OPTIONAL VALUE".to_string(),
|
title: "BAD OPTIONAL VALUE".to_string(),
|
||||||
|
@ -462,6 +466,7 @@ fn to_invalid_optional_value_report<'b>(
|
||||||
|
|
||||||
fn to_invalid_optional_value_report_help<'b>(
|
fn to_invalid_optional_value_report_help<'b>(
|
||||||
alloc: &'b RocDocAllocator<'b>,
|
alloc: &'b RocDocAllocator<'b>,
|
||||||
|
lines: &LineInfo,
|
||||||
field_name: Lowercase,
|
field_name: Lowercase,
|
||||||
field_region: Region,
|
field_region: Region,
|
||||||
record_region: Region,
|
record_region: Region,
|
||||||
|
@ -472,7 +477,7 @@ fn to_invalid_optional_value_report_help<'b>(
|
||||||
alloc.record_field(field_name),
|
alloc.record_field(field_name),
|
||||||
alloc.reflow(" field in an incorrect context!"),
|
alloc.reflow(" field in an incorrect context!"),
|
||||||
]),
|
]),
|
||||||
alloc.region_all_the_things(record_region, field_region, field_region, Annotation::Error),
|
alloc.region_all_the_things(lines.convert_region(record_region), lines.convert_region(field_region), lines.convert_region(field_region), Annotation::Error),
|
||||||
alloc.reflow(r"You can only use optional values in record destructuring, like:"),
|
alloc.reflow(r"You can only use optional values in record destructuring, like:"),
|
||||||
alloc
|
alloc
|
||||||
.reflow(r"{ answer ? 42, otherField } = myRecord")
|
.reflow(r"{ answer ? 42, otherField } = myRecord")
|
||||||
|
@ -482,6 +487,7 @@ fn to_invalid_optional_value_report_help<'b>(
|
||||||
|
|
||||||
fn to_bad_ident_expr_report<'b>(
|
fn to_bad_ident_expr_report<'b>(
|
||||||
alloc: &'b RocDocAllocator<'b>,
|
alloc: &'b RocDocAllocator<'b>,
|
||||||
|
lines: &LineInfo,
|
||||||
bad_ident: roc_parse::ident::BadIdent,
|
bad_ident: roc_parse::ident::BadIdent,
|
||||||
surroundings: Region,
|
surroundings: Region,
|
||||||
) -> RocDocBuilder<'b> {
|
) -> RocDocBuilder<'b> {
|
||||||
|
@ -494,7 +500,7 @@ fn to_bad_ident_expr_report<'b>(
|
||||||
|
|
||||||
alloc.stack(vec![
|
alloc.stack(vec![
|
||||||
alloc.reflow(r"I trying to parse a record field access here:"),
|
alloc.reflow(r"I trying to parse a record field access here:"),
|
||||||
alloc.region_with_subregion(surroundings, region),
|
alloc.region_with_subregion(lines.convert_region(surroundings), lines.convert_region(region)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow("So I expect to see a lowercase letter next, like "),
|
alloc.reflow("So I expect to see a lowercase letter next, like "),
|
||||||
alloc.parser_suggestion(".name"),
|
alloc.parser_suggestion(".name"),
|
||||||
|
@ -507,7 +513,7 @@ fn to_bad_ident_expr_report<'b>(
|
||||||
|
|
||||||
WeirdAccessor(_pos) => alloc.stack(vec![
|
WeirdAccessor(_pos) => alloc.stack(vec![
|
||||||
alloc.reflow("I am very confused by this field access"),
|
alloc.reflow("I am very confused by this field access"),
|
||||||
alloc.region(surroundings),
|
alloc.region(lines.convert_region(surroundings)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow("It looks like a field access on an accessor. I parse"),
|
alloc.reflow("It looks like a field access on an accessor. I parse"),
|
||||||
alloc.parser_suggestion(".client.name"),
|
alloc.parser_suggestion(".client.name"),
|
||||||
|
@ -525,7 +531,7 @@ fn to_bad_ident_expr_report<'b>(
|
||||||
|
|
||||||
alloc.stack(vec![
|
alloc.stack(vec![
|
||||||
alloc.reflow("I am trying to parse a qualified name here:"),
|
alloc.reflow("I am trying to parse a qualified name here:"),
|
||||||
alloc.region_with_subregion(surroundings, region),
|
alloc.region_with_subregion(lines.convert_region(surroundings), lines.convert_region(region)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow("I was expecting to see an identifier next, like "),
|
alloc.reflow("I was expecting to see an identifier next, like "),
|
||||||
alloc.parser_suggestion("height"),
|
alloc.parser_suggestion("height"),
|
||||||
|
@ -540,7 +546,7 @@ fn to_bad_ident_expr_report<'b>(
|
||||||
|
|
||||||
alloc.stack(vec![
|
alloc.stack(vec![
|
||||||
alloc.reflow("I am trying to parse a qualified name here:"),
|
alloc.reflow("I am trying to parse a qualified name here:"),
|
||||||
alloc.region_with_subregion(surroundings, region),
|
alloc.region_with_subregion(lines.convert_region(surroundings), lines.convert_region(region)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow(r"This looks like a qualified tag name to me, "),
|
alloc.reflow(r"This looks like a qualified tag name to me, "),
|
||||||
alloc.reflow(r"but tags cannot be qualified! "),
|
alloc.reflow(r"but tags cannot be qualified! "),
|
||||||
|
@ -555,7 +561,7 @@ fn to_bad_ident_expr_report<'b>(
|
||||||
let region = Region::new(surroundings.start(), pos);
|
let region = Region::new(surroundings.start(), pos);
|
||||||
alloc.stack(vec![
|
alloc.stack(vec![
|
||||||
alloc.reflow("Underscores are not allowed in identifier names:"),
|
alloc.reflow("Underscores are not allowed in identifier names:"),
|
||||||
alloc.region_with_subregion(surroundings, region),
|
alloc.region_with_subregion(lines.convert_region(surroundings), lines.convert_region(region)),
|
||||||
alloc.concat(vec![alloc.reflow(
|
alloc.concat(vec![alloc.reflow(
|
||||||
r"I recommend using camelCase, it is the standard in the Roc ecosystem.",
|
r"I recommend using camelCase, it is the standard in the Roc ecosystem.",
|
||||||
)]),
|
)]),
|
||||||
|
@ -569,7 +575,7 @@ fn to_bad_ident_expr_report<'b>(
|
||||||
let region = Region::new(pos, pos.bump_column(width));
|
let region = Region::new(pos, pos.bump_column(width));
|
||||||
alloc.stack(vec![
|
alloc.stack(vec![
|
||||||
alloc.reflow("I am very confused by this field access:"),
|
alloc.reflow("I am very confused by this field access:"),
|
||||||
alloc.region_with_subregion(surroundings, region),
|
alloc.region_with_subregion(lines.convert_region(surroundings), lines.convert_region(region)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow(r"It looks like a record field access on a private tag.")
|
alloc.reflow(r"It looks like a record field access on a private tag.")
|
||||||
]),
|
]),
|
||||||
|
@ -579,7 +585,7 @@ fn to_bad_ident_expr_report<'b>(
|
||||||
let region = Region::new(pos, pos.bump_column(width));
|
let region = Region::new(pos, pos.bump_column(width));
|
||||||
alloc.stack(vec![
|
alloc.stack(vec![
|
||||||
alloc.reflow("I am very confused by this expression:"),
|
alloc.reflow("I am very confused by this expression:"),
|
||||||
alloc.region_with_subregion(surroundings, region),
|
alloc.region_with_subregion(lines.convert_region(surroundings), lines.convert_region(region)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow(
|
alloc.reflow(
|
||||||
r"Looks like a private tag is treated like a module name. ",
|
r"Looks like a private tag is treated like a module name. ",
|
||||||
|
@ -595,7 +601,7 @@ fn to_bad_ident_expr_report<'b>(
|
||||||
Region::new(surroundings.start().bump_column(1), pos.bump_column(1));
|
Region::new(surroundings.start().bump_column(1), pos.bump_column(1));
|
||||||
alloc.stack(vec![
|
alloc.stack(vec![
|
||||||
alloc.reflow("I am trying to parse a private tag here:"),
|
alloc.reflow("I am trying to parse a private tag here:"),
|
||||||
alloc.region_with_subregion(surroundings, region),
|
alloc.region_with_subregion(lines.convert_region(surroundings), lines.convert_region(region)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow(r"But after the "),
|
alloc.reflow(r"But after the "),
|
||||||
alloc.keyword("@"),
|
alloc.keyword("@"),
|
||||||
|
@ -617,6 +623,7 @@ fn to_bad_ident_expr_report<'b>(
|
||||||
|
|
||||||
fn to_bad_ident_pattern_report<'b>(
|
fn to_bad_ident_pattern_report<'b>(
|
||||||
alloc: &'b RocDocAllocator<'b>,
|
alloc: &'b RocDocAllocator<'b>,
|
||||||
|
lines: &LineInfo,
|
||||||
bad_ident: roc_parse::ident::BadIdent,
|
bad_ident: roc_parse::ident::BadIdent,
|
||||||
surroundings: Region,
|
surroundings: Region,
|
||||||
) -> RocDocBuilder<'b> {
|
) -> RocDocBuilder<'b> {
|
||||||
|
@ -629,7 +636,7 @@ fn to_bad_ident_pattern_report<'b>(
|
||||||
|
|
||||||
alloc.stack(vec![
|
alloc.stack(vec![
|
||||||
alloc.reflow(r"I trying to parse a record field accessor here:"),
|
alloc.reflow(r"I trying to parse a record field accessor here:"),
|
||||||
alloc.region_with_subregion(surroundings, region),
|
alloc.region_with_subregion(lines.convert_region(surroundings), lines.convert_region(region)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow("Something like "),
|
alloc.reflow("Something like "),
|
||||||
alloc.parser_suggestion(".name"),
|
alloc.parser_suggestion(".name"),
|
||||||
|
@ -642,7 +649,7 @@ fn to_bad_ident_pattern_report<'b>(
|
||||||
|
|
||||||
WeirdAccessor(_pos) => alloc.stack(vec![
|
WeirdAccessor(_pos) => alloc.stack(vec![
|
||||||
alloc.reflow("I am very confused by this field access"),
|
alloc.reflow("I am very confused by this field access"),
|
||||||
alloc.region(surroundings),
|
alloc.region(lines.convert_region(surroundings)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow("It looks like a field access on an accessor. I parse"),
|
alloc.reflow("It looks like a field access on an accessor. I parse"),
|
||||||
alloc.parser_suggestion(".client.name"),
|
alloc.parser_suggestion(".client.name"),
|
||||||
|
@ -660,7 +667,7 @@ fn to_bad_ident_pattern_report<'b>(
|
||||||
|
|
||||||
alloc.stack(vec![
|
alloc.stack(vec![
|
||||||
alloc.reflow("I am trying to parse a qualified name here:"),
|
alloc.reflow("I am trying to parse a qualified name here:"),
|
||||||
alloc.region_with_subregion(surroundings, region),
|
alloc.region_with_subregion(lines.convert_region(surroundings), lines.convert_region(region)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow("I was expecting to see an identifier next, like "),
|
alloc.reflow("I was expecting to see an identifier next, like "),
|
||||||
alloc.parser_suggestion("height"),
|
alloc.parser_suggestion("height"),
|
||||||
|
@ -675,7 +682,7 @@ fn to_bad_ident_pattern_report<'b>(
|
||||||
|
|
||||||
alloc.stack(vec![
|
alloc.stack(vec![
|
||||||
alloc.reflow("I am trying to parse a qualified name here:"),
|
alloc.reflow("I am trying to parse a qualified name here:"),
|
||||||
alloc.region_with_subregion(surroundings, region),
|
alloc.region_with_subregion(lines.convert_region(surroundings), lines.convert_region(region)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow(r"This looks like a qualified tag name to me, "),
|
alloc.reflow(r"This looks like a qualified tag name to me, "),
|
||||||
alloc.reflow(r"but tags cannot be qualified! "),
|
alloc.reflow(r"but tags cannot be qualified! "),
|
||||||
|
@ -694,7 +701,7 @@ fn to_bad_ident_pattern_report<'b>(
|
||||||
|
|
||||||
alloc.stack(vec![
|
alloc.stack(vec![
|
||||||
alloc.reflow("I am trying to parse an identifier here:"),
|
alloc.reflow("I am trying to parse an identifier here:"),
|
||||||
alloc.region_with_subregion(surroundings, region),
|
alloc.region_with_subregion(lines.convert_region(surroundings), lines.convert_region(region)),
|
||||||
alloc.concat(vec![alloc.reflow(
|
alloc.concat(vec![alloc.reflow(
|
||||||
r"Underscores are not allowed in identifiers. Use camelCase instead!",
|
r"Underscores are not allowed in identifiers. Use camelCase instead!",
|
||||||
)]),
|
)]),
|
||||||
|
@ -770,6 +777,7 @@ where
|
||||||
|
|
||||||
fn report_shadowing<'b>(
|
fn report_shadowing<'b>(
|
||||||
alloc: &'b RocDocAllocator<'b>,
|
alloc: &'b RocDocAllocator<'b>,
|
||||||
|
lines: &LineInfo,
|
||||||
original_region: Region,
|
original_region: Region,
|
||||||
shadow: Loc<Ident>,
|
shadow: Loc<Ident>,
|
||||||
) -> RocDocBuilder<'b> {
|
) -> RocDocBuilder<'b> {
|
||||||
|
@ -780,15 +788,16 @@ fn report_shadowing<'b>(
|
||||||
.text("The ")
|
.text("The ")
|
||||||
.append(alloc.ident(shadow.value))
|
.append(alloc.ident(shadow.value))
|
||||||
.append(alloc.reflow(" name is first defined here:")),
|
.append(alloc.reflow(" name is first defined here:")),
|
||||||
alloc.region(original_region),
|
alloc.region(lines.convert_region(original_region)),
|
||||||
alloc.reflow("But then it's defined a second time here:"),
|
alloc.reflow("But then it's defined a second time here:"),
|
||||||
alloc.region(shadow.region),
|
alloc.region(lines.convert_region(shadow.region)),
|
||||||
alloc.reflow(line),
|
alloc.reflow(line),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pretty_runtime_error<'b>(
|
fn pretty_runtime_error<'b>(
|
||||||
alloc: &'b RocDocAllocator<'b>,
|
alloc: &'b RocDocAllocator<'b>,
|
||||||
|
lines: &LineInfo,
|
||||||
runtime_error: RuntimeError,
|
runtime_error: RuntimeError,
|
||||||
) -> (RocDocBuilder<'b>, &'static str) {
|
) -> (RocDocBuilder<'b>, &'static str) {
|
||||||
let doc;
|
let doc;
|
||||||
|
@ -810,16 +819,16 @@ fn pretty_runtime_error<'b>(
|
||||||
original_region,
|
original_region,
|
||||||
shadow,
|
shadow,
|
||||||
} => {
|
} => {
|
||||||
doc = report_shadowing(alloc, original_region, shadow);
|
doc = report_shadowing(alloc, lines, original_region, shadow);
|
||||||
title = DUPLICATE_NAME;
|
title = DUPLICATE_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
RuntimeError::LookupNotInScope(loc_name, options) => {
|
RuntimeError::LookupNotInScope(loc_name, options) => {
|
||||||
doc = not_found(alloc, loc_name.region, &loc_name.value, "value", options);
|
doc = not_found(alloc, lines, loc_name.region, &loc_name.value, "value", options);
|
||||||
title = UNRECOGNIZED_NAME;
|
title = UNRECOGNIZED_NAME;
|
||||||
}
|
}
|
||||||
RuntimeError::CircularDef(entries) => {
|
RuntimeError::CircularDef(entries) => {
|
||||||
doc = to_circular_def_doc(alloc, &entries);
|
doc = to_circular_def_doc(alloc, lines, &entries);
|
||||||
title = CIRCULAR_DEF;
|
title = CIRCULAR_DEF;
|
||||||
}
|
}
|
||||||
RuntimeError::MalformedPattern(problem, region) => {
|
RuntimeError::MalformedPattern(problem, region) => {
|
||||||
|
@ -835,7 +844,7 @@ fn pretty_runtime_error<'b>(
|
||||||
MalformedBase(Base::Decimal) => " integer ",
|
MalformedBase(Base::Decimal) => " integer ",
|
||||||
BadIdent(bad_ident) => {
|
BadIdent(bad_ident) => {
|
||||||
title = NAMING_PROBLEM;
|
title = NAMING_PROBLEM;
|
||||||
doc = to_bad_ident_pattern_report(alloc, bad_ident, region);
|
doc = to_bad_ident_pattern_report(alloc, lines, bad_ident, region);
|
||||||
|
|
||||||
return (doc, title);
|
return (doc, title);
|
||||||
}
|
}
|
||||||
|
@ -859,7 +868,7 @@ fn pretty_runtime_error<'b>(
|
||||||
alloc.text(name),
|
alloc.text(name),
|
||||||
alloc.reflow("pattern is malformed:"),
|
alloc.reflow("pattern is malformed:"),
|
||||||
]),
|
]),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
tip,
|
tip,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -900,7 +909,7 @@ fn pretty_runtime_error<'b>(
|
||||||
alloc.string(ident.to_string()),
|
alloc.string(ident.to_string()),
|
||||||
alloc.reflow("`:"),
|
alloc.reflow("`:"),
|
||||||
]),
|
]),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
did_you_mean,
|
did_you_mean,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -912,7 +921,7 @@ fn pretty_runtime_error<'b>(
|
||||||
imported_modules,
|
imported_modules,
|
||||||
region,
|
region,
|
||||||
} => {
|
} => {
|
||||||
doc = module_not_found(alloc, region, &module_name, imported_modules);
|
doc = module_not_found(alloc, lines, region, &module_name, imported_modules);
|
||||||
|
|
||||||
title = MODULE_NOT_IMPORTED;
|
title = MODULE_NOT_IMPORTED;
|
||||||
}
|
}
|
||||||
|
@ -921,14 +930,14 @@ fn pretty_runtime_error<'b>(
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
RuntimeError::MalformedIdentifier(_box_str, bad_ident, surroundings) => {
|
RuntimeError::MalformedIdentifier(_box_str, bad_ident, surroundings) => {
|
||||||
doc = to_bad_ident_expr_report(alloc, bad_ident, surroundings);
|
doc = to_bad_ident_expr_report(alloc, lines, bad_ident, surroundings);
|
||||||
|
|
||||||
title = SYNTAX_PROBLEM;
|
title = SYNTAX_PROBLEM;
|
||||||
}
|
}
|
||||||
RuntimeError::MalformedTypeName(_box_str, surroundings) => {
|
RuntimeError::MalformedTypeName(_box_str, surroundings) => {
|
||||||
doc = alloc.stack(vec![
|
doc = alloc.stack(vec![
|
||||||
alloc.reflow(r"I am confused by this type name:"),
|
alloc.reflow(r"I am confused by this type name:"),
|
||||||
alloc.region(surroundings),
|
alloc.region(lines.convert_region(surroundings)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow("Type names start with an uppercase letter, "),
|
alloc.reflow("Type names start with an uppercase letter, "),
|
||||||
alloc.reflow("and can optionally be qualified by a module name, like "),
|
alloc.reflow("and can optionally be qualified by a module name, like "),
|
||||||
|
@ -962,7 +971,7 @@ fn pretty_runtime_error<'b>(
|
||||||
alloc.text(big_or_small),
|
alloc.text(big_or_small),
|
||||||
alloc.reflow(":"),
|
alloc.reflow(":"),
|
||||||
]),
|
]),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc
|
alloc
|
||||||
.reflow("Roc uses signed 64-bit floating points, allowing values between "),
|
.reflow("Roc uses signed 64-bit floating points, allowing values between "),
|
||||||
|
@ -984,7 +993,7 @@ fn pretty_runtime_error<'b>(
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow("This float literal contains an invalid digit:"),
|
alloc.reflow("This float literal contains an invalid digit:"),
|
||||||
]),
|
]),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow("Floating point literals can only contain the digits 0-9, or use scientific notation 10e4"),
|
alloc.reflow("Floating point literals can only contain the digits 0-9, or use scientific notation 10e4"),
|
||||||
]),
|
]),
|
||||||
|
@ -1042,7 +1051,7 @@ fn pretty_runtime_error<'b>(
|
||||||
alloc.text(problem),
|
alloc.text(problem),
|
||||||
alloc.text(":"),
|
alloc.text(":"),
|
||||||
]),
|
]),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.text(plurals),
|
alloc.text(plurals),
|
||||||
contains,
|
contains,
|
||||||
|
@ -1072,7 +1081,7 @@ fn pretty_runtime_error<'b>(
|
||||||
alloc.text(big_or_small),
|
alloc.text(big_or_small),
|
||||||
alloc.reflow(":"),
|
alloc.reflow(":"),
|
||||||
]),
|
]),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc.reflow("Roc uses signed 64-bit integers, allowing values between −9_223_372_036_854_775_808 and 9_223_372_036_854_775_807."),
|
alloc.reflow("Roc uses signed 64-bit integers, allowing values between −9_223_372_036_854_775_808 and 9_223_372_036_854_775_807."),
|
||||||
tip,
|
tip,
|
||||||
]);
|
]);
|
||||||
|
@ -1086,6 +1095,7 @@ fn pretty_runtime_error<'b>(
|
||||||
} => {
|
} => {
|
||||||
doc = to_invalid_optional_value_report_help(
|
doc = to_invalid_optional_value_report_help(
|
||||||
alloc,
|
alloc,
|
||||||
|
lines,
|
||||||
field_name,
|
field_name,
|
||||||
field_region,
|
field_region,
|
||||||
record_region,
|
record_region,
|
||||||
|
@ -1099,7 +1109,7 @@ fn pretty_runtime_error<'b>(
|
||||||
alloc.reflow("This expression cannot be updated"),
|
alloc.reflow("This expression cannot be updated"),
|
||||||
alloc.reflow(":"),
|
alloc.reflow(":"),
|
||||||
]),
|
]),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc.reflow("Only variables can be updated with record update syntax."),
|
alloc.reflow("Only variables can be updated with record update syntax."),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -1147,6 +1157,7 @@ fn pretty_runtime_error<'b>(
|
||||||
|
|
||||||
fn to_circular_def_doc<'b>(
|
fn to_circular_def_doc<'b>(
|
||||||
alloc: &'b RocDocAllocator<'b>,
|
alloc: &'b RocDocAllocator<'b>,
|
||||||
|
lines: &LineInfo,
|
||||||
entries: &[roc_problem::can::CycleEntry],
|
entries: &[roc_problem::can::CycleEntry],
|
||||||
) -> RocDocBuilder<'b> {
|
) -> RocDocBuilder<'b> {
|
||||||
// TODO "are you trying to mutate a variable?
|
// TODO "are you trying to mutate a variable?
|
||||||
|
@ -1165,7 +1176,7 @@ fn to_circular_def_doc<'b>(
|
||||||
.reflow("The ")
|
.reflow("The ")
|
||||||
.append(alloc.symbol_unqualified(first.symbol))
|
.append(alloc.symbol_unqualified(first.symbol))
|
||||||
.append(alloc.reflow(" definition is causing a very tricky infinite loop:")),
|
.append(alloc.reflow(" definition is causing a very tricky infinite loop:")),
|
||||||
alloc.region(first.symbol_region),
|
alloc.region(lines.convert_region(first.symbol_region)),
|
||||||
alloc
|
alloc
|
||||||
.reflow("The ")
|
.reflow("The ")
|
||||||
.append(alloc.symbol_unqualified(first.symbol))
|
.append(alloc.symbol_unqualified(first.symbol))
|
||||||
|
@ -1189,6 +1200,7 @@ fn to_circular_def_doc<'b>(
|
||||||
|
|
||||||
fn not_found<'b>(
|
fn not_found<'b>(
|
||||||
alloc: &'b RocDocAllocator<'b>,
|
alloc: &'b RocDocAllocator<'b>,
|
||||||
|
lines: &LineInfo,
|
||||||
region: roc_region::all::Region,
|
region: roc_region::all::Region,
|
||||||
name: &Ident,
|
name: &Ident,
|
||||||
thing: &'b str,
|
thing: &'b str,
|
||||||
|
@ -1230,13 +1242,14 @@ fn not_found<'b>(
|
||||||
alloc.reflow("` "),
|
alloc.reflow("` "),
|
||||||
alloc.reflow(thing),
|
alloc.reflow(thing),
|
||||||
]),
|
]),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
to_details(default_no, default_yes),
|
to_details(default_no, default_yes),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn module_not_found<'b>(
|
fn module_not_found<'b>(
|
||||||
alloc: &'b RocDocAllocator<'b>,
|
alloc: &'b RocDocAllocator<'b>,
|
||||||
|
lines: &LineInfo,
|
||||||
region: roc_region::all::Region,
|
region: roc_region::all::Region,
|
||||||
name: &ModuleName,
|
name: &ModuleName,
|
||||||
options: MutSet<Box<str>>,
|
options: MutSet<Box<str>>,
|
||||||
|
@ -1275,7 +1288,7 @@ fn module_not_found<'b>(
|
||||||
alloc.string(name.to_string()),
|
alloc.string(name.to_string()),
|
||||||
alloc.reflow("` module is not imported:"),
|
alloc.reflow("` module is not imported:"),
|
||||||
]),
|
]),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
to_details(default_no, default_yes),
|
to_details(default_no, default_yes),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
use crate::report::{Annotation, Report, RocDocAllocator, RocDocBuilder, Severity};
|
use crate::report::{Annotation, Report, RocDocAllocator, RocDocBuilder, Severity};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use roc_region::all::LineInfo;
|
||||||
use ven_pretty::DocAllocator;
|
use ven_pretty::DocAllocator;
|
||||||
|
|
||||||
pub fn mono_problem<'b>(
|
pub fn mono_problem<'b>(
|
||||||
alloc: &'b RocDocAllocator<'b>,
|
alloc: &'b RocDocAllocator<'b>,
|
||||||
|
lines: &LineInfo,
|
||||||
filename: PathBuf,
|
filename: PathBuf,
|
||||||
problem: roc_mono::ir::MonoProblem,
|
problem: roc_mono::ir::MonoProblem,
|
||||||
) -> Report<'b> {
|
) -> Report<'b> {
|
||||||
|
@ -16,7 +18,7 @@ pub fn mono_problem<'b>(
|
||||||
BadArg => {
|
BadArg => {
|
||||||
let doc = alloc.stack(vec![
|
let doc = alloc.stack(vec![
|
||||||
alloc.reflow("This pattern does not cover all the possibilities:"),
|
alloc.reflow("This pattern does not cover all the possibilities:"),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc.reflow("Other possibilities include:"),
|
alloc.reflow("Other possibilities include:"),
|
||||||
unhandled_patterns_to_doc_block(alloc, missing),
|
unhandled_patterns_to_doc_block(alloc, missing),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
|
@ -39,7 +41,7 @@ pub fn mono_problem<'b>(
|
||||||
BadDestruct => {
|
BadDestruct => {
|
||||||
let doc = alloc.stack(vec![
|
let doc = alloc.stack(vec![
|
||||||
alloc.reflow("This pattern does not cover all the possibilities:"),
|
alloc.reflow("This pattern does not cover all the possibilities:"),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc.reflow("Other possibilities include:"),
|
alloc.reflow("Other possibilities include:"),
|
||||||
unhandled_patterns_to_doc_block(alloc, missing),
|
unhandled_patterns_to_doc_block(alloc, missing),
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
|
@ -67,7 +69,7 @@ pub fn mono_problem<'b>(
|
||||||
alloc.keyword("when"),
|
alloc.keyword("when"),
|
||||||
alloc.reflow(" does not cover all the possibilities:"),
|
alloc.reflow(" does not cover all the possibilities:"),
|
||||||
]),
|
]),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc.reflow("Other possibilities include:"),
|
alloc.reflow("Other possibilities include:"),
|
||||||
unhandled_patterns_to_doc_block(alloc, missing),
|
unhandled_patterns_to_doc_block(alloc, missing),
|
||||||
alloc.reflow(
|
alloc.reflow(
|
||||||
|
@ -96,7 +98,7 @@ pub fn mono_problem<'b>(
|
||||||
alloc.string(index.ordinal()),
|
alloc.string(index.ordinal()),
|
||||||
alloc.reflow(" pattern is redundant:"),
|
alloc.reflow(" pattern is redundant:"),
|
||||||
]),
|
]),
|
||||||
alloc.region_with_subregion(overall_region, branch_region),
|
alloc.region_with_subregion(lines.convert_region(overall_region), lines.convert_region(branch_region)),
|
||||||
alloc.reflow(
|
alloc.reflow(
|
||||||
"Any value of this shape will be handled by \
|
"Any value of this shape will be handled by \
|
||||||
a previous pattern, so this one should be removed.",
|
a previous pattern, so this one should be removed.",
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,7 +3,7 @@ use roc_collections::all::{Index, MutSet, SendMap};
|
||||||
use roc_module::called_via::{BinOp, CalledVia};
|
use roc_module::called_via::{BinOp, CalledVia};
|
||||||
use roc_module::ident::{Ident, IdentStr, Lowercase, TagName};
|
use roc_module::ident::{Ident, IdentStr, Lowercase, TagName};
|
||||||
use roc_module::symbol::Symbol;
|
use roc_module::symbol::Symbol;
|
||||||
use roc_region::all::{Loc, Region};
|
use roc_region::all::{Loc, Region, LineInfo};
|
||||||
use roc_solve::solve;
|
use roc_solve::solve;
|
||||||
use roc_types::pretty_print::{Parens, WILDCARD};
|
use roc_types::pretty_print::{Parens, WILDCARD};
|
||||||
use roc_types::types::{Category, ErrorType, PatternCategory, Reason, RecordField, TypeExt};
|
use roc_types::types::{Category, ErrorType, PatternCategory, Reason, RecordField, TypeExt};
|
||||||
|
@ -18,6 +18,7 @@ const ADD_ANNOTATIONS: &str = r#"Can more type annotations be added? Type annota
|
||||||
|
|
||||||
pub fn type_problem<'b>(
|
pub fn type_problem<'b>(
|
||||||
alloc: &'b RocDocAllocator<'b>,
|
alloc: &'b RocDocAllocator<'b>,
|
||||||
|
lines: &LineInfo,
|
||||||
filename: PathBuf,
|
filename: PathBuf,
|
||||||
problem: solve::TypeError,
|
problem: solve::TypeError,
|
||||||
) -> Option<Report<'b>> {
|
) -> Option<Report<'b>> {
|
||||||
|
@ -34,13 +35,14 @@ pub fn type_problem<'b>(
|
||||||
|
|
||||||
match problem {
|
match problem {
|
||||||
BadExpr(region, category, found, expected) => Some(to_expr_report(
|
BadExpr(region, category, found, expected) => Some(to_expr_report(
|
||||||
alloc, filename, region, category, found, expected,
|
alloc, lines, filename, region, category, found, expected,
|
||||||
)),
|
)),
|
||||||
BadPattern(region, category, found, expected) => Some(to_pattern_report(
|
BadPattern(region, category, found, expected) => Some(to_pattern_report(
|
||||||
alloc, filename, region, category, found, expected,
|
alloc, lines, filename, region, category, found, expected,
|
||||||
)),
|
)),
|
||||||
CircularType(region, symbol, overall_type) => Some(to_circular_report(
|
CircularType(region, symbol, overall_type) => Some(to_circular_report(
|
||||||
alloc,
|
alloc,
|
||||||
|
lines,
|
||||||
filename,
|
filename,
|
||||||
region,
|
region,
|
||||||
symbol,
|
symbol,
|
||||||
|
@ -87,7 +89,7 @@ pub fn type_problem<'b>(
|
||||||
found_arguments,
|
found_arguments,
|
||||||
alloc.reflow(" instead:"),
|
alloc.reflow(" instead:"),
|
||||||
]),
|
]),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc.reflow("Are there missing parentheses?"),
|
alloc.reflow("Are there missing parentheses?"),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -100,7 +102,7 @@ pub fn type_problem<'b>(
|
||||||
report(title, doc, filename)
|
report(title, doc, filename)
|
||||||
}
|
}
|
||||||
CyclicAlias(symbol, region, others) => {
|
CyclicAlias(symbol, region, others) => {
|
||||||
let (doc, title) = cyclic_alias(alloc, symbol, region, others);
|
let (doc, title) = cyclic_alias(alloc, lines, symbol, region, others);
|
||||||
|
|
||||||
report(title, doc, filename)
|
report(title, doc, filename)
|
||||||
}
|
}
|
||||||
|
@ -108,7 +110,7 @@ pub fn type_problem<'b>(
|
||||||
SolvedTypeError => None, // Don't re-report cascading errors - see https://github.com/rtfeldman/roc/pull/1711
|
SolvedTypeError => None, // Don't re-report cascading errors - see https://github.com/rtfeldman/roc/pull/1711
|
||||||
|
|
||||||
Shadowed(original_region, shadow) => {
|
Shadowed(original_region, shadow) => {
|
||||||
let doc = report_shadowing(alloc, original_region, shadow);
|
let doc = report_shadowing(alloc, lines, original_region, shadow);
|
||||||
let title = DUPLICATE_NAME.to_string();
|
let title = DUPLICATE_NAME.to_string();
|
||||||
|
|
||||||
report(title, doc, filename)
|
report(title, doc, filename)
|
||||||
|
@ -122,6 +124,7 @@ pub fn type_problem<'b>(
|
||||||
|
|
||||||
fn report_shadowing<'b>(
|
fn report_shadowing<'b>(
|
||||||
alloc: &'b RocDocAllocator<'b>,
|
alloc: &'b RocDocAllocator<'b>,
|
||||||
|
lines: &LineInfo,
|
||||||
original_region: Region,
|
original_region: Region,
|
||||||
shadow: Loc<Ident>,
|
shadow: Loc<Ident>,
|
||||||
) -> RocDocBuilder<'b> {
|
) -> RocDocBuilder<'b> {
|
||||||
|
@ -132,15 +135,16 @@ fn report_shadowing<'b>(
|
||||||
.text("The ")
|
.text("The ")
|
||||||
.append(alloc.ident(shadow.value))
|
.append(alloc.ident(shadow.value))
|
||||||
.append(alloc.reflow(" name is first defined here:")),
|
.append(alloc.reflow(" name is first defined here:")),
|
||||||
alloc.region(original_region),
|
alloc.region(lines.convert_region(original_region)),
|
||||||
alloc.reflow("But then it's defined a second time here:"),
|
alloc.reflow("But then it's defined a second time here:"),
|
||||||
alloc.region(shadow.region),
|
alloc.region(lines.convert_region(shadow.region)),
|
||||||
alloc.reflow(line),
|
alloc.reflow(line),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cyclic_alias<'b>(
|
pub fn cyclic_alias<'b>(
|
||||||
alloc: &'b RocDocAllocator<'b>,
|
alloc: &'b RocDocAllocator<'b>,
|
||||||
|
lines: &LineInfo,
|
||||||
symbol: Symbol,
|
symbol: Symbol,
|
||||||
region: roc_region::all::Region,
|
region: roc_region::all::Region,
|
||||||
others: Vec<Symbol>,
|
others: Vec<Symbol>,
|
||||||
|
@ -151,7 +155,7 @@ pub fn cyclic_alias<'b>(
|
||||||
.reflow("The ")
|
.reflow("The ")
|
||||||
.append(alloc.symbol_unqualified(symbol))
|
.append(alloc.symbol_unqualified(symbol))
|
||||||
.append(alloc.reflow(" alias is self-recursive in an invalid way:")),
|
.append(alloc.reflow(" alias is self-recursive in an invalid way:")),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc.reflow("Recursion in aliases is only allowed if recursion happens behind a tag."),
|
alloc.reflow("Recursion in aliases is only allowed if recursion happens behind a tag."),
|
||||||
])
|
])
|
||||||
} else {
|
} else {
|
||||||
|
@ -160,7 +164,7 @@ pub fn cyclic_alias<'b>(
|
||||||
.reflow("The ")
|
.reflow("The ")
|
||||||
.append(alloc.symbol_unqualified(symbol))
|
.append(alloc.symbol_unqualified(symbol))
|
||||||
.append(alloc.reflow(" alias is recursive in an invalid way:")),
|
.append(alloc.reflow(" alias is recursive in an invalid way:")),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc
|
alloc
|
||||||
.reflow("The ")
|
.reflow("The ")
|
||||||
.append(alloc.symbol_unqualified(symbol))
|
.append(alloc.symbol_unqualified(symbol))
|
||||||
|
@ -186,6 +190,7 @@ pub fn cyclic_alias<'b>(
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn report_mismatch<'b>(
|
fn report_mismatch<'b>(
|
||||||
alloc: &'b RocDocAllocator<'b>,
|
alloc: &'b RocDocAllocator<'b>,
|
||||||
|
lines: &LineInfo,
|
||||||
filename: PathBuf,
|
filename: PathBuf,
|
||||||
category: &Category,
|
category: &Category,
|
||||||
found: ErrorType,
|
found: ErrorType,
|
||||||
|
@ -198,9 +203,9 @@ fn report_mismatch<'b>(
|
||||||
further_details: Option<RocDocBuilder<'b>>,
|
further_details: Option<RocDocBuilder<'b>>,
|
||||||
) -> Report<'b> {
|
) -> Report<'b> {
|
||||||
let snippet = if let Some(highlight) = opt_highlight {
|
let snippet = if let Some(highlight) = opt_highlight {
|
||||||
alloc.region_with_subregion(highlight, region)
|
alloc.region_with_subregion(lines.convert_region(highlight), lines.convert_region(region))
|
||||||
} else {
|
} else {
|
||||||
alloc.region(region)
|
alloc.region(lines.convert_region(region))
|
||||||
};
|
};
|
||||||
let lines = vec![
|
let lines = vec![
|
||||||
problem,
|
problem,
|
||||||
|
@ -227,6 +232,7 @@ fn report_mismatch<'b>(
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn report_bad_type<'b>(
|
fn report_bad_type<'b>(
|
||||||
alloc: &'b RocDocAllocator<'b>,
|
alloc: &'b RocDocAllocator<'b>,
|
||||||
|
lines: &LineInfo,
|
||||||
filename: PathBuf,
|
filename: PathBuf,
|
||||||
category: &Category,
|
category: &Category,
|
||||||
found: ErrorType,
|
found: ErrorType,
|
||||||
|
@ -238,9 +244,9 @@ fn report_bad_type<'b>(
|
||||||
further_details: RocDocBuilder<'b>,
|
further_details: RocDocBuilder<'b>,
|
||||||
) -> Report<'b> {
|
) -> Report<'b> {
|
||||||
let snippet = if let Some(highlight) = opt_highlight {
|
let snippet = if let Some(highlight) = opt_highlight {
|
||||||
alloc.region_with_subregion(highlight, region)
|
alloc.region_with_subregion(lines.convert_region(highlight), lines.convert_region(region))
|
||||||
} else {
|
} else {
|
||||||
alloc.region(region)
|
alloc.region(lines.convert_region(region))
|
||||||
};
|
};
|
||||||
let lines = vec![
|
let lines = vec![
|
||||||
problem,
|
problem,
|
||||||
|
@ -285,6 +291,7 @@ fn lowercase_first(s: &str) -> String {
|
||||||
|
|
||||||
fn to_expr_report<'b>(
|
fn to_expr_report<'b>(
|
||||||
alloc: &'b RocDocAllocator<'b>,
|
alloc: &'b RocDocAllocator<'b>,
|
||||||
|
lines: &LineInfo,
|
||||||
filename: PathBuf,
|
filename: PathBuf,
|
||||||
expr_region: roc_region::all::Region,
|
expr_region: roc_region::all::Region,
|
||||||
category: Category,
|
category: Category,
|
||||||
|
@ -308,7 +315,7 @@ fn to_expr_report<'b>(
|
||||||
title: "TYPE MISMATCH".to_string(),
|
title: "TYPE MISMATCH".to_string(),
|
||||||
doc: alloc.stack(vec![
|
doc: alloc.stack(vec![
|
||||||
alloc.text("This expression is used in an unexpected way:"),
|
alloc.text("This expression is used in an unexpected way:"),
|
||||||
alloc.region(expr_region),
|
alloc.region(lines.convert_region(expr_region)),
|
||||||
comparison,
|
comparison,
|
||||||
]),
|
]),
|
||||||
severity: Severity::RuntimeError,
|
severity: Severity::RuntimeError,
|
||||||
|
@ -421,7 +428,7 @@ fn to_expr_report<'b>(
|
||||||
// for typed bodies, include the line(s) with the signature
|
// for typed bodies, include the line(s) with the signature
|
||||||
let joined =
|
let joined =
|
||||||
roc_region::all::Region::span_across(&ann_region, &expr_region);
|
roc_region::all::Region::span_across(&ann_region, &expr_region);
|
||||||
alloc.region_with_subregion(joined, expr_region)
|
alloc.region_with_subregion(lines.convert_region(joined), lines.convert_region(expr_region))
|
||||||
},
|
},
|
||||||
comparison,
|
comparison,
|
||||||
]),
|
]),
|
||||||
|
@ -440,6 +447,7 @@ fn to_expr_report<'b>(
|
||||||
|
|
||||||
report_bad_type(
|
report_bad_type(
|
||||||
alloc,
|
alloc,
|
||||||
|
lines,
|
||||||
filename,
|
filename,
|
||||||
&category,
|
&category,
|
||||||
found,
|
found,
|
||||||
|
@ -478,6 +486,7 @@ fn to_expr_report<'b>(
|
||||||
|
|
||||||
report_bad_type(
|
report_bad_type(
|
||||||
alloc,
|
alloc,
|
||||||
|
lines,
|
||||||
filename,
|
filename,
|
||||||
&category,
|
&category,
|
||||||
found,
|
found,
|
||||||
|
@ -515,6 +524,7 @@ fn to_expr_report<'b>(
|
||||||
]);
|
]);
|
||||||
report_bad_type(
|
report_bad_type(
|
||||||
alloc,
|
alloc,
|
||||||
|
lines,
|
||||||
filename,
|
filename,
|
||||||
&category,
|
&category,
|
||||||
found,
|
found,
|
||||||
|
@ -542,6 +552,7 @@ fn to_expr_report<'b>(
|
||||||
} => match total_branches {
|
} => match total_branches {
|
||||||
2 => report_mismatch(
|
2 => report_mismatch(
|
||||||
alloc,
|
alloc,
|
||||||
|
lines,
|
||||||
filename,
|
filename,
|
||||||
&category,
|
&category,
|
||||||
found,
|
found,
|
||||||
|
@ -575,6 +586,7 @@ fn to_expr_report<'b>(
|
||||||
),
|
),
|
||||||
_ => report_mismatch(
|
_ => report_mismatch(
|
||||||
alloc,
|
alloc,
|
||||||
|
lines,
|
||||||
filename,
|
filename,
|
||||||
&category,
|
&category,
|
||||||
found,
|
found,
|
||||||
|
@ -599,6 +611,7 @@ fn to_expr_report<'b>(
|
||||||
},
|
},
|
||||||
Reason::WhenBranch { index } => report_mismatch(
|
Reason::WhenBranch { index } => report_mismatch(
|
||||||
alloc,
|
alloc,
|
||||||
|
lines,
|
||||||
filename,
|
filename,
|
||||||
&category,
|
&category,
|
||||||
found,
|
found,
|
||||||
|
@ -637,6 +650,7 @@ fn to_expr_report<'b>(
|
||||||
|
|
||||||
report_mismatch(
|
report_mismatch(
|
||||||
alloc,
|
alloc,
|
||||||
|
lines,
|
||||||
filename,
|
filename,
|
||||||
&category,
|
&category,
|
||||||
found,
|
found,
|
||||||
|
@ -651,6 +665,7 @@ fn to_expr_report<'b>(
|
||||||
}
|
}
|
||||||
Reason::RecordUpdateValue(field) => report_mismatch(
|
Reason::RecordUpdateValue(field) => report_mismatch(
|
||||||
alloc,
|
alloc,
|
||||||
|
lines,
|
||||||
filename,
|
filename,
|
||||||
&category,
|
&category,
|
||||||
found,
|
found,
|
||||||
|
@ -685,6 +700,7 @@ fn to_expr_report<'b>(
|
||||||
match diff.next().and_then(|k| Some((k, expected_fields.get(k)?))) {
|
match diff.next().and_then(|k| Some((k, expected_fields.get(k)?))) {
|
||||||
None => report_mismatch(
|
None => report_mismatch(
|
||||||
alloc,
|
alloc,
|
||||||
|
lines,
|
||||||
filename,
|
filename,
|
||||||
&category,
|
&category,
|
||||||
found,
|
found,
|
||||||
|
@ -719,7 +735,7 @@ fn to_expr_report<'b>(
|
||||||
|
|
||||||
let doc = alloc.stack(vec![
|
let doc = alloc.stack(vec![
|
||||||
header,
|
header,
|
||||||
alloc.region(*field_region),
|
alloc.region(lines.convert_region(*field_region)),
|
||||||
if suggestions.is_empty() {
|
if suggestions.is_empty() {
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow("In fact, "),
|
alloc.reflow("In fact, "),
|
||||||
|
@ -764,6 +780,7 @@ fn to_expr_report<'b>(
|
||||||
}
|
}
|
||||||
_ => report_bad_type(
|
_ => report_bad_type(
|
||||||
alloc,
|
alloc,
|
||||||
|
lines,
|
||||||
filename,
|
filename,
|
||||||
&category,
|
&category,
|
||||||
found,
|
found,
|
||||||
|
@ -798,7 +815,7 @@ fn to_expr_report<'b>(
|
||||||
}
|
}
|
||||||
)),
|
)),
|
||||||
]),
|
]),
|
||||||
alloc.region(expr_region),
|
alloc.region(lines.convert_region(expr_region)),
|
||||||
alloc.reflow("Are there any missing commas? Or missing parentheses?"),
|
alloc.reflow("Are there any missing commas? Or missing parentheses?"),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -833,7 +850,7 @@ fn to_expr_report<'b>(
|
||||||
arity
|
arity
|
||||||
)),
|
)),
|
||||||
]),
|
]),
|
||||||
alloc.region(expr_region),
|
alloc.region(lines.convert_region(expr_region)),
|
||||||
alloc.reflow("Are there any missing commas? Or missing parentheses?"),
|
alloc.reflow("Are there any missing commas? Or missing parentheses?"),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -857,7 +874,7 @@ fn to_expr_report<'b>(
|
||||||
arity
|
arity
|
||||||
)),
|
)),
|
||||||
]),
|
]),
|
||||||
alloc.region(expr_region),
|
alloc.region(lines.convert_region(expr_region)),
|
||||||
alloc.reflow(
|
alloc.reflow(
|
||||||
"Roc does not allow functions to be partially applied. \
|
"Roc does not allow functions to be partially applied. \
|
||||||
Use a closure to make partial application explicit.",
|
Use a closure to make partial application explicit.",
|
||||||
|
@ -883,6 +900,7 @@ fn to_expr_report<'b>(
|
||||||
|
|
||||||
report_mismatch(
|
report_mismatch(
|
||||||
alloc,
|
alloc,
|
||||||
|
lines,
|
||||||
filename,
|
filename,
|
||||||
&category,
|
&category,
|
||||||
found,
|
found,
|
||||||
|
@ -1230,6 +1248,7 @@ fn add_category<'b>(
|
||||||
|
|
||||||
fn to_pattern_report<'b>(
|
fn to_pattern_report<'b>(
|
||||||
alloc: &'b RocDocAllocator<'b>,
|
alloc: &'b RocDocAllocator<'b>,
|
||||||
|
lines: &LineInfo,
|
||||||
filename: PathBuf,
|
filename: PathBuf,
|
||||||
expr_region: roc_region::all::Region,
|
expr_region: roc_region::all::Region,
|
||||||
category: PatternCategory,
|
category: PatternCategory,
|
||||||
|
@ -1242,7 +1261,7 @@ fn to_pattern_report<'b>(
|
||||||
PExpected::NoExpectation(expected_type) => {
|
PExpected::NoExpectation(expected_type) => {
|
||||||
let doc = alloc.stack(vec![
|
let doc = alloc.stack(vec![
|
||||||
alloc.text("This pattern is being used in an unexpected way:"),
|
alloc.text("This pattern is being used in an unexpected way:"),
|
||||||
alloc.region(expr_region),
|
alloc.region(lines.convert_region(expr_region)),
|
||||||
pattern_type_comparison(
|
pattern_type_comparison(
|
||||||
alloc,
|
alloc,
|
||||||
found,
|
found,
|
||||||
|
@ -1275,7 +1294,7 @@ fn to_pattern_report<'b>(
|
||||||
.append(alloc.text(" argument to "))
|
.append(alloc.text(" argument to "))
|
||||||
.append(name.clone())
|
.append(name.clone())
|
||||||
.append(alloc.text(" is weird:")),
|
.append(alloc.text(" is weird:")),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
pattern_type_comparison(
|
pattern_type_comparison(
|
||||||
alloc,
|
alloc,
|
||||||
found,
|
found,
|
||||||
|
@ -1310,7 +1329,7 @@ fn to_pattern_report<'b>(
|
||||||
.text("The 1st pattern in this ")
|
.text("The 1st pattern in this ")
|
||||||
.append(alloc.keyword("when"))
|
.append(alloc.keyword("when"))
|
||||||
.append(alloc.text(" is causing a mismatch:")),
|
.append(alloc.text(" is causing a mismatch:")),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
pattern_type_comparison(
|
pattern_type_comparison(
|
||||||
alloc,
|
alloc,
|
||||||
found,
|
found,
|
||||||
|
@ -1343,7 +1362,7 @@ fn to_pattern_report<'b>(
|
||||||
.string(format!("The {} pattern in this ", index.ordinal()))
|
.string(format!("The {} pattern in this ", index.ordinal()))
|
||||||
.append(alloc.keyword("when"))
|
.append(alloc.keyword("when"))
|
||||||
.append(alloc.text(" does not match the previous ones:")),
|
.append(alloc.text(" does not match the previous ones:")),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
pattern_type_comparison(
|
pattern_type_comparison(
|
||||||
alloc,
|
alloc,
|
||||||
found,
|
found,
|
||||||
|
@ -1432,6 +1451,7 @@ fn add_pattern_category<'b>(
|
||||||
|
|
||||||
fn to_circular_report<'b>(
|
fn to_circular_report<'b>(
|
||||||
alloc: &'b RocDocAllocator<'b>,
|
alloc: &'b RocDocAllocator<'b>,
|
||||||
|
lines: &LineInfo,
|
||||||
filename: PathBuf,
|
filename: PathBuf,
|
||||||
region: roc_region::all::Region,
|
region: roc_region::all::Region,
|
||||||
symbol: Symbol,
|
symbol: Symbol,
|
||||||
|
@ -1446,7 +1466,7 @@ fn to_circular_report<'b>(
|
||||||
.reflow("I'm inferring a weird self-referential type for ")
|
.reflow("I'm inferring a weird self-referential type for ")
|
||||||
.append(alloc.symbol_unqualified(symbol))
|
.append(alloc.symbol_unqualified(symbol))
|
||||||
.append(alloc.text(":")),
|
.append(alloc.text(":")),
|
||||||
alloc.region(region),
|
alloc.region(lines.convert_region(region)),
|
||||||
alloc.stack(vec![
|
alloc.stack(vec![
|
||||||
alloc.reflow(
|
alloc.reflow(
|
||||||
"Here is my best effort at writing down the type. \
|
"Here is my best effort at writing down the type. \
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use roc_module::ident::Ident;
|
use roc_module::ident::Ident;
|
||||||
use roc_module::ident::{Lowercase, ModuleName, TagName, Uppercase};
|
use roc_module::ident::{Lowercase, ModuleName, TagName, Uppercase};
|
||||||
use roc_module::symbol::{Interns, ModuleId, Symbol};
|
use roc_module::symbol::{Interns, ModuleId, Symbol};
|
||||||
|
use roc_region::all::LineColumnRegion;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use ven_pretty::{BoxAllocator, DocAllocator, DocBuilder, Render, RenderAnnotated};
|
use ven_pretty::{BoxAllocator, DocAllocator, DocBuilder, Render, RenderAnnotated};
|
||||||
|
@ -391,9 +392,9 @@ impl<'a> RocDocAllocator<'a> {
|
||||||
|
|
||||||
pub fn region_all_the_things(
|
pub fn region_all_the_things(
|
||||||
&'a self,
|
&'a self,
|
||||||
region: roc_region::all::Region,
|
region: LineColumnRegion,
|
||||||
sub_region1: roc_region::all::Region,
|
sub_region1: LineColumnRegion,
|
||||||
sub_region2: roc_region::all::Region,
|
sub_region2: LineColumnRegion,
|
||||||
error_annotation: Annotation,
|
error_annotation: Annotation,
|
||||||
) -> DocBuilder<'a, Self, Annotation> {
|
) -> DocBuilder<'a, Self, Annotation> {
|
||||||
debug_assert!(region.contains(&sub_region1));
|
debug_assert!(region.contains(&sub_region1));
|
||||||
|
@ -502,8 +503,8 @@ impl<'a> RocDocAllocator<'a> {
|
||||||
|
|
||||||
pub fn region_with_subregion(
|
pub fn region_with_subregion(
|
||||||
&'a self,
|
&'a self,
|
||||||
region: roc_region::all::Region,
|
region: LineColumnRegion,
|
||||||
sub_region: roc_region::all::Region,
|
sub_region: LineColumnRegion,
|
||||||
) -> DocBuilder<'a, Self, Annotation> {
|
) -> DocBuilder<'a, Self, Annotation> {
|
||||||
// debug_assert!(region.contains(&sub_region));
|
// debug_assert!(region.contains(&sub_region));
|
||||||
|
|
||||||
|
@ -588,13 +589,13 @@ impl<'a> RocDocAllocator<'a> {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn region(&'a self, region: roc_region::all::Region) -> DocBuilder<'a, Self, Annotation> {
|
pub fn region(&'a self, region: LineColumnRegion) -> DocBuilder<'a, Self, Annotation> {
|
||||||
self.region_with_subregion(region, region)
|
self.region_with_subregion(region, region)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn region_without_error(
|
pub fn region_without_error(
|
||||||
&'a self,
|
&'a self,
|
||||||
region: roc_region::all::Region,
|
region: LineColumnRegion,
|
||||||
) -> DocBuilder<'a, Self, Annotation> {
|
) -> DocBuilder<'a, Self, Annotation> {
|
||||||
let mut result = self.nil();
|
let mut result = self.nil();
|
||||||
for i in region.start().line..=region.end().line {
|
for i in region.start().line..=region.end().line {
|
||||||
|
|
|
@ -15,6 +15,7 @@ mod test_reporting {
|
||||||
use roc_module::symbol::{Interns, ModuleId};
|
use roc_module::symbol::{Interns, ModuleId};
|
||||||
use roc_mono::ir::{Procs, Stmt, UpdateModeIds};
|
use roc_mono::ir::{Procs, Stmt, UpdateModeIds};
|
||||||
use roc_mono::layout::LayoutCache;
|
use roc_mono::layout::LayoutCache;
|
||||||
|
use roc_region::all::LineInfo;
|
||||||
use roc_reporting::report::{
|
use roc_reporting::report::{
|
||||||
can_problem, mono_problem, parse_problem, type_problem, Report, Severity, BLUE_CODE,
|
can_problem, mono_problem, parse_problem, type_problem, Report, Severity, BLUE_CODE,
|
||||||
BOLD_CODE, CYAN_CODE, DEFAULT_PALETTE, GREEN_CODE, MAGENTA_CODE, RED_CODE, RESET_CODE,
|
BOLD_CODE, CYAN_CODE, DEFAULT_PALETTE, GREEN_CODE, MAGENTA_CODE, RED_CODE, RESET_CODE,
|
||||||
|
@ -126,6 +127,7 @@ mod test_reporting {
|
||||||
use ven_pretty::DocAllocator;
|
use ven_pretty::DocAllocator;
|
||||||
|
|
||||||
let src_lines: Vec<&str> = src.split('\n').collect();
|
let src_lines: Vec<&str> = src.split('\n').collect();
|
||||||
|
let lines = LineInfo::new(src);
|
||||||
|
|
||||||
let filename = filename_from_string(r"\code\proj\Main.roc");
|
let filename = filename_from_string(r"\code\proj\Main.roc");
|
||||||
|
|
||||||
|
@ -140,7 +142,7 @@ mod test_reporting {
|
||||||
let alloc = RocDocAllocator::new(&src_lines, home, &interns);
|
let alloc = RocDocAllocator::new(&src_lines, home, &interns);
|
||||||
|
|
||||||
let problem = fail.into_parse_problem(filename.clone(), "", src.as_bytes());
|
let problem = fail.into_parse_problem(filename.clone(), "", src.as_bytes());
|
||||||
let doc = parse_problem(&alloc, filename, 0, problem);
|
let doc = parse_problem(&alloc, &lines, filename, 0, problem);
|
||||||
|
|
||||||
callback(doc.pretty(&alloc).append(alloc.line()), buf)
|
callback(doc.pretty(&alloc).append(alloc.line()), buf)
|
||||||
}
|
}
|
||||||
|
@ -150,18 +152,18 @@ mod test_reporting {
|
||||||
let alloc = RocDocAllocator::new(&src_lines, home, &interns);
|
let alloc = RocDocAllocator::new(&src_lines, home, &interns);
|
||||||
|
|
||||||
for problem in can_problems {
|
for problem in can_problems {
|
||||||
let report = can_problem(&alloc, filename.clone(), problem.clone());
|
let report = can_problem(&alloc, &lines, filename.clone(), problem.clone());
|
||||||
reports.push(report);
|
reports.push(report);
|
||||||
}
|
}
|
||||||
|
|
||||||
for problem in type_problems {
|
for problem in type_problems {
|
||||||
if let Some(report) = type_problem(&alloc, filename.clone(), problem.clone()) {
|
if let Some(report) = type_problem(&alloc, &lines, filename.clone(), problem.clone()) {
|
||||||
reports.push(report);
|
reports.push(report);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for problem in mono_problems {
|
for problem in mono_problems {
|
||||||
let report = mono_problem(&alloc, filename.clone(), problem.clone());
|
let report = mono_problem(&alloc, &lines, filename.clone(), problem.clone());
|
||||||
reports.push(report);
|
reports.push(report);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,6 +194,7 @@ mod test_reporting {
|
||||||
|
|
||||||
let filename = filename_from_string(r"\code\proj\Main.roc");
|
let filename = filename_from_string(r"\code\proj\Main.roc");
|
||||||
let src_lines: Vec<&str> = src.split('\n').collect();
|
let src_lines: Vec<&str> = src.split('\n').collect();
|
||||||
|
let lines = LineInfo::new(src);
|
||||||
|
|
||||||
match roc_parse::module::parse_header(arena, state) {
|
match roc_parse::module::parse_header(arena, state) {
|
||||||
Err(fail) => {
|
Err(fail) => {
|
||||||
|
@ -206,7 +209,7 @@ mod test_reporting {
|
||||||
"",
|
"",
|
||||||
src.as_bytes(),
|
src.as_bytes(),
|
||||||
);
|
);
|
||||||
let doc = parse_problem(&alloc, filename, 0, problem);
|
let doc = parse_problem(&alloc, &lines, filename, 0, problem);
|
||||||
|
|
||||||
callback(doc.pretty(&alloc).append(alloc.line()), buf)
|
callback(doc.pretty(&alloc).append(alloc.line()), buf)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue