mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-22 08:17:40 +03:00
Merge pull request #1656 from rtfeldman/unused-warnings
Revise errors and warnings
This commit is contained in:
commit
d365724294
@ -42,10 +42,18 @@ pub fn gen_from_mono_module(
|
||||
use std::time::SystemTime;
|
||||
|
||||
use roc_reporting::report::{
|
||||
can_problem, mono_problem, type_problem, RocDocAllocator, DEFAULT_PALETTE,
|
||||
can_problem, mono_problem, type_problem, Report, RocDocAllocator, Severity::*,
|
||||
DEFAULT_PALETTE,
|
||||
};
|
||||
|
||||
let code_gen_start = SystemTime::now();
|
||||
let palette = DEFAULT_PALETTE;
|
||||
|
||||
// This will often over-allocate total memory, but it means we definitely
|
||||
// never need to re-allocate either the warnings or the errors vec!
|
||||
let total_problems = loaded.total_problems();
|
||||
let mut warnings = Vec::with_capacity(total_problems);
|
||||
let mut errors = Vec::with_capacity(total_problems);
|
||||
|
||||
for (home, (module_path, src)) in loaded.sources {
|
||||
let mut src_lines: Vec<&str> = Vec::new();
|
||||
@ -56,7 +64,6 @@ pub fn gen_from_mono_module(
|
||||
} else {
|
||||
src_lines.extend(src.split('\n'));
|
||||
}
|
||||
let palette = DEFAULT_PALETTE;
|
||||
|
||||
// Report parsing and canonicalization problems
|
||||
let alloc = RocDocAllocator::new(&src_lines, home, &loaded.interns);
|
||||
@ -64,34 +71,79 @@ pub fn gen_from_mono_module(
|
||||
let problems = loaded.can_problems.remove(&home).unwrap_or_default();
|
||||
for problem in problems.into_iter() {
|
||||
let report = can_problem(&alloc, module_path.clone(), problem);
|
||||
let severity = report.severity;
|
||||
let mut buf = String::new();
|
||||
|
||||
report.render_color_terminal(&mut buf, &alloc, &palette);
|
||||
|
||||
println!("\n{}\n", buf);
|
||||
match severity {
|
||||
Warning => {
|
||||
warnings.push(buf);
|
||||
}
|
||||
RuntimeError => {
|
||||
errors.push(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let problems = loaded.type_problems.remove(&home).unwrap_or_default();
|
||||
for problem in problems {
|
||||
let report = type_problem(&alloc, module_path.clone(), problem);
|
||||
let severity = report.severity;
|
||||
let mut buf = String::new();
|
||||
|
||||
report.render_color_terminal(&mut buf, &alloc, &palette);
|
||||
|
||||
println!("\n{}\n", buf);
|
||||
match severity {
|
||||
Warning => {
|
||||
warnings.push(buf);
|
||||
}
|
||||
RuntimeError => {
|
||||
errors.push(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let problems = loaded.mono_problems.remove(&home).unwrap_or_default();
|
||||
for problem in problems {
|
||||
let report = mono_problem(&alloc, module_path.clone(), problem);
|
||||
let severity = report.severity;
|
||||
let mut buf = String::new();
|
||||
|
||||
report.render_color_terminal(&mut buf, &alloc, &palette);
|
||||
|
||||
println!("\n{}\n", buf);
|
||||
match severity {
|
||||
Warning => {
|
||||
warnings.push(buf);
|
||||
}
|
||||
RuntimeError => {
|
||||
errors.push(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only print warnings if there are no errors
|
||||
if errors.is_empty() {
|
||||
for warning in warnings {
|
||||
println!("\n{}\n", warning);
|
||||
}
|
||||
} else {
|
||||
for error in errors {
|
||||
println!("\n{}\n", error);
|
||||
}
|
||||
}
|
||||
|
||||
// If we printed any problems, print a horizontal rule at the end,
|
||||
// and then clear any ANSI escape codes (e.g. colors) we've used.
|
||||
//
|
||||
// The horizontal rule is nice when running the program right after
|
||||
// compiling it, as it lets you clearly see where the compiler
|
||||
// errors/warnings end and the program output begins.
|
||||
if total_problems > 0 {
|
||||
println!("{}\u{001B}[0m\n", Report::horizontal_rule(&palette));
|
||||
}
|
||||
|
||||
// Generate the binary
|
||||
let ptr_bytes = target.pointer_width().unwrap().bytes() as u32;
|
||||
let context = Context::create();
|
||||
|
@ -721,6 +721,12 @@ pub struct MonomorphizedModule<'a> {
|
||||
pub timings: MutMap<ModuleId, ModuleTiming>,
|
||||
}
|
||||
|
||||
impl<'a> MonomorphizedModule<'a> {
|
||||
pub fn total_problems(&self) -> usize {
|
||||
self.can_problems.len() + self.type_problems.len() + self.mono_problems.len()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct VariablySizedLayouts<'a> {
|
||||
rigids: MutMap<Lowercase, Layout<'a>>,
|
||||
@ -4293,7 +4299,7 @@ where
|
||||
}
|
||||
|
||||
fn to_file_problem_report(filename: &Path, error: io::ErrorKind) -> String {
|
||||
use roc_reporting::report::{Report, RocDocAllocator, DEFAULT_PALETTE};
|
||||
use roc_reporting::report::{Report, RocDocAllocator, Severity, DEFAULT_PALETTE};
|
||||
use ven_pretty::DocAllocator;
|
||||
|
||||
let src_lines: Vec<&str> = Vec::new();
|
||||
@ -4324,6 +4330,7 @@ fn to_file_problem_report(filename: &Path, error: io::ErrorKind) -> String {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
doc,
|
||||
title: "FILE NOT FOUND".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
io::ErrorKind::PermissionDenied => {
|
||||
@ -4340,7 +4347,8 @@ fn to_file_problem_report(filename: &Path, error: io::ErrorKind) -> String {
|
||||
Report {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
doc,
|
||||
title: "PERMISSION DENIED".to_string(),
|
||||
title: "FILE PERMISSION DENIED".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -4356,6 +4364,7 @@ fn to_file_problem_report(filename: &Path, error: io::ErrorKind) -> String {
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
doc,
|
||||
title: "FILE PROBLEM".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -4401,7 +4410,7 @@ fn to_parse_problem_report<'a>(
|
||||
}
|
||||
|
||||
fn to_missing_platform_report(module_id: ModuleId, other: PlatformPath) -> String {
|
||||
use roc_reporting::report::{Report, RocDocAllocator, DEFAULT_PALETTE};
|
||||
use roc_reporting::report::{Report, RocDocAllocator, Severity, DEFAULT_PALETTE};
|
||||
use ven_pretty::DocAllocator;
|
||||
use PlatformPath::*;
|
||||
|
||||
@ -4426,6 +4435,7 @@ fn to_missing_platform_report(module_id: ModuleId, other: PlatformPath) -> Strin
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
doc,
|
||||
title: "NO PLATFORM".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
RootIsInterface => {
|
||||
@ -4441,6 +4451,7 @@ fn to_missing_platform_report(module_id: ModuleId, other: PlatformPath) -> Strin
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
doc,
|
||||
title: "NO PLATFORM".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
RootIsPkgConfig => {
|
||||
@ -4456,6 +4467,7 @@ fn to_missing_platform_report(module_id: ModuleId, other: PlatformPath) -> Strin
|
||||
filename: "UNKNOWN.roc".into(),
|
||||
doc,
|
||||
title: "NO PLATFORM".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,23 +3,43 @@ use roc_module::ident::{Ident, Lowercase, ModuleName};
|
||||
use roc_parse::parser::{Col, Row};
|
||||
use roc_problem::can::PrecedenceProblem::BothNonAssociative;
|
||||
use roc_problem::can::{BadPattern, FloatErrorKind, IntErrorKind, Problem, RuntimeError};
|
||||
use roc_region::all::Region;
|
||||
use roc_region::all::{Located, Region};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::report::{Annotation, Report, RocDocAllocator, RocDocBuilder};
|
||||
use crate::report::{Annotation, Report, RocDocAllocator, RocDocBuilder, Severity};
|
||||
use ven_pretty::DocAllocator;
|
||||
|
||||
const SYNTAX_PROBLEM: &str = "SYNTAX PROBLEM";
|
||||
const NAMING_PROBLEM: &str = "NAMING PROBLEM";
|
||||
const UNRECOGNIZED_NAME: &str = "UNRECOGNIZED NAME";
|
||||
const UNUSED_DEF: &str = "UNUSED DEFINITION";
|
||||
const UNUSED_IMPORT: &str = "UNUSED IMPORT";
|
||||
const UNUSED_ALIAS_PARAM: &str = "UNUSED TYPE ALIAS PARAMETER";
|
||||
const UNUSED_ARG: &str = "UNUSED ARGUMENT";
|
||||
const MISSING_DEFINITION: &str = "MISSING_DEFINITION";
|
||||
const DUPLICATE_FIELD_NAME: &str = "DUPLICATE FIELD NAME";
|
||||
const DUPLICATE_TAG_NAME: &str = "DUPLICATE TAG NAME";
|
||||
const INVALID_UNICODE: &str = "INVALID UNICODE";
|
||||
const CIRCULAR_DEF: &str = "CIRCULAR DEFINITION";
|
||||
const DUPLICATE_NAME: &str = "DUPLICATE NAME";
|
||||
const VALUE_NOT_EXPOSED: &str = "NOT EXPOSED";
|
||||
const MODULE_NOT_IMPORTED: &str = "MODULE NOT IMPORTED";
|
||||
|
||||
pub fn can_problem<'b>(
|
||||
alloc: &'b RocDocAllocator<'b>,
|
||||
filename: PathBuf,
|
||||
problem: Problem,
|
||||
) -> Report<'b> {
|
||||
let doc = match problem {
|
||||
let doc;
|
||||
let title;
|
||||
let severity;
|
||||
|
||||
match problem {
|
||||
Problem::UnusedDef(symbol, region) => {
|
||||
let line =
|
||||
r#" then remove it so future readers of your code don't wonder why it is there."#;
|
||||
|
||||
alloc.stack(vec![
|
||||
doc = alloc.stack(vec![
|
||||
alloc
|
||||
.symbol_unqualified(symbol)
|
||||
.append(alloc.reflow(" is not used anywhere in your code.")),
|
||||
@ -28,36 +48,49 @@ pub fn can_problem<'b>(
|
||||
.reflow("If you didn't intend on using ")
|
||||
.append(alloc.symbol_unqualified(symbol))
|
||||
.append(alloc.reflow(line)),
|
||||
])
|
||||
]);
|
||||
|
||||
title = UNUSED_DEF.to_string();
|
||||
severity = Severity::Warning;
|
||||
}
|
||||
Problem::UnusedImport(module_id, region) => {
|
||||
doc = alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("Nothing from "),
|
||||
alloc.module(module_id),
|
||||
alloc.reflow(" is used in this module."),
|
||||
]),
|
||||
alloc.region(region),
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("Since "),
|
||||
alloc.module(module_id),
|
||||
alloc.reflow(" isn't used, you don't need to import it."),
|
||||
]),
|
||||
]);
|
||||
|
||||
title = UNUSED_IMPORT.to_string();
|
||||
severity = Severity::Warning;
|
||||
}
|
||||
Problem::ExposedButNotDefined(symbol) => {
|
||||
doc = alloc.stack(vec![
|
||||
alloc.symbol_unqualified(symbol).append(
|
||||
alloc.reflow(" is listed as exposed, but it isn't defined in this module."),
|
||||
),
|
||||
alloc
|
||||
.reflow("You can fix this by adding a definition for ")
|
||||
.append(alloc.symbol_unqualified(symbol))
|
||||
.append(alloc.reflow(", or by removing it from "))
|
||||
.append(alloc.keyword("exposes"))
|
||||
.append(alloc.reflow(".")),
|
||||
]);
|
||||
|
||||
title = MISSING_DEFINITION.to_string();
|
||||
severity = Severity::RuntimeError;
|
||||
}
|
||||
Problem::UnusedImport(module_id, region) => alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("Nothing from "),
|
||||
alloc.module(module_id),
|
||||
alloc.reflow(" is used in this module."),
|
||||
]),
|
||||
alloc.region(region),
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("Since "),
|
||||
alloc.module(module_id),
|
||||
alloc.reflow(" isn't used, you don't need to import it."),
|
||||
]),
|
||||
]),
|
||||
Problem::ExposedButNotDefined(symbol) => alloc.stack(vec![
|
||||
alloc.symbol_unqualified(symbol).append(
|
||||
alloc.reflow(" is listed as exposed, but it isn't defined in this module."),
|
||||
),
|
||||
alloc
|
||||
.reflow("You can fix this by adding a definition for ")
|
||||
.append(alloc.symbol_unqualified(symbol))
|
||||
.append(alloc.reflow(", or by removing it from "))
|
||||
.append(alloc.keyword("exposes"))
|
||||
.append(alloc.reflow(".")),
|
||||
]),
|
||||
Problem::UnusedArgument(closure_symbol, argument_symbol, region) => {
|
||||
let line = "\". Adding an underscore at the start of a variable name is a way of saying that the variable is not used.";
|
||||
|
||||
alloc.stack(vec![
|
||||
doc = alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.symbol_unqualified(closure_symbol),
|
||||
alloc.reflow(" doesn't use "),
|
||||
@ -76,10 +109,13 @@ pub fn can_problem<'b>(
|
||||
alloc.symbol_unqualified(argument_symbol),
|
||||
alloc.reflow(line),
|
||||
]),
|
||||
])
|
||||
]);
|
||||
|
||||
title = UNUSED_ARG.to_string();
|
||||
severity = Severity::Warning;
|
||||
}
|
||||
Problem::PrecedenceProblem(BothNonAssociative(region, left_bin_op, right_bin_op)) => alloc
|
||||
.stack(vec![
|
||||
Problem::PrecedenceProblem(BothNonAssociative(region, left_bin_op, right_bin_op)) => {
|
||||
doc = alloc.stack(vec![
|
||||
if left_bin_op.value == right_bin_op.value {
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("Using more than one "),
|
||||
@ -102,11 +138,20 @@ pub fn can_problem<'b>(
|
||||
])
|
||||
},
|
||||
alloc.region(region),
|
||||
]),
|
||||
Problem::UnsupportedPattern(BadPattern::UnderscoreInDef, region) => alloc.stack(vec![
|
||||
alloc.reflow("Underscore patterns are not allowed in definitions"),
|
||||
alloc.region(region),
|
||||
]),
|
||||
]);
|
||||
|
||||
title = SYNTAX_PROBLEM.to_string();
|
||||
severity = Severity::RuntimeError;
|
||||
}
|
||||
Problem::UnsupportedPattern(BadPattern::UnderscoreInDef, region) => {
|
||||
doc = alloc.stack(vec![
|
||||
alloc.reflow("Underscore patterns are not allowed in definitions"),
|
||||
alloc.region(region),
|
||||
]);
|
||||
|
||||
title = SYNTAX_PROBLEM.to_string();
|
||||
severity = Severity::RuntimeError;
|
||||
}
|
||||
Problem::UnsupportedPattern(BadPattern::Unsupported(pattern_type), region) => {
|
||||
use roc_parse::pattern::PatternType::*;
|
||||
|
||||
@ -127,84 +172,98 @@ pub fn can_problem<'b>(
|
||||
alloc.reflow(" instead."),
|
||||
];
|
||||
|
||||
alloc.stack(vec![
|
||||
doc = alloc.stack(vec![
|
||||
alloc
|
||||
.reflow("This pattern is not allowed in ")
|
||||
.append(alloc.reflow(this_thing)),
|
||||
alloc.region(region),
|
||||
alloc.concat(suggestion),
|
||||
])
|
||||
]);
|
||||
|
||||
title = SYNTAX_PROBLEM.to_string();
|
||||
severity = Severity::RuntimeError;
|
||||
}
|
||||
Problem::ShadowingInAnnotation {
|
||||
original_region,
|
||||
shadow,
|
||||
} => pretty_runtime_error(
|
||||
alloc,
|
||||
RuntimeError::Shadowing {
|
||||
original_region,
|
||||
shadow,
|
||||
},
|
||||
),
|
||||
Problem::CyclicAlias(symbol, region, others) => {
|
||||
let (doc, title) = crate::error::r#type::cyclic_alias(alloc, symbol, region, others);
|
||||
} => {
|
||||
doc = report_shadowing(alloc, original_region, shadow);
|
||||
|
||||
return Report {
|
||||
title,
|
||||
filename,
|
||||
doc,
|
||||
};
|
||||
title = DUPLICATE_NAME.to_string();
|
||||
severity = Severity::RuntimeError;
|
||||
}
|
||||
Problem::CyclicAlias(symbol, region, others) => {
|
||||
let answer = crate::error::r#type::cyclic_alias(alloc, symbol, region, others);
|
||||
|
||||
doc = answer.0;
|
||||
title = answer.1;
|
||||
severity = Severity::RuntimeError;
|
||||
}
|
||||
Problem::PhantomTypeArgument {
|
||||
alias,
|
||||
variable_region,
|
||||
variable_name,
|
||||
} => alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("The "),
|
||||
alloc.type_variable(variable_name),
|
||||
alloc.reflow(" type variable is not used in the "),
|
||||
alloc.symbol_unqualified(alias),
|
||||
alloc.reflow(" alias definition:"),
|
||||
]),
|
||||
alloc.region(variable_region),
|
||||
alloc.reflow("Roc does not allow unused type parameters!"),
|
||||
// TODO add link to this guide section
|
||||
alloc.tip().append(alloc.reflow(
|
||||
"If you want an unused type parameter (a so-called \"phantom type\"), \
|
||||
read the guide section on phantom data.",
|
||||
)),
|
||||
]),
|
||||
Problem::BadRecursion(entries) => to_circular_def_doc(alloc, &entries),
|
||||
} => {
|
||||
doc = alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("The "),
|
||||
alloc.type_variable(variable_name),
|
||||
alloc.reflow(" type parameter is not used in the "),
|
||||
alloc.symbol_unqualified(alias),
|
||||
alloc.reflow(" alias definition:"),
|
||||
]),
|
||||
alloc.region(variable_region),
|
||||
alloc.reflow("Roc does not allow unused type alias parameters!"),
|
||||
// TODO add link to this guide section
|
||||
alloc.tip().append(alloc.reflow(
|
||||
"If you want an unused type parameter (a so-called \"phantom type\"), \
|
||||
read the guide section on phantom values.",
|
||||
)),
|
||||
]);
|
||||
|
||||
title = UNUSED_ALIAS_PARAM.to_string();
|
||||
severity = Severity::RuntimeError;
|
||||
}
|
||||
Problem::BadRecursion(entries) => {
|
||||
doc = to_circular_def_doc(alloc, &entries);
|
||||
title = CIRCULAR_DEF.to_string();
|
||||
severity = Severity::RuntimeError;
|
||||
}
|
||||
Problem::DuplicateRecordFieldValue {
|
||||
field_name,
|
||||
field_region,
|
||||
record_region,
|
||||
replaced_region,
|
||||
} => alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("This record defines the "),
|
||||
alloc.record_field(field_name.clone()),
|
||||
alloc.reflow(" field twice!"),
|
||||
]),
|
||||
alloc.region_all_the_things(
|
||||
record_region,
|
||||
replaced_region,
|
||||
field_region,
|
||||
Annotation::Error,
|
||||
),
|
||||
alloc.reflow(r"In the rest of the program, I will only use the latter definition:"),
|
||||
alloc.region_all_the_things(
|
||||
record_region,
|
||||
field_region,
|
||||
field_region,
|
||||
Annotation::TypoSuggestion,
|
||||
),
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("For clarity, remove the previous "),
|
||||
alloc.record_field(field_name),
|
||||
alloc.reflow(" definitions from this record."),
|
||||
]),
|
||||
]),
|
||||
} => {
|
||||
doc = alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("This record defines the "),
|
||||
alloc.record_field(field_name.clone()),
|
||||
alloc.reflow(" field twice!"),
|
||||
]),
|
||||
alloc.region_all_the_things(
|
||||
record_region,
|
||||
replaced_region,
|
||||
field_region,
|
||||
Annotation::Error,
|
||||
),
|
||||
alloc.reflow(r"In the rest of the program, I will only use the latter definition:"),
|
||||
alloc.region_all_the_things(
|
||||
record_region,
|
||||
field_region,
|
||||
field_region,
|
||||
Annotation::TypoSuggestion,
|
||||
),
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("For clarity, remove the previous "),
|
||||
alloc.record_field(field_name),
|
||||
alloc.reflow(" definitions from this record."),
|
||||
]),
|
||||
]);
|
||||
|
||||
title = DUPLICATE_FIELD_NAME.to_string();
|
||||
severity = Severity::Warning;
|
||||
}
|
||||
Problem::InvalidOptionalValue {
|
||||
field_name,
|
||||
field_region,
|
||||
@ -223,120 +282,164 @@ pub fn can_problem<'b>(
|
||||
field_region,
|
||||
record_region,
|
||||
replaced_region,
|
||||
} => alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("This record type defines the "),
|
||||
alloc.record_field(field_name.clone()),
|
||||
alloc.reflow(" field twice!"),
|
||||
]),
|
||||
alloc.region_all_the_things(
|
||||
record_region,
|
||||
replaced_region,
|
||||
field_region,
|
||||
Annotation::Error,
|
||||
),
|
||||
alloc.reflow("In the rest of the program, I will only use the latter definition:"),
|
||||
alloc.region_all_the_things(
|
||||
record_region,
|
||||
field_region,
|
||||
field_region,
|
||||
Annotation::TypoSuggestion,
|
||||
),
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("For clarity, remove the previous "),
|
||||
alloc.record_field(field_name),
|
||||
alloc.reflow(" definitions from this record type."),
|
||||
]),
|
||||
]),
|
||||
} => {
|
||||
doc = alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("This record type defines the "),
|
||||
alloc.record_field(field_name.clone()),
|
||||
alloc.reflow(" field twice!"),
|
||||
]),
|
||||
alloc.region_all_the_things(
|
||||
record_region,
|
||||
replaced_region,
|
||||
field_region,
|
||||
Annotation::Error,
|
||||
),
|
||||
alloc.reflow("In the rest of the program, I will only use the latter definition:"),
|
||||
alloc.region_all_the_things(
|
||||
record_region,
|
||||
field_region,
|
||||
field_region,
|
||||
Annotation::TypoSuggestion,
|
||||
),
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("For clarity, remove the previous "),
|
||||
alloc.record_field(field_name),
|
||||
alloc.reflow(" definitions from this record type."),
|
||||
]),
|
||||
]);
|
||||
|
||||
title = DUPLICATE_FIELD_NAME.to_string();
|
||||
severity = Severity::Warning;
|
||||
}
|
||||
Problem::DuplicateTag {
|
||||
tag_name,
|
||||
tag_union_region,
|
||||
tag_region,
|
||||
replaced_region,
|
||||
} => alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("This tag union type defines the "),
|
||||
alloc.tag_name(tag_name.clone()),
|
||||
alloc.reflow(" tag twice!"),
|
||||
]),
|
||||
alloc.region_all_the_things(
|
||||
tag_union_region,
|
||||
replaced_region,
|
||||
tag_region,
|
||||
Annotation::Error,
|
||||
),
|
||||
alloc.reflow("In the rest of the program, I will only use the latter definition:"),
|
||||
alloc.region_all_the_things(
|
||||
tag_union_region,
|
||||
tag_region,
|
||||
tag_region,
|
||||
Annotation::TypoSuggestion,
|
||||
),
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("For clarity, remove the previous "),
|
||||
alloc.tag_name(tag_name),
|
||||
alloc.reflow(" definitions from this tag union type."),
|
||||
]),
|
||||
]),
|
||||
} => {
|
||||
doc = alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("This tag union type defines the "),
|
||||
alloc.tag_name(tag_name.clone()),
|
||||
alloc.reflow(" tag twice!"),
|
||||
]),
|
||||
alloc.region_all_the_things(
|
||||
tag_union_region,
|
||||
replaced_region,
|
||||
tag_region,
|
||||
Annotation::Error,
|
||||
),
|
||||
alloc.reflow("In the rest of the program, I will only use the latter definition:"),
|
||||
alloc.region_all_the_things(
|
||||
tag_union_region,
|
||||
tag_region,
|
||||
tag_region,
|
||||
Annotation::TypoSuggestion,
|
||||
),
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("For clarity, remove the previous "),
|
||||
alloc.tag_name(tag_name),
|
||||
alloc.reflow(" definitions from this tag union type."),
|
||||
]),
|
||||
]);
|
||||
|
||||
title = DUPLICATE_TAG_NAME.to_string();
|
||||
severity = Severity::Warning;
|
||||
}
|
||||
Problem::SignatureDefMismatch {
|
||||
ref annotation_pattern,
|
||||
ref def_pattern,
|
||||
} => alloc.stack(vec![
|
||||
alloc.reflow("This annotation does not match the definition immediately following it:"),
|
||||
alloc.region(Region::span_across(annotation_pattern, def_pattern)),
|
||||
alloc.reflow("Is it a typo? If not, put either a newline or comment between them."),
|
||||
]),
|
||||
Problem::InvalidAliasRigid { alias_name, region } => alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("This pattern in the definition of "),
|
||||
alloc.symbol_unqualified(alias_name),
|
||||
alloc.reflow(" is not what I expect:"),
|
||||
]),
|
||||
alloc.region(region),
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("Only type variables like "),
|
||||
alloc.type_variable("a".into()),
|
||||
alloc.reflow(" or "),
|
||||
alloc.type_variable("value".into()),
|
||||
alloc.reflow(" can occur in this position."),
|
||||
]),
|
||||
]),
|
||||
Problem::InvalidHexadecimal(region) => alloc.stack(vec![
|
||||
alloc.reflow("This unicode code point is invalid:"),
|
||||
alloc.region(region),
|
||||
alloc.concat(vec![
|
||||
alloc.reflow(r"I was expecting a hexadecimal number, like "),
|
||||
alloc.parser_suggestion("\\u(1100)"),
|
||||
alloc.reflow(" or "),
|
||||
alloc.parser_suggestion("\\u(00FF)"),
|
||||
alloc.text("."),
|
||||
]),
|
||||
alloc.reflow(r"Learn more about working with unicode in roc at TODO"),
|
||||
]),
|
||||
Problem::InvalidUnicodeCodePt(region) => alloc.stack(vec![
|
||||
alloc.reflow("This unicode code point is invalid:"),
|
||||
alloc.region(region),
|
||||
alloc.reflow("Learn more about working with unicode in roc at TODO"),
|
||||
]),
|
||||
Problem::InvalidInterpolation(region) => alloc.stack(vec![
|
||||
alloc.reflow("This string interpolation is invalid:"),
|
||||
alloc.region(region),
|
||||
alloc.concat(vec![
|
||||
alloc.reflow(r"I was expecting an identifier, like "),
|
||||
alloc.parser_suggestion("\\u(message)"),
|
||||
alloc.reflow(" or "),
|
||||
alloc.parser_suggestion("\\u(LoremIpsum.text)"),
|
||||
alloc.text("."),
|
||||
]),
|
||||
alloc.reflow(r"Learn more about string interpolation at TODO"),
|
||||
]),
|
||||
Problem::RuntimeError(runtime_error) => pretty_runtime_error(alloc, runtime_error),
|
||||
} => {
|
||||
doc = alloc.stack(vec![
|
||||
alloc.reflow(
|
||||
"This annotation does not match the definition immediately following it:",
|
||||
),
|
||||
alloc.region(Region::span_across(annotation_pattern, def_pattern)),
|
||||
alloc.reflow("Is it a typo? If not, put either a newline or comment between them."),
|
||||
]);
|
||||
|
||||
title = NAMING_PROBLEM.to_string();
|
||||
severity = Severity::RuntimeError;
|
||||
}
|
||||
Problem::InvalidAliasRigid { alias_name, region } => {
|
||||
doc = alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("This pattern in the definition of "),
|
||||
alloc.symbol_unqualified(alias_name),
|
||||
alloc.reflow(" is not what I expect:"),
|
||||
]),
|
||||
alloc.region(region),
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("Only type variables like "),
|
||||
alloc.type_variable("a".into()),
|
||||
alloc.reflow(" or "),
|
||||
alloc.type_variable("value".into()),
|
||||
alloc.reflow(" can occur in this position."),
|
||||
]),
|
||||
]);
|
||||
|
||||
title = SYNTAX_PROBLEM.to_string();
|
||||
severity = Severity::RuntimeError;
|
||||
}
|
||||
Problem::InvalidHexadecimal(region) => {
|
||||
doc = alloc.stack(vec![
|
||||
alloc.reflow("This unicode code point is invalid:"),
|
||||
alloc.region(region),
|
||||
alloc.concat(vec![
|
||||
alloc.reflow(r"I was expecting a hexadecimal number, like "),
|
||||
alloc.parser_suggestion("\\u(1100)"),
|
||||
alloc.reflow(" or "),
|
||||
alloc.parser_suggestion("\\u(00FF)"),
|
||||
alloc.text("."),
|
||||
]),
|
||||
alloc.reflow(r"Learn more about working with unicode in roc at TODO"),
|
||||
]);
|
||||
|
||||
title = INVALID_UNICODE.to_string();
|
||||
severity = Severity::RuntimeError;
|
||||
}
|
||||
Problem::InvalidUnicodeCodePt(region) => {
|
||||
doc = alloc.stack(vec![
|
||||
alloc.reflow("This unicode code point is invalid:"),
|
||||
alloc.region(region),
|
||||
alloc.reflow("Learn more about working with unicode in roc at TODO"),
|
||||
]);
|
||||
|
||||
title = INVALID_UNICODE.to_string();
|
||||
severity = Severity::RuntimeError;
|
||||
}
|
||||
Problem::InvalidInterpolation(region) => {
|
||||
doc = alloc.stack(vec![
|
||||
alloc.reflow("This string interpolation is invalid:"),
|
||||
alloc.region(region),
|
||||
alloc.concat(vec![
|
||||
alloc.reflow(r"I was expecting an identifier, like "),
|
||||
alloc.parser_suggestion("\\u(message)"),
|
||||
alloc.reflow(" or "),
|
||||
alloc.parser_suggestion("\\u(LoremIpsum.text)"),
|
||||
alloc.text("."),
|
||||
]),
|
||||
alloc.reflow(r"Learn more about string interpolation at TODO"),
|
||||
]);
|
||||
|
||||
title = SYNTAX_PROBLEM.to_string();
|
||||
severity = Severity::RuntimeError;
|
||||
}
|
||||
Problem::RuntimeError(runtime_error) => {
|
||||
let answer = pretty_runtime_error(alloc, runtime_error);
|
||||
|
||||
doc = answer.0;
|
||||
title = answer.1.to_string();
|
||||
severity = Severity::RuntimeError;
|
||||
}
|
||||
};
|
||||
|
||||
Report {
|
||||
title: "SYNTAX PROBLEM".to_string(),
|
||||
title,
|
||||
filename,
|
||||
doc,
|
||||
severity,
|
||||
}
|
||||
}
|
||||
|
||||
@ -353,6 +456,7 @@ fn to_invalid_optional_value_report<'b>(
|
||||
title: "BAD OPTIONAL VALUE".to_string(),
|
||||
filename,
|
||||
doc,
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -666,44 +770,60 @@ where
|
||||
chomped
|
||||
}
|
||||
|
||||
fn report_shadowing<'b>(
|
||||
alloc: &'b RocDocAllocator<'b>,
|
||||
original_region: Region,
|
||||
shadow: Located<Ident>,
|
||||
) -> RocDocBuilder<'b> {
|
||||
let line = r#"Since these variables have the same name, it's easy to use the wrong one on accident. Give one of them a new name."#;
|
||||
|
||||
alloc.stack(vec![
|
||||
alloc
|
||||
.text("The ")
|
||||
.append(alloc.ident(shadow.value))
|
||||
.append(alloc.reflow(" name is first defined here:")),
|
||||
alloc.region(original_region),
|
||||
alloc.reflow("But then it's defined a second time here:"),
|
||||
alloc.region(shadow.region),
|
||||
alloc.reflow(line),
|
||||
])
|
||||
}
|
||||
|
||||
fn pretty_runtime_error<'b>(
|
||||
alloc: &'b RocDocAllocator<'b>,
|
||||
runtime_error: RuntimeError,
|
||||
) -> RocDocBuilder<'b> {
|
||||
) -> (RocDocBuilder<'b>, &'static str) {
|
||||
let doc;
|
||||
let title;
|
||||
|
||||
match runtime_error {
|
||||
RuntimeError::VoidValue => {
|
||||
// is used to communicate to the compiler that
|
||||
// a branch is unreachable; this should never reach a user
|
||||
unreachable!("")
|
||||
unreachable!("");
|
||||
}
|
||||
|
||||
RuntimeError::UnresolvedTypeVar | RuntimeError::ErroneousType => {
|
||||
// only generated during layout generation
|
||||
unreachable!("")
|
||||
unreachable!("");
|
||||
}
|
||||
|
||||
RuntimeError::Shadowing {
|
||||
original_region,
|
||||
shadow,
|
||||
} => {
|
||||
let line = r#"Since these variables have the same name, it's easy to use the wrong one on accident. Give one of them a new name."#;
|
||||
|
||||
alloc.stack(vec![
|
||||
alloc
|
||||
.text("The ")
|
||||
.append(alloc.ident(shadow.value))
|
||||
.append(alloc.reflow(" name is first defined here:")),
|
||||
alloc.region(original_region),
|
||||
alloc.reflow("But then it's defined a second time here:"),
|
||||
alloc.region(shadow.region),
|
||||
alloc.reflow(line),
|
||||
])
|
||||
doc = report_shadowing(alloc, original_region, shadow);
|
||||
title = DUPLICATE_NAME;
|
||||
}
|
||||
|
||||
RuntimeError::LookupNotInScope(loc_name, options) => {
|
||||
not_found(alloc, loc_name.region, &loc_name.value, "value", options)
|
||||
doc = not_found(alloc, loc_name.region, &loc_name.value, "value", options);
|
||||
title = UNRECOGNIZED_NAME;
|
||||
}
|
||||
RuntimeError::CircularDef(entries) => {
|
||||
doc = to_circular_def_doc(alloc, &entries);
|
||||
title = CIRCULAR_DEF;
|
||||
}
|
||||
RuntimeError::CircularDef(entries) => to_circular_def_doc(alloc, &entries),
|
||||
RuntimeError::MalformedPattern(problem, region) => {
|
||||
use roc_parse::ast::Base;
|
||||
use roc_problem::can::MalformedPatternProblem::*;
|
||||
@ -716,7 +836,10 @@ fn pretty_runtime_error<'b>(
|
||||
MalformedBase(Base::Octal) => " octal integer ",
|
||||
MalformedBase(Base::Decimal) => " integer ",
|
||||
BadIdent(bad_ident) => {
|
||||
return to_bad_ident_pattern_report(alloc, bad_ident, region)
|
||||
title = NAMING_PROBLEM;
|
||||
doc = to_bad_ident_pattern_report(alloc, bad_ident, region);
|
||||
|
||||
return (doc, title);
|
||||
}
|
||||
Unknown => " ",
|
||||
QualifiedIdentifier => " qualified ",
|
||||
@ -732,7 +855,7 @@ fn pretty_runtime_error<'b>(
|
||||
),
|
||||
};
|
||||
|
||||
alloc.stack(vec![
|
||||
doc = alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("This"),
|
||||
alloc.text(name),
|
||||
@ -740,7 +863,9 @@ fn pretty_runtime_error<'b>(
|
||||
]),
|
||||
alloc.region(region),
|
||||
tip,
|
||||
])
|
||||
]);
|
||||
|
||||
title = SYNTAX_PROBLEM;
|
||||
}
|
||||
RuntimeError::UnsupportedPattern(_) => {
|
||||
todo!("unsupported patterns are currently not parsed!")
|
||||
@ -749,42 +874,58 @@ fn pretty_runtime_error<'b>(
|
||||
module_name,
|
||||
ident,
|
||||
region,
|
||||
} => alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("The "),
|
||||
alloc.module_name(module_name),
|
||||
alloc.reflow(" module does not expose a "),
|
||||
alloc.string(ident.to_string()),
|
||||
alloc.reflow(" value:"),
|
||||
]),
|
||||
alloc.region(region),
|
||||
]),
|
||||
} => {
|
||||
doc = alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("The "),
|
||||
alloc.module_name(module_name),
|
||||
alloc.reflow(" module does not expose a "),
|
||||
alloc.string(ident.to_string()),
|
||||
alloc.reflow(" value:"),
|
||||
]),
|
||||
alloc.region(region),
|
||||
]);
|
||||
|
||||
title = VALUE_NOT_EXPOSED;
|
||||
}
|
||||
|
||||
RuntimeError::ModuleNotImported {
|
||||
module_name,
|
||||
imported_modules,
|
||||
region,
|
||||
} => module_not_found(alloc, region, &module_name, imported_modules),
|
||||
} => {
|
||||
doc = module_not_found(alloc, region, &module_name, imported_modules);
|
||||
|
||||
title = MODULE_NOT_IMPORTED;
|
||||
}
|
||||
RuntimeError::InvalidPrecedence(_, _) => {
|
||||
// do nothing, reported with PrecedenceProblem
|
||||
unreachable!()
|
||||
unreachable!();
|
||||
}
|
||||
RuntimeError::MalformedIdentifier(_box_str, bad_ident, surroundings) => {
|
||||
to_bad_ident_expr_report(alloc, bad_ident, surroundings)
|
||||
doc = to_bad_ident_expr_report(alloc, bad_ident, surroundings);
|
||||
|
||||
title = SYNTAX_PROBLEM;
|
||||
}
|
||||
RuntimeError::MalformedTypeName(_box_str, surroundings) => {
|
||||
doc = alloc.stack(vec![
|
||||
alloc.reflow(r"I am confused by this type name:"),
|
||||
alloc.region(surroundings),
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("Type names start with an uppercase letter, "),
|
||||
alloc.reflow("and can optionally be qualified by a module name, like "),
|
||||
alloc.parser_suggestion("Bool"),
|
||||
alloc.reflow(" or "),
|
||||
alloc.parser_suggestion("Http.Request.Request"),
|
||||
alloc.reflow("."),
|
||||
]),
|
||||
]);
|
||||
|
||||
title = SYNTAX_PROBLEM;
|
||||
}
|
||||
RuntimeError::MalformedClosure(_) => {
|
||||
todo!("");
|
||||
}
|
||||
RuntimeError::MalformedTypeName(_box_str, surroundings) => alloc.stack(vec![
|
||||
alloc.reflow(r"I am confused by this type name:"),
|
||||
alloc.region(surroundings),
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("Type names start with an uppercase letter, "),
|
||||
alloc.reflow("and can optionally be qualified by a module name, like "),
|
||||
alloc.parser_suggestion("Bool"),
|
||||
alloc.reflow(" or "),
|
||||
alloc.parser_suggestion("Http.Request.Request"),
|
||||
alloc.reflow("."),
|
||||
]),
|
||||
]),
|
||||
RuntimeError::MalformedClosure(_) => todo!(""),
|
||||
RuntimeError::InvalidFloat(sign @ FloatErrorKind::PositiveInfinity, region, _raw_str)
|
||||
| RuntimeError::InvalidFloat(sign @ FloatErrorKind::NegativeInfinity, region, _raw_str) => {
|
||||
let tip = alloc
|
||||
@ -797,7 +938,7 @@ fn pretty_runtime_error<'b>(
|
||||
"small"
|
||||
};
|
||||
|
||||
alloc.stack(vec![
|
||||
doc = alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("This float literal is too "),
|
||||
alloc.text(big_or_small),
|
||||
@ -812,14 +953,16 @@ fn pretty_runtime_error<'b>(
|
||||
alloc.text(format!("{:e}", f64::MAX)),
|
||||
]),
|
||||
tip,
|
||||
])
|
||||
]);
|
||||
|
||||
title = SYNTAX_PROBLEM;
|
||||
}
|
||||
RuntimeError::InvalidFloat(FloatErrorKind::Error, region, _raw_str) => {
|
||||
let tip = alloc
|
||||
.tip()
|
||||
.append(alloc.reflow("Learn more about number literals at TODO"));
|
||||
|
||||
alloc.stack(vec![
|
||||
doc = alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("This float literal contains an invalid digit:"),
|
||||
]),
|
||||
@ -828,7 +971,9 @@ fn pretty_runtime_error<'b>(
|
||||
alloc.reflow("Floating point literals can only contain the digits 0-9, or use scientific notation 10e4"),
|
||||
]),
|
||||
tip,
|
||||
])
|
||||
]);
|
||||
|
||||
title = SYNTAX_PROBLEM;
|
||||
}
|
||||
RuntimeError::InvalidInt(error @ IntErrorKind::InvalidDigit, base, region, _raw_str)
|
||||
| RuntimeError::InvalidInt(error @ IntErrorKind::Empty, base, region, _raw_str) => {
|
||||
@ -871,7 +1016,7 @@ fn pretty_runtime_error<'b>(
|
||||
.tip()
|
||||
.append(alloc.reflow("Learn more about number literals at TODO"));
|
||||
|
||||
alloc.stack(vec![
|
||||
doc = alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("This "),
|
||||
alloc.text(name),
|
||||
@ -887,7 +1032,9 @@ fn pretty_runtime_error<'b>(
|
||||
alloc.text("."),
|
||||
]),
|
||||
tip,
|
||||
])
|
||||
]);
|
||||
|
||||
title = SYNTAX_PROBLEM;
|
||||
}
|
||||
RuntimeError::InvalidInt(error_kind @ IntErrorKind::Underflow, _base, region, _raw_str)
|
||||
| RuntimeError::InvalidInt(error_kind @ IntErrorKind::Overflow, _base, region, _raw_str) => {
|
||||
@ -901,7 +1048,7 @@ fn pretty_runtime_error<'b>(
|
||||
.tip()
|
||||
.append(alloc.reflow("Learn more about number literals at TODO"));
|
||||
|
||||
alloc.stack(vec![
|
||||
doc = alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("This integer literal is too "),
|
||||
alloc.text(big_or_small),
|
||||
@ -910,21 +1057,36 @@ fn pretty_runtime_error<'b>(
|
||||
alloc.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."),
|
||||
tip,
|
||||
])
|
||||
]);
|
||||
|
||||
title = SYNTAX_PROBLEM;
|
||||
}
|
||||
RuntimeError::InvalidOptionalValue {
|
||||
field_name,
|
||||
field_region,
|
||||
record_region,
|
||||
} => to_invalid_optional_value_report_help(alloc, field_name, field_region, record_region),
|
||||
RuntimeError::InvalidRecordUpdate { region } => alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("This expression cannot be updated"),
|
||||
alloc.reflow(":"),
|
||||
]),
|
||||
alloc.region(region),
|
||||
alloc.reflow("Only variables can be updated with record update syntax."),
|
||||
]),
|
||||
} => {
|
||||
doc = to_invalid_optional_value_report_help(
|
||||
alloc,
|
||||
field_name,
|
||||
field_region,
|
||||
record_region,
|
||||
);
|
||||
|
||||
title = SYNTAX_PROBLEM;
|
||||
}
|
||||
RuntimeError::InvalidRecordUpdate { region } => {
|
||||
doc = alloc.stack(vec![
|
||||
alloc.concat(vec![
|
||||
alloc.reflow("This expression cannot be updated"),
|
||||
alloc.reflow(":"),
|
||||
]),
|
||||
alloc.region(region),
|
||||
alloc.reflow("Only variables can be updated with record update syntax."),
|
||||
]);
|
||||
|
||||
title = SYNTAX_PROBLEM;
|
||||
}
|
||||
RuntimeError::InvalidHexadecimal(region) => {
|
||||
todo!(
|
||||
"TODO runtime error for an invalid hexadecimal number in a \\u(...) code point at region {:?}",
|
||||
@ -949,12 +1111,20 @@ fn pretty_runtime_error<'b>(
|
||||
RuntimeError::NonExhaustivePattern => {
|
||||
unreachable!("not currently reported (but can blow up at runtime)")
|
||||
}
|
||||
RuntimeError::ExposedButNotDefined(symbol) => alloc.stack(vec![alloc
|
||||
.symbol_unqualified(symbol)
|
||||
.append(alloc.reflow(" was listed as exposed in "))
|
||||
.append(alloc.module(symbol.module_id()))
|
||||
.append(alloc.reflow(", but it was not defined anywhere in that module."))]),
|
||||
RuntimeError::ExposedButNotDefined(symbol) => {
|
||||
doc = alloc.stack(vec![alloc
|
||||
.symbol_unqualified(symbol)
|
||||
.append(alloc.reflow(" was listed as exposed in "))
|
||||
.append(alloc.module(symbol.module_id()))
|
||||
.append(
|
||||
alloc.reflow(", but it was not defined anywhere in that module."),
|
||||
)]);
|
||||
|
||||
title = MISSING_DEFINITION;
|
||||
}
|
||||
}
|
||||
|
||||
(doc, title)
|
||||
}
|
||||
|
||||
fn to_circular_def_doc<'b>(
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::report::{Annotation, Report, RocDocAllocator, RocDocBuilder};
|
||||
use crate::report::{Annotation, Report, RocDocAllocator, RocDocBuilder, Severity};
|
||||
use std::path::PathBuf;
|
||||
use ven_pretty::DocAllocator;
|
||||
|
||||
@ -33,6 +33,7 @@ pub fn mono_problem<'b>(
|
||||
filename,
|
||||
title: "UNSAFE PATTERN".to_string(),
|
||||
doc,
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
BadDestruct => {
|
||||
@ -56,6 +57,7 @@ pub fn mono_problem<'b>(
|
||||
filename,
|
||||
title: "UNSAFE PATTERN".to_string(),
|
||||
doc,
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
BadCase => {
|
||||
@ -79,6 +81,7 @@ pub fn mono_problem<'b>(
|
||||
filename,
|
||||
title: "UNSAFE PATTERN".to_string(),
|
||||
doc,
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -104,6 +107,7 @@ pub fn mono_problem<'b>(
|
||||
filename,
|
||||
title: "REDUNDANT PATTERN".to_string(),
|
||||
doc,
|
||||
severity: Severity::Warning,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use roc_parse::parser::{Col, ParseProblem, Row, SyntaxError};
|
||||
use roc_region::all::Region;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::report::{Report, RocDocAllocator, RocDocBuilder};
|
||||
use crate::report::{Report, RocDocAllocator, RocDocBuilder, Severity};
|
||||
use ven_pretty::DocAllocator;
|
||||
|
||||
pub fn parse_problem<'a>(
|
||||
@ -75,6 +75,7 @@ fn to_syntax_report<'a>(
|
||||
filename: filename.clone(),
|
||||
doc,
|
||||
title: "PARSE PROBLEM".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
};
|
||||
|
||||
let region = Region {
|
||||
@ -95,6 +96,7 @@ fn to_syntax_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "PARSE PROBLEM".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
SyntaxError::ArgumentsBeforeEquals(region) => {
|
||||
@ -107,6 +109,7 @@ fn to_syntax_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "PARSE PROBLEM".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
Unexpected(mut region) => {
|
||||
@ -139,6 +142,7 @@ fn to_syntax_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "NOT END OF FILE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
SyntaxError::Eof(region) => {
|
||||
@ -148,6 +152,7 @@ fn to_syntax_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "PARSE PROBLEM".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
SyntaxError::OutdentedTooFar => {
|
||||
@ -157,6 +162,7 @@ fn to_syntax_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "PARSE PROBLEM".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
Type(typ) => to_type_report(alloc, filename, typ, 0, 0),
|
||||
@ -235,6 +241,7 @@ fn to_expr_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "ARGUMENTS BEFORE EQUALS".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -320,6 +327,7 @@ fn to_expr_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNKNOWN OPERATOR".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -345,6 +353,7 @@ fn to_expr_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD IDENTIFIER".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -426,6 +435,7 @@ fn to_expr_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: title.to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -453,6 +463,7 @@ fn to_expr_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "MISSING FINAL EXPRESSION".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -483,6 +494,7 @@ fn to_expr_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "SYNTAX PROBLEM".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -505,6 +517,7 @@ fn to_expr_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "ARGUMENTS BEFORE EQUALS".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -524,6 +537,7 @@ fn to_expr_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "BAD BACKPASSING ARROW".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -564,6 +578,7 @@ fn to_lambda_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD ARROW".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -585,6 +600,7 @@ fn to_lambda_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "MISSING ARROW".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -609,6 +625,7 @@ fn to_lambda_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD ARROW".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -630,6 +647,7 @@ fn to_lambda_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "MISSING ARROW".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -653,6 +671,7 @@ fn to_lambda_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED ARGUMENT LIST".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -673,6 +692,7 @@ fn to_lambda_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "MISSING ARROW".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -762,6 +782,7 @@ fn to_unfinished_lambda_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED FUNCTION".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -824,6 +845,7 @@ fn to_str_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD ESCAPE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
EString::CodePtOpen(row, col) | EString::CodePtEnd(row, col) => {
|
||||
@ -849,6 +871,7 @@ fn to_str_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD CODE POINT".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
EString::FormatEnd(row, col) => {
|
||||
@ -869,6 +892,7 @@ fn to_str_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "ENDLESS FORMAT".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
EString::EndlessSingle(row, col) => {
|
||||
@ -891,6 +915,7 @@ fn to_str_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "ENDLESS STRING".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
EString::EndlessMulti(row, col) => {
|
||||
@ -913,6 +938,7 @@ fn to_str_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "ENDLESS STRING".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -958,6 +984,7 @@ fn to_expr_in_parens_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED PARENTHESES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
EInParens::Open(row, col) | EInParens::IndentOpen(row, col) => {
|
||||
@ -982,6 +1009,7 @@ fn to_expr_in_parens_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED PARENTHESES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1031,6 +1059,7 @@ fn to_list_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED LIST".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -1063,6 +1092,7 @@ fn to_list_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED LIST".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1090,6 +1120,7 @@ fn to_list_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED LIST".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1210,6 +1241,7 @@ fn to_unfinished_if_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED IF".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1243,6 +1275,7 @@ fn to_when_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "IF GUARD NO CONDITION".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
_ => to_expr_report(
|
||||
@ -1273,6 +1306,7 @@ fn to_when_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "MISSING ARROW".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1440,6 +1474,7 @@ fn to_unfinished_when_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED WHEN".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1477,6 +1512,7 @@ fn to_unexpected_arrow_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNEXPECTED ARROW".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1552,6 +1588,7 @@ fn to_pattern_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED PATTERN".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
EPattern::Record(record, row, col) => {
|
||||
@ -1593,6 +1630,7 @@ fn to_precord_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED RECORD PATTERN".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -1609,6 +1647,7 @@ fn to_precord_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED RECORD PATTERN".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1633,6 +1672,7 @@ fn to_precord_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED RECORD PATTERN".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -1652,6 +1692,7 @@ fn to_precord_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED RECORD PATTERN".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1676,6 +1717,7 @@ fn to_precord_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED RECORD PATTERN".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
Next::Other(Some(',')) => todo!(),
|
||||
@ -1700,6 +1742,7 @@ fn to_precord_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "PROBLEM IN RECORD PATTERN".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1744,6 +1787,7 @@ fn to_precord_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED RECORD PATTERN".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1768,6 +1812,7 @@ fn to_precord_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "NEED MORE INDENTATION".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
None => {
|
||||
@ -1792,6 +1837,7 @@ fn to_precord_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED RECORD PATTERN".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1842,6 +1888,7 @@ fn to_pattern_in_parens_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED PARENTHESES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1865,6 +1912,7 @@ fn to_pattern_in_parens_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED PARENTHESES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1889,6 +1937,7 @@ fn to_pattern_in_parens_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED PARENTHESES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1913,6 +1962,7 @@ fn to_pattern_in_parens_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "NEED MORE INDENTATION".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
None => {
|
||||
@ -1937,6 +1987,7 @@ fn to_pattern_in_parens_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED PARENTHESES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1980,6 +2031,7 @@ fn to_type_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "DOUBLE COMMA".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
_ => todo!(),
|
||||
@ -2005,6 +2057,7 @@ fn to_type_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED TYPE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2022,6 +2075,7 @@ fn to_type_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED TYPE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2039,6 +2093,7 @@ fn to_type_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED TYPE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2056,6 +2111,7 @@ fn to_type_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED INLINE ALIAS".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2072,6 +2128,7 @@ fn to_type_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "BAD TYPE VARIABLE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2108,6 +2165,7 @@ fn to_trecord_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED RECORD TYPE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -2128,6 +2186,7 @@ fn to_trecord_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED RECORD TYPE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2152,6 +2211,7 @@ fn to_trecord_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED RECORD TYPE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -2171,6 +2231,7 @@ fn to_trecord_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED RECORD TYPE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2195,6 +2256,7 @@ fn to_trecord_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED RECORD TYPE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
Next::Other(Some(',')) => todo!(),
|
||||
@ -2219,6 +2281,7 @@ fn to_trecord_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "PROBLEM IN RECORD TYPE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2251,6 +2314,7 @@ fn to_trecord_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED RECORD TYPE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2275,6 +2339,7 @@ fn to_trecord_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "NEED MORE INDENTATION".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
None => {
|
||||
@ -2299,6 +2364,7 @@ fn to_trecord_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED RECORD TYPE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2345,6 +2411,7 @@ fn to_ttag_union_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED TAG UNION TYPE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
Next::Other(Some(c)) if c.is_alphabetic() => {
|
||||
@ -2366,6 +2433,7 @@ fn to_ttag_union_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD TAG NAME".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -2386,6 +2454,7 @@ fn to_ttag_union_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED TAG UNION TYPE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2411,6 +2480,7 @@ fn to_ttag_union_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD TAG NAME".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
Next::Other(Some('@')) => {
|
||||
@ -2427,6 +2497,7 @@ fn to_ttag_union_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD TAG NAME".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -2446,6 +2517,7 @@ fn to_ttag_union_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED TAG UNION TYPE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2472,6 +2544,7 @@ fn to_ttag_union_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED TAG UNION TYPE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2496,6 +2569,7 @@ fn to_ttag_union_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "NEED MORE INDENTATION".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
None => {
|
||||
@ -2520,6 +2594,7 @@ fn to_ttag_union_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED TAG UNION TYPE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2560,6 +2635,7 @@ fn to_tinparens_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED PARENTHESES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
Next::Other(Some(c)) if c.is_alphabetic() => {
|
||||
@ -2581,6 +2657,7 @@ fn to_tinparens_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD TAG NAME".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -2603,6 +2680,7 @@ fn to_tinparens_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED PARENTHESES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2630,6 +2708,7 @@ fn to_tinparens_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD TAG NAME".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -2649,6 +2728,7 @@ fn to_tinparens_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED PARENTHESES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2676,6 +2756,7 @@ fn to_tinparens_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED PARENTHESES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2700,6 +2781,7 @@ fn to_tinparens_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "NEED MORE INDENTATION".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
None => {
|
||||
@ -2724,6 +2806,7 @@ fn to_tinparens_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "UNFINISHED PARENTHESES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2756,6 +2839,7 @@ fn to_tapply_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "DOUBLE DOT".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
TApply::TrailingDot(row, col) => {
|
||||
@ -2777,6 +2861,7 @@ fn to_tapply_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "TRAILING DOT".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
TApply::StartIsNumber(row, col) => {
|
||||
@ -2798,6 +2883,7 @@ fn to_tapply_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD QUALIFIED NAME".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
TApply::StartNotUppercase(row, col) => {
|
||||
@ -2819,6 +2905,7 @@ fn to_tapply_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD QUALIFIED NAME".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2836,6 +2923,7 @@ fn to_tapply_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "END OF FILE".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2891,6 +2979,7 @@ fn to_header_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "INCOMPLETE HEADER".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2916,6 +3005,7 @@ fn to_header_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "MISSING HEADER".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2939,6 +3029,7 @@ fn to_header_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD MODULE NAME".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2962,6 +3053,7 @@ fn to_header_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD APP NAME".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2983,6 +3075,7 @@ fn to_header_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD MODULE NAME".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -3020,6 +3113,7 @@ fn to_provides_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD PROVIDES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -3044,6 +3138,7 @@ fn to_provides_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD PROVIDES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -3082,6 +3177,7 @@ fn to_exposes_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD EXPOSES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -3106,6 +3202,7 @@ fn to_exposes_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD EXPOSES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -3144,6 +3241,7 @@ fn to_imports_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD EXPOSES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -3168,6 +3266,7 @@ fn to_imports_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD IMPORTS".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -3193,6 +3292,7 @@ fn to_imports_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "WEIRD MODULE NAME".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -3231,6 +3331,7 @@ fn to_requires_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "MISSING REQUIRES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -3257,6 +3358,7 @@ fn to_requires_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "MISSING REQUIRES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -3285,6 +3387,7 @@ fn to_requires_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "BAD REQUIRES RIGIDS".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -3321,6 +3424,7 @@ fn to_packages_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "MISSING PACKAGES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -3359,6 +3463,7 @@ fn to_effects_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "MISSING PACKAGES".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -3391,6 +3496,7 @@ fn to_space_report<'a>(
|
||||
filename,
|
||||
doc,
|
||||
title: "TAB CHARACTER".to_string(),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ use roc_types::pretty_print::Parens;
|
||||
use roc_types::types::{Category, ErrorType, PatternCategory, Reason, RecordField, TypeExt};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::report::{Annotation, Report, RocDocAllocator, RocDocBuilder};
|
||||
use crate::report::{Annotation, Report, RocDocAllocator, RocDocBuilder, Severity};
|
||||
use ven_pretty::DocAllocator;
|
||||
|
||||
const ADD_ANNOTATIONS: &str = r#"Can more type annotations be added? Type annotations always help me give more specific messages, and I think they could help a lot in this case"#;
|
||||
@ -19,6 +19,15 @@ pub fn type_problem<'b>(
|
||||
) -> Report<'b> {
|
||||
use solve::TypeError::*;
|
||||
|
||||
fn report(title: String, doc: RocDocBuilder<'_>, filename: PathBuf) -> Report<'_> {
|
||||
Report {
|
||||
title,
|
||||
filename,
|
||||
doc,
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
match problem {
|
||||
BadExpr(region, category, found, expected) => {
|
||||
to_expr_report(alloc, filename, region, category, found, expected)
|
||||
@ -39,11 +48,7 @@ pub fn type_problem<'b>(
|
||||
.append(alloc.symbol_unqualified(symbol))])
|
||||
.append(alloc.reflow("."));
|
||||
|
||||
Report {
|
||||
title,
|
||||
filename,
|
||||
doc,
|
||||
}
|
||||
report(title, doc, filename)
|
||||
}
|
||||
BadType(type_problem) => {
|
||||
use roc_types::types::Problem::*;
|
||||
@ -84,20 +89,12 @@ pub fn type_problem<'b>(
|
||||
"TOO FEW TYPE ARGUMENTS".to_string()
|
||||
};
|
||||
|
||||
Report {
|
||||
title,
|
||||
filename,
|
||||
doc,
|
||||
}
|
||||
report(title, doc, filename)
|
||||
}
|
||||
CyclicAlias(symbol, region, others) => {
|
||||
let (doc, title) = cyclic_alias(alloc, symbol, region, others);
|
||||
|
||||
Report {
|
||||
title,
|
||||
filename,
|
||||
doc,
|
||||
}
|
||||
report(title, doc, filename)
|
||||
}
|
||||
|
||||
other => panic!("unhandled bad type: {:?}", other),
|
||||
@ -186,6 +183,7 @@ fn report_mismatch<'b>(
|
||||
title: "TYPE MISMATCH".to_string(),
|
||||
filename,
|
||||
doc: alloc.stack(lines),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,6 +221,7 @@ fn report_bad_type<'b>(
|
||||
title: "TYPE MISMATCH".to_string(),
|
||||
filename,
|
||||
doc: alloc.stack(lines),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -265,6 +264,7 @@ fn to_expr_report<'b>(
|
||||
alloc.region(expr_region),
|
||||
comparison,
|
||||
]),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
Expected::FromAnnotation(name, _arity, annotation_source, expected_type) => {
|
||||
@ -351,6 +351,7 @@ fn to_expr_report<'b>(
|
||||
},
|
||||
comparison,
|
||||
]),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
Expected::ForReason(reason, expected_type, region) => match reason {
|
||||
@ -682,6 +683,7 @@ fn to_expr_report<'b>(
|
||||
filename,
|
||||
title: "TYPE MISMATCH".to_string(),
|
||||
doc,
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -730,6 +732,7 @@ fn to_expr_report<'b>(
|
||||
filename,
|
||||
title: "TOO MANY ARGS".to_string(),
|
||||
doc: alloc.stack(lines),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
n => {
|
||||
@ -764,6 +767,7 @@ fn to_expr_report<'b>(
|
||||
filename,
|
||||
title: "TOO MANY ARGS".to_string(),
|
||||
doc: alloc.stack(lines),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
} else {
|
||||
let lines = vec![
|
||||
@ -790,6 +794,7 @@ fn to_expr_report<'b>(
|
||||
filename,
|
||||
title: "TOO FEW ARGS".to_string(),
|
||||
doc: alloc.stack(lines),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1060,6 +1065,7 @@ fn to_pattern_report<'b>(
|
||||
filename,
|
||||
title: "TYPE MISMATCH".to_string(),
|
||||
doc,
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1102,6 +1108,7 @@ fn to_pattern_report<'b>(
|
||||
filename,
|
||||
title: "TYPE MISMATCH".to_string(),
|
||||
doc,
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
PReason::WhenMatch { index } => {
|
||||
@ -1136,6 +1143,7 @@ fn to_pattern_report<'b>(
|
||||
filename,
|
||||
title: "TYPE MISMATCH".to_string(),
|
||||
doc,
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
} else {
|
||||
let doc = alloc.stack(vec![
|
||||
@ -1165,6 +1173,7 @@ fn to_pattern_report<'b>(
|
||||
filename,
|
||||
title: "TYPE MISMATCH".to_string(),
|
||||
doc,
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1252,6 +1261,7 @@ fn to_circular_report<'b>(
|
||||
]),
|
||||
])
|
||||
},
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,11 +57,24 @@ pub fn cycle<'b>(
|
||||
.annotate(Annotation::TypeBlock)
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Severity {
|
||||
/// This will cause a runtime error if some code get srun
|
||||
/// (e.g. type mismatch, naming error)
|
||||
RuntimeError,
|
||||
|
||||
/// This will never cause the code to misbehave,
|
||||
/// but should be cleaned up
|
||||
/// (e.g. unused def, unused import)
|
||||
Warning,
|
||||
}
|
||||
|
||||
/// A textual report.
|
||||
pub struct Report<'b> {
|
||||
pub title: String,
|
||||
pub filename: PathBuf,
|
||||
pub doc: RocDocBuilder<'b>,
|
||||
pub severity: Severity,
|
||||
}
|
||||
|
||||
impl<'b> Report<'b> {
|
||||
@ -106,6 +119,10 @@ impl<'b> Report<'b> {
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
pub fn horizontal_rule(palette: &'b Palette) -> String {
|
||||
format!("{}{}", palette.header, "─".repeat(80))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Palette<'a> {
|
||||
|
@ -16,9 +16,9 @@ mod test_reporting {
|
||||
use roc_mono::ir::{Procs, Stmt};
|
||||
use roc_mono::layout::LayoutCache;
|
||||
use roc_reporting::report::{
|
||||
can_problem, mono_problem, parse_problem, type_problem, Report, BLUE_CODE, BOLD_CODE,
|
||||
CYAN_CODE, DEFAULT_PALETTE, GREEN_CODE, MAGENTA_CODE, RED_CODE, RESET_CODE, UNDERLINE_CODE,
|
||||
WHITE_CODE, YELLOW_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,
|
||||
UNDERLINE_CODE, WHITE_CODE, YELLOW_CODE,
|
||||
};
|
||||
use roc_reporting::report::{RocDocAllocator, RocDocBuilder};
|
||||
use roc_solve::solve;
|
||||
@ -38,6 +38,7 @@ mod test_reporting {
|
||||
title: "".to_string(),
|
||||
doc,
|
||||
filename: filename_from_string(r"\code\proj\Main.roc"),
|
||||
severity: Severity::RuntimeError,
|
||||
}
|
||||
}
|
||||
|
||||
@ -301,7 +302,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── NOT EXPOSED ─────────────────────────────────────────────────────────────────
|
||||
|
||||
The List module does not expose a foobar value:
|
||||
|
||||
@ -325,7 +326,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── UNUSED DEFINITION ───────────────────────────────────────────────────────────
|
||||
|
||||
`y` is not used anywhere in your code.
|
||||
|
||||
@ -354,7 +355,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── DUPLICATE NAME ──────────────────────────────────────────────────────────────
|
||||
|
||||
The `i` name is first defined here:
|
||||
|
||||
@ -391,7 +392,7 @@ mod test_reporting {
|
||||
// Booly is called a "variable"
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── DUPLICATE NAME ──────────────────────────────────────────────────────────────
|
||||
|
||||
The `Booly` name is first defined here:
|
||||
|
||||
@ -406,7 +407,7 @@ mod test_reporting {
|
||||
Since these variables have the same name, it's easy to use the wrong
|
||||
one on accident. Give one of them a new name.
|
||||
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── UNUSED DEFINITION ───────────────────────────────────────────────────────────
|
||||
|
||||
`Booly` is not used anywhere in your code.
|
||||
|
||||
@ -514,7 +515,7 @@ mod test_reporting {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unused_undefined_argument() {
|
||||
fn unrecognized_name() {
|
||||
report_problem_as(
|
||||
indoc!(
|
||||
r#"
|
||||
@ -533,7 +534,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── UNRECOGNIZED NAME ───────────────────────────────────────────────────────────
|
||||
|
||||
I cannot find a `bar` value
|
||||
|
||||
@ -582,57 +583,79 @@ mod test_reporting {
|
||||
)
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn report_unused_argument() {
|
||||
// report_problem_as(
|
||||
// indoc!(r#"
|
||||
// y = 9
|
||||
//
|
||||
// box = \class, htmlChildren ->
|
||||
// div [ class ] []
|
||||
//
|
||||
// div = 4
|
||||
//
|
||||
// box "wizard" []
|
||||
// "#),
|
||||
// indoc!(
|
||||
// r#"
|
||||
// box doesn't use htmlChildren.
|
||||
//
|
||||
// 3│ box = \class, htmlChildren ->
|
||||
//
|
||||
// If you don't need htmlChildren, then you can just remove it. However, if you really do need htmlChildren as an argument of box, prefix it with an underscore, like this: "_htmlChildren". Adding an underscore at the start of a variable name is a way of saying that the variable is not used."#
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
#[test]
|
||||
fn unused_arg_and_unused_def() {
|
||||
report_problem_as(
|
||||
indoc!(
|
||||
r#"
|
||||
y = 9
|
||||
|
||||
box = \class, htmlChildren ->
|
||||
div [ class ] []
|
||||
|
||||
div = \_, _ -> 4
|
||||
|
||||
box "wizard" []
|
||||
"#
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── UNUSED ARGUMENT ─────────────────────────────────────────────────────────────
|
||||
|
||||
`box` doesn't use `htmlChildren`.
|
||||
|
||||
3│ box = \class, htmlChildren ->
|
||||
^^^^^^^^^^^^
|
||||
|
||||
If you don't need `htmlChildren`, then you can just remove it. However,
|
||||
if you really do need `htmlChildren` as an argument of `box`, prefix it
|
||||
with an underscore, like this: "_`htmlChildren`". Adding an underscore
|
||||
at the start of a variable name is a way of saying that the variable
|
||||
is not used.
|
||||
|
||||
── UNUSED DEFINITION ───────────────────────────────────────────────────────────
|
||||
|
||||
`y` is not used anywhere in your code.
|
||||
|
||||
1│ y = 9
|
||||
^
|
||||
|
||||
If you didn't intend on using `y` then remove it so future readers of
|
||||
your code don't wonder why it is there.
|
||||
"#
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn report_unused_import() {
|
||||
// report_problem_as(
|
||||
// indoc!(r#"
|
||||
// interface Report
|
||||
// exposes [
|
||||
// plainText,
|
||||
// emText
|
||||
// ]
|
||||
// imports [
|
||||
// Symbol.{ Interns }
|
||||
// ]
|
||||
//
|
||||
// plainText = \str -> PlainText str
|
||||
//
|
||||
// emText = \str -> EmText str
|
||||
// "#),
|
||||
// indoc!(
|
||||
// r#"
|
||||
// Nothing from Symbol is used in this module.
|
||||
//
|
||||
// 6│ imports [
|
||||
// 7│ Symbol.{ Interns }
|
||||
// ^^^^^^
|
||||
// 8│ ]
|
||||
//
|
||||
// Since Symbol isn't used, you don't need to import it."#
|
||||
// interface Report
|
||||
// exposes [
|
||||
// plainText,
|
||||
// emText
|
||||
// ]
|
||||
// imports [
|
||||
// Symbol.{ Interns }
|
||||
// ]
|
||||
|
||||
// plainText = \str -> PlainText str
|
||||
|
||||
// emText = \str -> EmText str
|
||||
// "#
|
||||
// ),
|
||||
// indoc!(
|
||||
// r#"
|
||||
// Nothing from Symbol is used in this module.
|
||||
|
||||
// 6│ imports [
|
||||
// 7│ Symbol.{ Interns }
|
||||
// ^^^^^^
|
||||
// 8│ ]
|
||||
|
||||
// Since Symbol isn't used, you don't need to import it."#
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
@ -709,7 +732,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
<cyan>── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────<reset>
|
||||
<cyan>── UNRECOGNIZED NAME ───────────────────────────────────────────────────────────<reset>
|
||||
|
||||
I cannot find a `theAdmin` value
|
||||
|
||||
@ -727,51 +750,51 @@ mod test_reporting {
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn shadowing_type_alias() {
|
||||
// report_problem_as(
|
||||
// indoc!(
|
||||
// r#"
|
||||
// foo : I64 as I64
|
||||
// foo = 42
|
||||
//
|
||||
// foo
|
||||
// "#
|
||||
// ),
|
||||
// indoc!(
|
||||
// r#"
|
||||
// You cannot mix (!=) and (==) without parentheses
|
||||
//
|
||||
// 3│ if selectedId != thisId == adminsId then
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//
|
||||
// "#
|
||||
// ),
|
||||
// )
|
||||
// }
|
||||
// #[test]
|
||||
// fn shadowing_type_alias() {
|
||||
// report_problem_as(
|
||||
// indoc!(
|
||||
// r#"
|
||||
// foo : I64 as I64
|
||||
// foo = 42
|
||||
|
||||
// #[test]
|
||||
// fn invalid_as_type_alias() {
|
||||
// report_problem_as(
|
||||
// indoc!(
|
||||
// r#"
|
||||
// foo : I64 as a
|
||||
// foo = 42
|
||||
//
|
||||
// foo
|
||||
// "#
|
||||
// ),
|
||||
// indoc!(
|
||||
// r#"
|
||||
// You cannot mix (!=) and (==) without parentheses
|
||||
//
|
||||
// 3│ if selectedId != thisId == adminsId then
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//
|
||||
// "#
|
||||
// ),
|
||||
// )
|
||||
// }
|
||||
// foo
|
||||
// "#
|
||||
// ),
|
||||
// indoc!(
|
||||
// r#"
|
||||
// You cannot mix (!=) and (==) without parentheses
|
||||
|
||||
// 3│ if selectedId != thisId == adminsId then
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
// "#
|
||||
// ),
|
||||
// )
|
||||
// }
|
||||
|
||||
// #[test]
|
||||
// fn invalid_as_type_alias() {
|
||||
// report_problem_as(
|
||||
// indoc!(
|
||||
// r#"
|
||||
// foo : I64 as a
|
||||
// foo = 42
|
||||
|
||||
// foo
|
||||
// "#
|
||||
// ),
|
||||
// indoc!(
|
||||
// r#"
|
||||
// You cannot mix (!=) and (==) without parentheses
|
||||
|
||||
// 3│ if selectedId != thisId == adminsId then
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
// "#
|
||||
// ),
|
||||
// )
|
||||
// }
|
||||
|
||||
#[test]
|
||||
fn if_condition_not_bool() {
|
||||
@ -1461,7 +1484,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── UNRECOGNIZED NAME ───────────────────────────────────────────────────────────
|
||||
|
||||
I cannot find a `foo` value
|
||||
|
||||
@ -1917,7 +1940,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── UNRECOGNIZED NAME ───────────────────────────────────────────────────────────
|
||||
|
||||
I cannot find a `ok` value
|
||||
|
||||
@ -1952,7 +1975,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── UNUSED DEFINITION ───────────────────────────────────────────────────────────
|
||||
|
||||
`ok` is not used anywhere in your code.
|
||||
|
||||
@ -1998,7 +2021,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── CIRCULAR DEFINITION ─────────────────────────────────────────────────────────
|
||||
|
||||
The `f` value is defined directly in terms of itself, causing an
|
||||
infinite loop.
|
||||
@ -2022,7 +2045,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── CIRCULAR DEFINITION ─────────────────────────────────────────────────────────
|
||||
|
||||
The `foo` definition is causing a very tricky infinite loop:
|
||||
|
||||
@ -2789,7 +2812,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── DUPLICATE FIELD NAME ────────────────────────────────────────────────────────
|
||||
|
||||
This record defines the `.x` field twice!
|
||||
|
||||
@ -2817,7 +2840,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── DUPLICATE FIELD NAME ────────────────────────────────────────────────────────
|
||||
|
||||
This record defines the `.x` field twice!
|
||||
|
||||
@ -2849,7 +2872,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── DUPLICATE FIELD NAME ────────────────────────────────────────────────────────
|
||||
|
||||
This record defines the `.x` field twice!
|
||||
|
||||
@ -2888,7 +2911,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── DUPLICATE FIELD NAME ────────────────────────────────────────────────────────
|
||||
|
||||
This record defines the `.x` field twice!
|
||||
|
||||
@ -2925,7 +2948,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── DUPLICATE FIELD NAME ────────────────────────────────────────────────────────
|
||||
|
||||
This record type defines the `.foo` field twice!
|
||||
|
||||
@ -2957,7 +2980,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── DUPLICATE TAG NAME ──────────────────────────────────────────────────────────
|
||||
|
||||
This tag union type defines the `Foo` tag twice!
|
||||
|
||||
@ -2990,7 +3013,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── NAMING PROBLEM ──────────────────────────────────────────────────────────────
|
||||
|
||||
This annotation does not match the definition immediately following
|
||||
it:
|
||||
@ -3041,7 +3064,7 @@ mod test_reporting {
|
||||
|
||||
Only type variables like `a` or `value` can occur in this position.
|
||||
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── UNUSED DEFINITION ───────────────────────────────────────────────────────────
|
||||
|
||||
`MyAlias` is not used anywhere in your code.
|
||||
|
||||
@ -3177,17 +3200,17 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── UNUSED TYPE ALIAS PARAMETER ─────────────────────────────────────────────────
|
||||
|
||||
The `a` type variable is not used in the `Foo` alias definition:
|
||||
The `a` type parameter is not used in the `Foo` alias definition:
|
||||
|
||||
1│ Foo a : [ Foo ]
|
||||
^
|
||||
|
||||
Roc does not allow unused type parameters!
|
||||
Roc does not allow unused type alias parameters!
|
||||
|
||||
Tip: If you want an unused type parameter (a so-called "phantom
|
||||
type"), read the guide section on phantom data.
|
||||
type"), read the guide section on phantom values.
|
||||
"#
|
||||
),
|
||||
)
|
||||
@ -3604,7 +3627,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── MODULE NOT IMPORTED ─────────────────────────────────────────────────────────
|
||||
|
||||
The `Foo` module is not imported:
|
||||
|
||||
@ -4035,7 +4058,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── UNUSED ARGUMENT ─────────────────────────────────────────────────────────────
|
||||
|
||||
`f` doesn't use `foo`.
|
||||
|
||||
@ -5446,7 +5469,7 @@ mod test_reporting {
|
||||
r#""abc\u(110000)def""#,
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── INVALID UNICODE ─────────────────────────────────────────────────────────────
|
||||
|
||||
This unicode code point is invalid:
|
||||
|
||||
@ -5570,7 +5593,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── NOT EXPOSED ─────────────────────────────────────────────────────────────────
|
||||
|
||||
The Num module does not expose a if value:
|
||||
|
||||
@ -5710,7 +5733,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── NAMING PROBLEM ──────────────────────────────────────────────────────────────
|
||||
|
||||
I am trying to parse an identifier here:
|
||||
|
||||
@ -5767,7 +5790,7 @@ mod test_reporting {
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
── SYNTAX PROBLEM ──────────────────────────────────────────────────────────────
|
||||
── UNRECOGNIZED NAME ───────────────────────────────────────────────────────────
|
||||
|
||||
I cannot find a `bar` value
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user