diff --git a/crates/compiler/load/tests/test_reporting.rs b/crates/compiler/load/tests/test_reporting.rs index 66a9767604..8a22b9fa86 100644 --- a/crates/compiler/load/tests/test_reporting.rs +++ b/crates/compiler/load/tests/test_reporting.rs @@ -4771,7 +4771,7 @@ mod test_reporting { // TODO investigate this test. It was disabled in https://github.com/roc-lang/roc/pull/6634 // as the way Defs without final expressions are handled. The changes probably shouldn't have // changed this error report. The exact same test_syntax test for this has not changed, so - // we know the parser is parsing thesame thing. Therefore the way the AST is desugared must be + // we know the parser is parsing the same thing. Therefore the way the AST is desugared must be // the cause of the change in error report. // test_report!( // def_missing_final_expression, @@ -8162,7 +8162,7 @@ In roc, functions are always written as a lambda, like{} "# ), // TODO(opaques): error could be improved by saying that the opaque definition demands - // that the argument be a U8, and linking to the definitin! + // that the argument be a U8, and linking to the definition! @r#" ── TYPE MISMATCH in /code/proj/Main.roc ──────────────────────────────────────── @@ -13530,7 +13530,7 @@ In roc, functions are always written as a lambda, like{} 4│ crash "" "" ^^^^^ - `crash` must be given exacly one message to crash with. + `crash` must be given exactly one message to crash with. "# ); diff --git a/crates/compiler/load_internal/src/file.rs b/crates/compiler/load_internal/src/file.rs index be4628f1d6..3315a5a8ba 100644 --- a/crates/compiler/load_internal/src/file.rs +++ b/crates/compiler/load_internal/src/file.rs @@ -6303,6 +6303,8 @@ fn to_incorrect_module_name_report<'a>( expected, } = problem; + let severity = Severity::RuntimeError; + // SAFETY: if the module was not UTF-8, that would be reported as a parsing problem, rather // than an incorrect module name problem (the latter can happen only after parsing). let src = unsafe { from_utf8_unchecked(src) }; @@ -6317,7 +6319,7 @@ fn to_incorrect_module_name_report<'a>( let doc = alloc.stack([ alloc.reflow("This module has a different name than I expected:"), - alloc.region(lines.convert_region(found.region)), + alloc.region(lines.convert_region(found.region), severity), alloc.reflow("Based on the nesting and use of this module, I expect it to have name"), alloc.pq_module_name(expected).indent(4), ]); @@ -6326,7 +6328,7 @@ fn to_incorrect_module_name_report<'a>( filename, doc, title: "INCORRECT MODULE NAME".to_string(), - severity: Severity::RuntimeError, + severity, }; let mut buf = String::new(); @@ -6346,6 +6348,7 @@ fn to_no_platform_package_report( ) -> String { use roc_reporting::report::{Report, RocDocAllocator, DEFAULT_PALETTE}; use ven_pretty::DocAllocator; + let severity = Severity::RuntimeError; // SAFETY: if the module was not UTF-8, that would be reported as a parsing problem, rather // than an incorrect module name problem (the latter can happen only after parsing). @@ -6361,7 +6364,7 @@ fn to_no_platform_package_report( let doc = alloc.stack([ alloc.reflow("This app does not specify a platform:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region),severity), alloc.reflow("Make sure you have exactly one package specified as `platform`:"), alloc .parser_suggestion(" app [main] {\n pf: platform \"…path or URL to platform…\"\n ^^^^^^^^\n }"), @@ -6373,7 +6376,7 @@ fn to_no_platform_package_report( filename, doc, title: "UNSPECIFIED PLATFORM".to_string(), - severity: Severity::RuntimeError, + severity, }; let mut buf = String::new(); @@ -6393,6 +6396,7 @@ fn to_multiple_platform_packages_report( ) -> String { use roc_reporting::report::{Report, RocDocAllocator, DEFAULT_PALETTE}; use ven_pretty::DocAllocator; + let severity = Severity::RuntimeError; // SAFETY: if the module was not UTF-8, that would be reported as a parsing problem, rather // than an incorrect module name problem (the latter can happen only after parsing). @@ -6408,7 +6412,7 @@ fn to_multiple_platform_packages_report( let doc = alloc.stack([ alloc.reflow("This app specifies multiple packages as `platform`:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("Roc apps must specify exactly one platform."), ]); @@ -6416,7 +6420,7 @@ fn to_multiple_platform_packages_report( filename, doc, title: "MULTIPLE PLATFORMS".to_string(), - severity: Severity::RuntimeError, + severity, }; let mut buf = String::new(); diff --git a/crates/reporting/src/error/canonicalize.rs b/crates/reporting/src/error/canonicalize.rs index 79898ed037..41957cdf3f 100644 --- a/crates/reporting/src/error/canonicalize.rs +++ b/crates/reporting/src/error/canonicalize.rs @@ -84,7 +84,7 @@ pub fn can_problem<'b>( alloc .symbol_unqualified(symbol) .append(alloc.reflow(" is not used anywhere in your code.")), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc .reflow("If you didn't intend on using ") .append(alloc.symbol_unqualified(symbol)) @@ -99,7 +99,7 @@ pub fn can_problem<'b>( alloc.symbol_qualified(symbol), alloc.reflow(" is not used in this module."), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.reflow("Since "), alloc.symbol_qualified(symbol), @@ -115,7 +115,7 @@ pub fn can_problem<'b>( alloc.module(module_id), alloc.reflow(" is imported but not used."), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.reflow("Since "), alloc.module(module_id), @@ -145,17 +145,17 @@ pub fn can_problem<'b>( alloc.reflow(" was imported here: ") }, ]), - alloc.region(lines.convert_region(new_import_region)), + alloc.region(lines.convert_region(new_import_region), severity), match existing_import { - ScopeModuleSource::Import(exsting_import_region) => { + ScopeModuleSource::Import(existing_import_region) => { alloc.stack([ alloc.concat([ alloc.reflow("but "), alloc.module_name(name.clone()), alloc.reflow(" is already used by a previous import:"), ]), - alloc.region(lines.convert_region(exsting_import_region)), + alloc.region(lines.convert_region(existing_import_region), severity), ]) } ScopeModuleSource::Builtin => { @@ -193,7 +193,7 @@ pub fn can_problem<'b>( alloc.module(module_id), alloc.reflow(" was imported here:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("Builtins are imported automatically, so you can remove this import."), alloc.reflow("Tip: Learn more about builtins in the tutorial:\n\n"), ]); @@ -207,7 +207,7 @@ pub fn can_problem<'b>( alloc.symbol_qualified(symbol), alloc.reflow(" was imported here:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.reflow("All types from builtins are automatically exposed, so you can remove "), alloc.symbol_unqualified(symbol), @@ -230,13 +230,13 @@ pub fn can_problem<'b>( alloc.symbol_qualified(new_symbol), alloc.reflow(":"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.reflow("However, the name "), alloc.symbol_unqualified(new_symbol), alloc.reflow(" was already used here:"), ]), - alloc.region(lines.convert_region(existing_symbol_region)), + alloc.region(lines.convert_region(existing_symbol_region), severity), alloc.concat([ alloc.reflow("You can rename it, or use the qualified name: "), alloc.symbol_qualified(new_symbol), @@ -249,7 +249,7 @@ pub fn can_problem<'b>( Problem::DefsOnlyUsedInRecursion(1, region) => { doc = alloc.stack([ alloc.reflow("This definition is only used in recursion with itself:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow( "If you don't intend to use or export this definition, it should be removed!", ), @@ -264,7 +264,7 @@ pub fn can_problem<'b>( alloc.string(n.to_string()), alloc.reflow(" definitions are only used in mutual recursion with themselves:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow( "If you don't intend to use or export any of them, they should all be removed!", ), @@ -293,7 +293,7 @@ pub fn can_problem<'b>( .reflow("I don't know how to generate the ") .append(alloc.ident(loc_ident.value)) .append(alloc.reflow(" function.")), - alloc.region(lines.convert_region(loc_ident.region)), + alloc.region(lines.convert_region(loc_ident.region), severity), alloc .reflow("Only specific functions like `after` and `map` can be generated.") .append(alloc.reflow("Learn more about hosted modules at TODO.")), @@ -315,7 +315,7 @@ pub fn can_problem<'b>( alloc.symbol_unqualified(argument_symbol), alloc.text("."), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.reflow("If you don't need "), alloc.symbol_unqualified(argument_symbol), @@ -343,7 +343,7 @@ pub fn can_problem<'b>( alloc.keyword("when"), alloc.reflow(" branch."), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.reflow("If you don't need to use "), alloc.symbol_unqualified(symbol), @@ -378,7 +378,7 @@ pub fn can_problem<'b>( )), ]) }, - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), ]); title = SYNTAX_PROBLEM.to_string(); @@ -407,7 +407,7 @@ pub fn can_problem<'b>( alloc .reflow("This pattern is not allowed in ") .append(alloc.reflow(this_thing)), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat(suggestion), ]); @@ -419,14 +419,14 @@ pub fn can_problem<'b>( kind, } => { let (res_title, res_doc) = - report_shadowing(alloc, lines, original_region, shadow, kind); + report_shadowing(alloc, lines, original_region, shadow, kind, severity); doc = res_doc; title = res_title.to_string(); } Problem::CyclicAlias(symbol, region, others, alias_kind) => { let answer = crate::error::r#type::cyclic_alias( - alloc, lines, symbol, region, others, alias_kind, + alloc, lines, symbol, region, others, alias_kind, severity, ); doc = answer.0; @@ -448,7 +448,7 @@ pub fn can_problem<'b>( alloc.reflow(alias_kind.as_str()), alloc.reflow(" definition:"), ]), - alloc.region(lines.convert_region(variable_region)), + alloc.region(lines.convert_region(variable_region), severity), alloc.reflow("Roc does not allow unused type parameters!"), // TODO add link to this guide section alloc.tip().append(alloc.reflow( @@ -485,7 +485,7 @@ pub fn can_problem<'b>( alloc.reflow(") type variables. Here is one of them:"), ])); } - stack.push(alloc.region(lines.convert_region(one_occurrence))); + stack.push(alloc.region(lines.convert_region(one_occurrence), severity)); stack.push(alloc.concat([ alloc.reflow(match kind { AliasKind::Structural => "Type alias", @@ -526,7 +526,7 @@ pub fn can_problem<'b>( ])); stack.push(alloc.reflow("Here is one of them:")); } - stack.push(alloc.region(lines.convert_region(one_occurrence))); + stack.push(alloc.region(lines.convert_region(one_occurrence), severity)); stack.push(alloc.concat([ alloc.reflow(match kind { AliasKind::Structural => "Type alias", @@ -568,7 +568,7 @@ pub fn can_problem<'b>( ])); stack.push(alloc.reflow("Here is one of them:")); } - stack.push(alloc.region(lines.convert_region(one_occurrence))); + stack.push(alloc.region(lines.convert_region(one_occurrence), severity)); stack.push(alloc.concat([ alloc.reflow("All type variables in "), alloc.reflow(match kind { @@ -587,7 +587,7 @@ pub fn can_problem<'b>( title = UNDECLARED_TYPE_VARIABLE.to_string(); } Problem::BadRecursion(entries) => { - doc = to_circular_def_doc(alloc, lines, &entries); + doc = to_circular_def_doc(alloc, lines, &entries, severity); title = CIRCULAR_DEF.to_string(); } Problem::DuplicateRecordFieldValue { @@ -716,6 +716,7 @@ pub fn can_problem<'b>( ), alloc.region( lines.convert_region(Region::span_across(annotation_pattern, def_pattern)), + severity, ), alloc.reflow("Is it a typo? If not, put either a newline or comment between them."), ]); @@ -732,7 +733,7 @@ pub fn can_problem<'b>( alloc.symbol_unqualified(type_name), alloc.reflow(" has an unexpected pattern:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.reflow("Only type variables like "), alloc.type_variable("a".into()), @@ -747,7 +748,7 @@ pub fn can_problem<'b>( Problem::InvalidHexadecimal(region) => { doc = alloc.stack([ alloc.reflow("This unicode code point is invalid:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.reflow(r"I was expecting a hexadecimal number, like "), alloc.parser_suggestion("\\u(1100)"), @@ -763,7 +764,7 @@ pub fn can_problem<'b>( Problem::InvalidUnicodeCodePt(region) => { doc = alloc.stack([ alloc.reflow("This unicode code point is invalid:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("Learn more about working with unicode in roc at TODO"), ]); @@ -772,7 +773,7 @@ pub fn can_problem<'b>( Problem::InvalidInterpolation(region) => { doc = alloc.stack([ alloc.reflow("This string interpolation is invalid:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow(r"String interpolations cannot contain newlines or other interpolations."), alloc.reflow(r"You can learn more about string interpolation at "), ]); @@ -795,13 +796,13 @@ pub fn can_problem<'b>( alloc.symbol_unqualified(alias), alloc.reflow(" is a nested datatype. Here is one recursive usage of it:"), ]), - alloc.region(lines.convert_region(differing_recursion_region)), + alloc.region(lines.convert_region(differing_recursion_region), severity), alloc.concat([ alloc.reflow("But recursive usages of "), alloc.symbol_unqualified(alias), alloc.reflow(" must match its definition:"), ]), - alloc.region(lines.convert_region(def_region)), + alloc.region(lines.convert_region(def_region), severity), alloc.reflow("Nested datatypes are not supported in Roc."), alloc.concat([ alloc.hint("Consider rewriting the definition of "), @@ -827,7 +828,7 @@ pub fn can_problem<'b>( alloc.text(kind_str), alloc.reflow(" extension type is invalid:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.note("A "), alloc.reflow(kind_str), @@ -850,7 +851,7 @@ pub fn can_problem<'b>( alloc.symbol_unqualified(name), alloc.reflow(" ability includes type variables:"), ]), - alloc.region(lines.convert_region(variables_region)), + alloc.region(lines.convert_region(variables_region), severity), alloc.reflow( "Abilities cannot depend on type variables, but their member values can!", ), @@ -865,7 +866,7 @@ pub fn can_problem<'b>( alloc.reflow( r#"The type referenced in this "implements" clause is not an ability:"#, ), - alloc.region(lines.convert_region(clause_region)), + alloc.region(lines.convert_region(clause_region), severity), ]); title = IMPLEMENTS_CLAUSE_IS_NOT_AN_ABILITY.to_string(); } @@ -877,7 +878,7 @@ pub fn can_problem<'b>( alloc.keyword(roc_parse::keyword::IMPLEMENTS), alloc.reflow(" clause is not allowed here:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.keyword(roc_parse::keyword::IMPLEMENTS), alloc.reflow( @@ -895,7 +896,7 @@ pub fn can_problem<'b>( alloc.symbol_foreign_qualified(ability), alloc.reflow(" ability once before:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.reflow("Abilities only need to bound to a type variable once in an "), alloc.keyword(roc_parse::keyword::IMPLEMENTS), @@ -920,7 +921,7 @@ pub fn can_problem<'b>( alloc.symbol_unqualified(ability), alloc.reflow(":"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.reflow("Ability members must include an "), alloc.keyword(roc_parse::keyword::IMPLEMENTS), @@ -953,7 +954,7 @@ pub fn can_problem<'b>( alloc.symbol_unqualified(ability), alloc.keyword(" ability:"), ]), - alloc.region(lines.convert_region(span_has_clauses)), + alloc.region(lines.convert_region(span_has_clauses), severity), alloc.reflow("Ability members can only bind one type variable to their parent ability. Otherwise, I wouldn't know what type implements an ability by looking at specializations!"), alloc.concat([ alloc.hint("Did you mean to only bind "), @@ -971,7 +972,7 @@ pub fn can_problem<'b>( alloc .concat([alloc .reflow("This ability definition is not on the top-level of a module:")]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("Abilities can only be defined on the top-level of a Roc module."), ]); title = ABILITY_NOT_ON_TOPLEVEL.to_string(); @@ -984,7 +985,7 @@ pub fn can_problem<'b>( alloc.symbol_unqualified(ability), alloc.reflow(" as a type directly:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow( "Abilities can only be used in type annotations to constrain type variables.", ), @@ -1010,7 +1011,7 @@ pub fn can_problem<'b>( alloc.symbol_unqualified(member), alloc.reflow(" ability member is in a nested scope:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("Specializations can only be defined on the top-level of a module."), ]); title = SPECIALIZATION_NOT_ON_TOPLEVEL.to_string(); @@ -1018,7 +1019,7 @@ pub fn can_problem<'b>( Problem::IllegalDerivedAbility(region) => { doc = alloc.stack([ alloc.reflow("This ability cannot be derived:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("Only builtin abilities can be derived."), alloc .note("The builtin abilities are ") @@ -1029,7 +1030,7 @@ pub fn can_problem<'b>( Problem::NotAnAbility(region) => { doc = alloc.stack([ alloc.reflow("This identifier is not an ability in scope:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("Only abilities can be implemented."), ]); title = NOT_AN_ABILITY.to_string(); @@ -1043,7 +1044,7 @@ pub fn can_problem<'b>( alloc.concat([ alloc.reflow("The "), alloc.symbol_unqualified(ability), alloc.reflow(" ability does not have a member "), alloc.string(name), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("Only implementations for members an ability has can be specified in this location.") ]); title = NOT_AN_ABILITY_MEMBER.to_string(); @@ -1054,7 +1055,7 @@ pub fn can_problem<'b>( alloc.concat([ alloc.reflow("An implementation of "), alloc.symbol_unqualified(member), alloc.reflow(" could not be found in this scope:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.tip().append(alloc.concat([alloc.reflow("consider adding a value of name "), alloc.symbol_unqualified(member), alloc.reflow(" in this scope, or using another variable that implements this ability member, like "), alloc.type_str(&format!("{{ {member_str}: my{member_str} }}"))])) ]); title = IMPLEMENTATION_NOT_FOUND.to_string(); @@ -1071,7 +1072,7 @@ pub fn can_problem<'b>( doc = alloc.stack([ alloc.reflow("Ability implementations cannot be optional:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("Custom implementations must be supplied fully."), hint, ]); @@ -1080,7 +1081,7 @@ pub fn can_problem<'b>( Problem::QualifiedAbilityImpl { region } => { doc = alloc.stack([ alloc.reflow("This ability implementation is qualified:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow( "Custom implementations must be defined in the local scope, and unqualified.", ), @@ -1090,7 +1091,7 @@ pub fn can_problem<'b>( Problem::AbilityImplNotIdent { region } => { doc = alloc.stack([ alloc.reflow("This ability implementation is not an identifier:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow( "Custom ability implementations defined in this position can only be unqualified identifiers, not arbitrary expressions.", ), @@ -1104,9 +1105,9 @@ pub fn can_problem<'b>( } => { doc = alloc.stack([ alloc.reflow("This ability member implementation is duplicate:"), - alloc.region(lines.convert_region(duplicate)), + alloc.region(lines.convert_region(duplicate), severity), alloc.reflow("The first implementation was defined here:"), - alloc.region(lines.convert_region(original)), + alloc.region(lines.convert_region(original), severity), alloc .reflow("Only one custom implementation can be defined for an ability member."), ]); @@ -1123,7 +1124,7 @@ pub fn can_problem<'b>( alloc.symbol_unqualified(ability), alloc.reflow(" ability:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("The following implemented members should not be listed:"), alloc.type_block( alloc.intersperse( @@ -1147,7 +1148,7 @@ pub fn can_problem<'b>( alloc.symbol_unqualified(ability), alloc.reflow(" ability:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("The following necessary members are missing implementations:"), alloc.type_block( alloc.intersperse( @@ -1171,7 +1172,7 @@ pub fn can_problem<'b>( alloc.keyword("when"), alloc.reflow(" branch"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.reflow("Identifiers introduced in a "), alloc.keyword("when"), @@ -1183,7 +1184,7 @@ pub fn can_problem<'b>( Problem::NoIdentifiersIntroduced(region) => { doc = alloc.stack([ alloc.reflow("This destructure assignment doesn't introduce any new variables:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("If you don't need to use the value on the right-hand-side of this assignment, consider removing the assignment. Since Roc is purely functional, assignments that don't introduce variables cannot affect a program's behavior!"), ]); title = "UNNECESSARY DEFINITION".to_string(); @@ -1195,7 +1196,7 @@ pub fn can_problem<'b>( } => { doc = alloc.stack([ alloc.reflow("This ability member specialization is already claimed to specialize another opaque type:"), - alloc.region(lines.convert_region(overload)), + alloc.region(lines.convert_region(overload), severity), alloc.concat([ alloc.reflow("Previously, we found it to specialize "), alloc.symbol_unqualified(ability_member), @@ -1214,7 +1215,7 @@ pub fn can_problem<'b>( alloc.keyword("*"), alloc.reflow(") that isn't needed."), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.reflow("Annotations for tag unions which are constants, or which are returned from functions, work the same way with or without a "), alloc.keyword("*"), @@ -1229,7 +1230,7 @@ pub fn can_problem<'b>( Problem::MultipleListRestPattern { region } => { doc = alloc.stack([ alloc.reflow("This list pattern match has multiple rest patterns:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.reflow("I only support compiling list patterns with one "), alloc.parser_suggestion(".."), @@ -1267,7 +1268,7 @@ pub fn can_problem<'b>( found_arguments, alloc.reflow(" instead:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("Are there missing parentheses?"), ]); @@ -1282,7 +1283,7 @@ pub fn can_problem<'b>( alloc.concat([ alloc.reflow("This "), alloc.keyword("crash"), alloc.reflow(" doesn't have a message given to it:") ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.keyword("crash"), alloc.reflow(" must be passed a message to crash with at the exact place it's used. "), alloc.keyword("crash"), alloc.reflow(" can't be used as a value that's passed around, like functions can be - it must be applied immediately!"), @@ -1297,10 +1298,10 @@ pub fn can_problem<'b>( alloc.keyword("crash"), alloc.reflow(" has too many values given to it:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.keyword("crash"), - alloc.reflow(" must be given exacly one message to crash with."), + alloc.reflow(" must be given exactly one message to crash with."), ]), ]); title = "OVERAPPLIED CRASH".to_string(); @@ -1384,6 +1385,7 @@ fn to_bad_ident_expr_report<'b>( lines: &LineInfo, bad_ident: roc_parse::ident::BadIdent, surroundings: Region, + severity: Severity, ) -> RocDocBuilder<'b> { use roc_parse::ident::BadIdent::*; @@ -1394,7 +1396,7 @@ fn to_bad_ident_expr_report<'b>( alloc.stack([ alloc.reflow(r"I am trying to parse a record field access here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("So I expect to see a lowercase letter next, like "), alloc.parser_suggestion(".name"), @@ -1407,7 +1409,7 @@ fn to_bad_ident_expr_report<'b>( WeirdAccessor(_pos) => alloc.stack([ alloc.reflow("I am very confused by this field access"), - alloc.region(lines.convert_region(surroundings)), + alloc.region(lines.convert_region(surroundings), severity), alloc.concat([ alloc.reflow("It looks like a field access on an accessor. I parse"), alloc.parser_suggestion(".client.name"), @@ -1425,7 +1427,7 @@ fn to_bad_ident_expr_report<'b>( alloc.stack([ alloc.reflow("I am trying to parse a qualified name here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I was expecting to see an identifier next, like "), alloc.parser_suggestion("height"), @@ -1440,7 +1442,7 @@ fn to_bad_ident_expr_report<'b>( alloc.stack([ alloc.reflow("I am trying to parse a qualified name here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("This looks like a tuple accessor on a module or tag name,"), alloc.reflow(r"but neither modules nor tags can have tuple elements! "), @@ -1455,7 +1457,7 @@ fn to_bad_ident_expr_report<'b>( alloc.stack([ alloc.reflow("I am trying to parse a qualified name here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"This looks like a qualified tag name to me, "), alloc.reflow(r"but tags cannot be qualified! "), @@ -1469,7 +1471,7 @@ fn to_bad_ident_expr_report<'b>( UnderscoreAlone(_pos) => { alloc.stack([ alloc.reflow("An underscore is being used as a variable here:"), - alloc.region(lines.convert_region(surroundings)), + alloc.region(lines.convert_region(surroundings), severity), alloc.concat([alloc .reflow(r"An underscore can be used to ignore a value when pattern matching, but it cannot be used as a variable.")]), ]) @@ -1478,7 +1480,7 @@ fn to_bad_ident_expr_report<'b>( UnderscoreInMiddle(_pos) => { alloc.stack([ alloc.reflow("Underscores are not allowed in identifier names:"), - alloc.region(lines.convert_region(surroundings)), + alloc.region(lines.convert_region(surroundings), severity), alloc.concat([alloc .reflow(r"I recommend using camelCase. It's the standard style in Roc code!")]), ]) @@ -1494,11 +1496,11 @@ fn to_bad_ident_expr_report<'b>( None => alloc.reflow(line), Some(declaration_region) => alloc.stack([ alloc.reflow(line), - alloc.region(lines.convert_region(declaration_region)), + alloc.region(lines.convert_region(declaration_region), severity), alloc.reflow("But then it is used here:"), ]) }, - alloc.region(lines.convert_region(surroundings)), + alloc.region(lines.convert_region(surroundings), severity), alloc.concat([ alloc.reflow(r"A variable's name can only start with an underscore if the variable is unused. "), match declaration_region { @@ -1521,6 +1523,7 @@ fn to_bad_ident_expr_report<'b>( alloc.region_with_subregion( lines.convert_region(surroundings), lines.convert_region(region), + severity ), alloc.concat([ alloc.reflow(r"It looks like a record field access on "), @@ -1536,6 +1539,7 @@ fn to_bad_ident_expr_report<'b>( alloc.region_with_subregion( lines.convert_region(surroundings), lines.convert_region(region), + severity ), alloc.concat([ alloc.reflow(r"Looks like "), @@ -1559,6 +1563,7 @@ fn to_bad_ident_expr_report<'b>( alloc.region_with_subregion( lines.convert_region(surroundings), lines.convert_region(region), + severity, ), alloc.concat([ alloc.reflow(r"But after the "), @@ -1584,6 +1589,7 @@ fn to_bad_ident_pattern_report<'b>( lines: &LineInfo, bad_ident: roc_parse::ident::BadIdent, surroundings: Region, + severity: Severity, ) -> RocDocBuilder<'b> { use roc_parse::ident::BadIdent::*; @@ -1594,7 +1600,7 @@ fn to_bad_ident_pattern_report<'b>( alloc.stack([ alloc.reflow(r"I am trying to parse a record field accessor here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("Something like "), alloc.parser_suggestion(".name"), @@ -1607,7 +1613,7 @@ fn to_bad_ident_pattern_report<'b>( WeirdAccessor(_pos) => alloc.stack([ alloc.reflow("I am very confused by this field access"), - alloc.region(lines.convert_region(surroundings)), + alloc.region(lines.convert_region(surroundings), severity), alloc.concat([ alloc.reflow("It looks like a field access on an accessor. I parse"), alloc.parser_suggestion(".client.name"), @@ -1625,7 +1631,7 @@ fn to_bad_ident_pattern_report<'b>( alloc.stack([ alloc.reflow("I am trying to parse a qualified name here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I was expecting to see an identifier next, like "), alloc.parser_suggestion("height"), @@ -1640,7 +1646,7 @@ fn to_bad_ident_pattern_report<'b>( alloc.stack([ alloc.reflow("I am trying to parse a qualified name here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"This looks like a qualified tag name to me, "), alloc.reflow(r"but tags cannot be qualified! "), @@ -1665,6 +1671,7 @@ fn to_bad_ident_pattern_report<'b>( alloc.region_with_subregion( lines.convert_region(surroundings), lines.convert_region(region), + severity, ), alloc.concat([alloc.reflow( r"Underscores are not allowed in identifiers. Use camelCase instead!", @@ -1677,7 +1684,7 @@ fn to_bad_ident_pattern_report<'b>( alloc.stack([ alloc.reflow("This opaque type reference has an invalid name:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"Opaque type names must begin with a capital letter, "), alloc.reflow(r"and must contain only letters and numbers."), @@ -1756,6 +1763,7 @@ fn report_shadowing<'b>( original_region: Region, shadow: Loc, kind: ShadowKind, + severity: Severity, ) -> (&'static str, RocDocBuilder<'b>) { let (what, what_plural, is_builtin) = match kind { ShadowKind::Variable => ("variable", "variables", false), @@ -1771,7 +1779,7 @@ fn report_shadowing<'b>( alloc.reflow(what), alloc.reflow(" has the same name as a builtin:"), ]), - alloc.region(lines.convert_region(shadow.region)), + alloc.region(lines.convert_region(shadow.region), severity), alloc.concat([ alloc.reflow("All builtin "), alloc.reflow(what_plural), @@ -1786,9 +1794,9 @@ fn report_shadowing<'b>( .text("The ") .append(alloc.ident(shadow.value)) .append(alloc.reflow(" name is first defined here:")), - alloc.region(lines.convert_region(original_region)), + alloc.region(lines.convert_region(original_region), severity), alloc.reflow("But then it's defined a second time here:"), - alloc.region(lines.convert_region(shadow.region)), + alloc.region(lines.convert_region(shadow.region), severity), alloc.concat([ alloc.reflow("Since these "), alloc.reflow(what_plural), @@ -1808,6 +1816,8 @@ fn pretty_runtime_error<'b>( let doc; let title; + let severity = Severity::RuntimeError; + match runtime_error { RuntimeError::VoidValue => { // is used to communicate to the compiler that @@ -1825,7 +1835,7 @@ fn pretty_runtime_error<'b>( shadow, kind, } => { - (title, doc) = report_shadowing(alloc, lines, original_region, shadow, kind); + (title, doc) = report_shadowing(alloc, lines, original_region, shadow, kind, severity); } RuntimeError::LookupNotInScope { @@ -1840,11 +1850,12 @@ fn pretty_runtime_error<'b>( &loc_name.value, options, underscored_suggestion_region, + severity, ); title = UNRECOGNIZED_NAME; } RuntimeError::CircularDef(entries) => { - doc = to_circular_def_doc(alloc, lines, &entries); + doc = to_circular_def_doc(alloc, lines, &entries, severity); title = CIRCULAR_DEF; } RuntimeError::MalformedPattern(problem, region) => { @@ -1860,7 +1871,7 @@ fn pretty_runtime_error<'b>( MalformedBase(Base::Decimal) => " integer ", BadIdent(bad_ident) => { title = NAMING_PROBLEM; - doc = to_bad_ident_pattern_report(alloc, lines, bad_ident, region); + doc = to_bad_ident_pattern_report(alloc, lines, bad_ident, region, severity); return (doc, title); } @@ -1892,7 +1903,7 @@ fn pretty_runtime_error<'b>( alloc.text(name), alloc.reflow("pattern is malformed:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), tip, ]); @@ -1933,7 +1944,7 @@ fn pretty_runtime_error<'b>( alloc.string(ident.to_string()), alloc.reflow("`:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), did_you_mean, ]); @@ -1953,6 +1964,7 @@ fn pretty_runtime_error<'b>( &module_name, imported_modules, module_exists, + severity, ); title = MODULE_NOT_IMPORTED; @@ -1972,14 +1984,14 @@ fn pretty_runtime_error<'b>( unreachable!(); } RuntimeError::MalformedIdentifier(_box_str, bad_ident, surroundings) => { - doc = to_bad_ident_expr_report(alloc, lines, bad_ident, surroundings); + doc = to_bad_ident_expr_report(alloc, lines, bad_ident, surroundings, severity); title = SYNTAX_PROBLEM; } RuntimeError::MalformedTypeName(_box_str, surroundings) => { doc = alloc.stack([ alloc.reflow(r"I am confused by this type name:"), - alloc.region(lines.convert_region(surroundings)), + alloc.region(lines.convert_region(surroundings), severity), alloc.concat([ alloc.reflow("Type names start with an uppercase letter, "), alloc.reflow("and can optionally be qualified by a module name, like "), @@ -2016,7 +2028,7 @@ fn pretty_runtime_error<'b>( alloc.text(big_or_small), alloc.reflow(":"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc .reflow("Roc uses signed 64-bit floating points, allowing values between "), @@ -2038,7 +2050,7 @@ fn pretty_runtime_error<'b>( alloc.concat([ alloc.reflow("This float literal contains an invalid digit:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.reflow("Floating point literals can only contain the digits 0-9, or use scientific notation 10e4, or have a float suffix."), ]), @@ -2052,7 +2064,7 @@ fn pretty_runtime_error<'b>( alloc .concat([alloc .reflow("This number literal is a float, but it has an integer suffix:")]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), ]); title = CONFLICTING_NUMBER_SUFFIX; @@ -2106,7 +2118,7 @@ fn pretty_runtime_error<'b>( alloc.text(problem), alloc.text(":"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.text(plurals), contains, @@ -2154,7 +2166,7 @@ fn pretty_runtime_error<'b>( alloc.text(big_or_small), alloc.reflow(":"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), info, tip, ]); @@ -2166,7 +2178,7 @@ fn pretty_runtime_error<'b>( alloc .concat([alloc .reflow("This number literal is an integer, but it has a float suffix:")]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), ]); title = CONFLICTING_NUMBER_SUFFIX; @@ -2183,7 +2195,7 @@ fn pretty_runtime_error<'b>( doc = alloc.stack([ alloc.concat([alloc .reflow("This integer literal overflows the type indicated by its suffix:")]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.tip().append(alloc.concat([ alloc.reflow("The suffix indicates this integer is a "), alloc.type_str(suffix_type), @@ -2207,7 +2219,7 @@ fn pretty_runtime_error<'b>( doc = alloc.stack([ alloc.concat([alloc .reflow("This integer literal underflows the type indicated by its suffix:")]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.tip().append(alloc.concat([ alloc.reflow("The suffix indicates this integer is a "), alloc.type_str(suffix_type), @@ -2240,7 +2252,7 @@ fn pretty_runtime_error<'b>( alloc.reflow("This expression cannot be updated"), alloc.reflow(":"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("Only variables can be updated with record update syntax."), ]); @@ -2286,7 +2298,7 @@ fn pretty_runtime_error<'b>( doc = alloc.stack([ alloc.concat([alloc.reflow("This character literal is empty.")]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), tip, ]); @@ -2301,7 +2313,7 @@ fn pretty_runtime_error<'b>( alloc.concat([ alloc.reflow("This character literal contains more than one code point.") ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([alloc.reflow("Character literals can only contain one code point.")]), tip, ]); @@ -2342,13 +2354,13 @@ fn pretty_runtime_error<'b>( alloc.type_str(opaque.as_inline_str().as_str()), alloc.reflow(" referenced here is not defined:"), ]), - alloc.region(lines.convert_region(used_region)), + alloc.region(lines.convert_region(used_region), severity), ]; if let Some(defined_alias_region) = opt_defined_alias { stack.push(alloc.stack([ alloc.note("There is an alias of the same name:"), - alloc.region(lines.convert_region(defined_alias_region)), + alloc.region(lines.convert_region(defined_alias_region), severity), ])); } @@ -2369,9 +2381,9 @@ fn pretty_runtime_error<'b>( alloc.type_str(opaque.as_inline_str().as_str()), alloc.reflow(" referenced here:"), ]), - alloc.region(lines.convert_region(referenced_region)), + alloc.region(lines.convert_region(referenced_region), severity), alloc.reflow("is imported from another module:"), - alloc.region(lines.convert_region(imported_region)), + alloc.region(lines.convert_region(imported_region), severity), alloc.note( "Opaque types can only be wrapped and unwrapped in the module they are defined in!", ), @@ -2382,7 +2394,7 @@ fn pretty_runtime_error<'b>( RuntimeError::OpaqueNotApplied(loc_ident) => { doc = alloc.stack([ alloc.reflow("This opaque type is not applied to an argument:"), - alloc.region(lines.convert_region(loc_ident.region)), + alloc.region(lines.convert_region(loc_ident.region), severity), alloc.note("Opaque types always wrap exactly one argument!"), ]); @@ -2391,7 +2403,7 @@ fn pretty_runtime_error<'b>( RuntimeError::OpaqueAppliedToMultipleArgs(region) => { doc = alloc.stack([ alloc.reflow("This opaque type is applied to multiple arguments:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.note("Opaque types always wrap exactly one argument!"), ]); @@ -2400,7 +2412,7 @@ fn pretty_runtime_error<'b>( RuntimeError::DegenerateBranch(region) => { doc = alloc.stack([ alloc.reflow("This branch pattern does not bind all symbols its body needs:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), ]); title = "DEGENERATE BRANCH"; @@ -2412,7 +2424,7 @@ fn pretty_runtime_error<'b>( doc = alloc.stack([ alloc.reflow("This function is applied to multiple record builders:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.note("Functions can only take at most one record builder!"), tip, ]); @@ -2422,7 +2434,7 @@ fn pretty_runtime_error<'b>( RuntimeError::UnappliedRecordBuilder(region) => { doc = alloc.stack([ alloc.reflow("This record builder was not applied to a function:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("However, we need a function to construct the record."), alloc.note( "Functions must be applied directly. The pipe operator (|>) cannot be used.", @@ -2440,6 +2452,7 @@ pub fn to_circular_def_doc<'b>( alloc: &'b RocDocAllocator<'b>, lines: &LineInfo, entries: &[roc_problem::can::CycleEntry], + severity: Severity, ) -> RocDocBuilder<'b> { // TODO "are you trying to mutate a variable? // TODO tip? @@ -2451,7 +2464,7 @@ pub fn to_circular_def_doc<'b>( alloc.symbol_unqualified(*symbol), alloc.reflow(" is defined directly in terms of itself:"), ]), - alloc.region(lines.convert_region(Region::span_across(symbol_region, expr_region))), + alloc.region(lines.convert_region(Region::span_across(symbol_region, expr_region)), severity), alloc.reflow("Roc evaluates values strictly, so running this program would enter an infinite loop!"), alloc.hint("").append(alloc.concat([ alloc.reflow("Did you mean to define "),alloc.symbol_unqualified(*symbol),alloc.reflow(" as a function?"), @@ -2463,7 +2476,7 @@ pub fn to_circular_def_doc<'b>( .reflow("The ") .append(alloc.symbol_unqualified(first.symbol)) .append(alloc.reflow(" definition is causing a very tricky infinite loop:")), - alloc.region(lines.convert_region(first.symbol_region)), + alloc.region(lines.convert_region(first.symbol_region), severity), alloc .reflow("The ") .append(alloc.symbol_unqualified(first.symbol)) @@ -2492,6 +2505,7 @@ fn not_found<'b>( name: &Ident, options: MutSet>, underscored_suggestion_region: Option, + severity: Severity, ) -> RocDocBuilder<'b> { let mut suggestions = suggest::sort( name.as_inline_str().as_str(), @@ -2510,7 +2524,7 @@ fn not_found<'b>( let default_yes = match underscored_suggestion_region { Some(underscored_region) => alloc.stack([ alloc.reflow("There is an ignored identifier of a similar name here:"), - alloc.region(lines.convert_region(underscored_region)), + alloc.region(lines.convert_region(underscored_region), severity), alloc.reflow("Did you mean to remove the leading underscore?"), alloc.reflow("If not, did you mean one of these?"), ]), @@ -2536,7 +2550,7 @@ fn not_found<'b>( alloc.string(name.to_string()), alloc.reflow("` in this scope."), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), to_details(default_no, default_yes), ]) } @@ -2551,13 +2565,14 @@ fn module_not_found<'b>( name: &ModuleName, options: MutSet>, module_exists: bool, + severity: Severity, ) -> RocDocBuilder<'b> { - // If the module exists, sugguest that the user import it + // If the module exists, suggest that the user import it let details = if module_exists { // TODO: Maybe give an example of how to do that alloc.reflow("Did you mean to import it?") } else { - // If the module might not exist, sugguest that it's a typo + // If the module might not exist, suggest that it's a typo let mut suggestions = suggest::sort(name.as_str(), options.iter().map(|v| v.as_ref()).collect()); suggestions.truncate(4); @@ -2587,7 +2602,7 @@ fn module_not_found<'b>( alloc.string(name.to_string()), alloc.reflow("` module is not imported:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), details, ]) } diff --git a/crates/reporting/src/error/expect.rs b/crates/reporting/src/error/expect.rs index 8b5eaa1b20..c0ff888b3c 100644 --- a/crates/reporting/src/error/expect.rs +++ b/crates/reporting/src/error/expect.rs @@ -80,6 +80,7 @@ impl<'a> Renderer<'a> { symbols: &[Symbol], variables: &[Variable], expressions: &[Expr<'_>], + severity: Severity, ) -> RocDocBuilder<'a> { use ven_pretty::DocAllocator; @@ -96,7 +97,7 @@ impl<'a> Renderer<'a> { if it.len() > 0 { self.alloc.stack([ self.alloc.text("This expectation failed:"), - self.alloc.region(line_col_region), + self.alloc.region(line_col_region, severity), self.alloc .text("When it failed, these variables had these values:"), self.alloc.stack(it), @@ -105,7 +106,7 @@ impl<'a> Renderer<'a> { } else { self.alloc.stack([ self.alloc.text("This expectation failed:"), - self.alloc.region(line_col_region), + self.alloc.region(line_col_region, severity), self.alloc.text(""), // Blank line at the end ]) } @@ -147,15 +148,23 @@ impl<'a> Renderer<'a> { W: std::io::Write, { use crate::report::Report; + let severity = Severity::RuntimeError; let line_col_region = self.to_line_col_region(expect_region, failure_region); - let doc = self.render_lookups(subs, line_col_region, symbols, variables, expressions); + let doc = self.render_lookups( + subs, + line_col_region, + symbols, + variables, + expressions, + severity, + ); let report = Report { title: "EXPECT FAILED".into(), doc, filename: self.filename.clone(), - severity: Severity::RuntimeError, + severity, }; let mut buf = String::new(); @@ -214,10 +223,11 @@ impl<'a> Renderer<'a> { use ven_pretty::DocAllocator; let line_col_region = self.line_info.convert_region(expect_region); + let severity = Severity::RuntimeError; let doc = self.alloc.stack([ self.alloc.text("This expectation crashed while running:"), - self.alloc.region(line_col_region), + self.alloc.region(line_col_region, severity), self.alloc.text("The crash reported this message:"), self.alloc.text(message), ]); @@ -226,7 +236,7 @@ impl<'a> Renderer<'a> { title: "EXPECT PANICKED".into(), doc, filename: self.filename.clone(), - severity: Severity::RuntimeError, + severity, }; let mut buf = String::new(); diff --git a/crates/reporting/src/error/parse.rs b/crates/reporting/src/error/parse.rs index e7a4050dfb..36dd105f89 100644 --- a/crates/reporting/src/error/parse.rs +++ b/crates/reporting/src/error/parse.rs @@ -60,25 +60,26 @@ fn to_syntax_report<'a>( ) -> Report<'a> { use SyntaxError::*; + let severity = Severity::RuntimeError; let report = |doc| Report { filename: filename.clone(), doc, title: "PARSE PROBLEM".to_string(), - severity: Severity::RuntimeError, + severity, }; match parse_problem { SyntaxError::ArgumentsBeforeEquals(region) => { let doc = alloc.stack([ alloc.reflow("Unexpected tokens in front of the `=` symbol:"), - alloc.region(lines.convert_region(*region)), + alloc.region(lines.convert_region(*region), severity), ]); Report { filename, doc, title: "PARSE PROBLEM".to_string(), - severity: Severity::RuntimeError, + severity, } } Unexpected(region) => { @@ -93,7 +94,7 @@ fn to_syntax_report<'a>( // context(alloc, &parse_problem.context_stack, "here"), alloc.text(":"), ]), - alloc.region(region), + alloc.region(region, severity), ]); report(doc) @@ -103,27 +104,27 @@ fn to_syntax_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I expected to reach the end of the file, but got stuck here:"), - alloc.region(region), + alloc.region(region, severity), ]); Report { filename, doc, title: "NOT END OF FILE".to_string(), - severity: Severity::RuntimeError, + severity, } } SyntaxError::Eof(region) => { let doc = alloc.stack([ alloc.reflow("End of Field"), - alloc.region(lines.convert_region(*region)), + alloc.region(lines.convert_region(*region), severity), ]); Report { filename, doc, title: "PARSE PROBLEM".to_string(), - severity: Severity::RuntimeError, + severity, } } SyntaxError::OutdentedTooFar => { @@ -133,7 +134,7 @@ fn to_syntax_report<'a>( filename, doc, title: "PARSE PROBLEM".to_string(), - severity: Severity::RuntimeError, + severity, } } Type(typ) => to_type_report(alloc, lines, filename, typ, Position::default()), @@ -182,7 +183,7 @@ fn to_expr_report<'a>( start: Position, ) -> Report<'a> { use roc_parse::parser::EExpr; - + let severity = Severity::RuntimeError; match parse_problem { EExpr::If(if_, pos) => to_if_report(alloc, lines, filename, context, if_, *pos), EExpr::When(when, pos) => to_when_report(alloc, lines, filename, context, when, *pos), @@ -201,7 +202,7 @@ fn to_expr_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a definition, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("Looks like you are trying to define a function. "), alloc.reflow("In roc, functions are always written as a lambda, like "), @@ -214,7 +215,7 @@ fn to_expr_report<'a>( filename, doc, title: "ARGUMENTS BEFORE EQUALS".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -320,6 +321,7 @@ fn to_expr_report<'a>( alloc.region_with_subregion( lines.convert_region(surroundings), lines.convert_region(region), + severity, ), alloc.concat(suggestion), ]); @@ -328,7 +330,7 @@ fn to_expr_report<'a>( filename, doc, title: "UNKNOWN OPERATOR".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -340,9 +342,10 @@ fn to_expr_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am very confused by this identifier:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ - alloc.reflow("Are you trying to qualify a name? I am execting something like "), + alloc + .reflow("Are you trying to qualify a name? I am expecting something like "), alloc.parser_suggestion("Json.Decode.string"), alloc.reflow(". Maybe you are trying to qualify a tag? Tags like "), alloc.parser_suggestion("Err"), @@ -354,7 +357,7 @@ fn to_expr_report<'a>( filename, doc, title: "WEIRD IDENTIFIER".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -428,7 +431,7 @@ fn to_expr_report<'a>( a_thing, alloc.reflow(", but I got stuck here:"), ]), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), expecting, ]); @@ -436,7 +439,7 @@ fn to_expr_report<'a>( filename, doc, title: title.to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -446,7 +449,7 @@ fn to_expr_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a definition, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("This definition is missing a final expression."), alloc.reflow(" A nested definition must be followed by"), @@ -464,7 +467,7 @@ fn to_expr_report<'a>( filename, doc, title: "MISSING FINAL EXPRESSION".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -483,7 +486,7 @@ fn to_expr_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("Whatever I am running into is confusing me a lot! "), alloc.reflow("Normally I can give fairly specific hints, "), @@ -495,7 +498,7 @@ fn to_expr_report<'a>( filename, doc, title: "SYNTAX PROBLEM".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -505,7 +508,7 @@ fn to_expr_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a definition, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("Looks like you are trying to define a function. "), alloc.reflow("In roc, functions are always written as a lambda, like "), @@ -518,7 +521,7 @@ fn to_expr_report<'a>( filename, doc, title: "ARGUMENTS BEFORE EQUALS".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -528,7 +531,7 @@ fn to_expr_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing an expression, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([alloc.reflow("Looks like you are trying to define a function. ")]), ]); @@ -536,7 +539,7 @@ fn to_expr_report<'a>( filename, doc, title: "BAD BACKPASSING ARROW".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -552,7 +555,7 @@ fn to_expr_report<'a>( alloc.reflow( r"I am partway through parsing a record builder, and I found an optional field:", ), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.reflow("Optional fields can only appear when you destructure a record."), ]); @@ -560,7 +563,7 @@ fn to_expr_report<'a>( filename, doc, title: "BAD RECORD BUILDER".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -572,7 +575,7 @@ fn to_expr_report<'a>( alloc.reflow( r"I am partway through parsing a record update, and I found a record builder field:", ), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.reflow("Record builders cannot be updated like records."), ]); @@ -580,7 +583,7 @@ fn to_expr_report<'a>( filename, doc, title: "BAD RECORD UPDATE".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -596,7 +599,8 @@ fn to_expr_report<'a>( let surroundings = Region::new(start, *pos); let region = LineColumnRegion::from_pos(lines.convert_pos(*pos)); - let snippet = alloc.region_with_subregion(lines.convert_region(surroundings), region); + let snippet = + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity); let doc = match context { Context::InNode(Node::Dbg, _, _) => alloc.stack([ @@ -646,7 +650,7 @@ fn to_expr_report<'a>( filename, doc, title: "INDENT ENDS AFTER EXPRESSION".to_string(), - severity: Severity::RuntimeError, + severity, } } EExpr::Expect(e_expect, _position) => { @@ -665,7 +669,7 @@ fn to_expr_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing an expression, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([alloc.reflow("TODO provide more context.")]), ]); @@ -673,7 +677,7 @@ fn to_expr_report<'a>( filename, doc, title: "TRAILING OPERATOR".to_string(), - severity: Severity::RuntimeError, + severity, } } EExpr::UnexpectedComma(pos) => { @@ -682,7 +686,7 @@ fn to_expr_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am trying to parse an expression, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([alloc.reflow("This comma in an invalid position.")]), ]); @@ -690,7 +694,7 @@ fn to_expr_report<'a>( filename, doc, title: "UNEXPECTED COMMA".to_string(), - severity: Severity::RuntimeError, + severity, } } _ => todo!("unhandled parse error: {:?}", parse_problem), @@ -708,9 +712,10 @@ fn to_record_report<'a>( let surroundings = Region::new(start, pos); let region = LineColumnRegion::from_pos(lines.convert_pos(pos)); + let severity = Severity::RuntimeError; let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a record, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([alloc.reflow("TODO provide more context.")]), ]); @@ -718,7 +723,7 @@ fn to_record_report<'a>( filename, doc, title: "RECORD PARSE PROBLEM".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -732,6 +737,8 @@ fn to_lambda_report<'a>( ) -> Report<'a> { use roc_parse::parser::EClosure; + let severity = Severity::RuntimeError; + match *parse_problem { EClosure::Arrow(pos) => match what_is_next(alloc.src_lines, lines.convert_pos(pos)) { Next::Token("=>") => { @@ -741,7 +748,7 @@ fn to_lambda_report<'a>( let doc = alloc.stack([ alloc .reflow(r"I am partway through parsing a function argument list, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I was expecting a "), alloc.parser_suggestion("->"), @@ -753,7 +760,7 @@ fn to_lambda_report<'a>( filename, doc, title: "WEIRD ARROW".to_string(), - severity: Severity::RuntimeError, + severity, } } _ => { @@ -763,7 +770,7 @@ fn to_lambda_report<'a>( let doc = alloc.stack([ alloc .reflow(r"I am partway through parsing a function argument list, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I was expecting a "), alloc.parser_suggestion("->"), @@ -775,7 +782,7 @@ fn to_lambda_report<'a>( filename, doc, title: "MISSING ARROW".to_string(), - severity: Severity::RuntimeError, + severity, } } }, @@ -788,7 +795,7 @@ fn to_lambda_report<'a>( let doc = alloc.stack([ alloc .reflow(r"I am partway through parsing a function argument list, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I was expecting a "), alloc.parser_suggestion("->"), @@ -800,7 +807,7 @@ fn to_lambda_report<'a>( filename, doc, title: "WEIRD ARROW".to_string(), - severity: Severity::RuntimeError, + severity, } } _ => { @@ -810,7 +817,7 @@ fn to_lambda_report<'a>( let doc = alloc.stack([ alloc .reflow(r"I am partway through parsing a function argument list, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I was expecting a "), alloc.parser_suggestion("->"), @@ -822,7 +829,7 @@ fn to_lambda_report<'a>( filename, doc, title: "MISSING ARROW".to_string(), - severity: Severity::RuntimeError, + severity, } } }, @@ -835,7 +842,7 @@ fn to_lambda_report<'a>( let doc = alloc.stack([ alloc .reflow(r"I am partway through parsing a function argument list, but I got stuck at this comma:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I was expecting an argument pattern before this, "), alloc.reflow("so try adding an argument before the comma and see if that helps?"), @@ -846,7 +853,7 @@ fn to_lambda_report<'a>( filename, doc, title: "UNFINISHED ARGUMENT LIST".to_string(), - severity: Severity::RuntimeError, + severity, } } _ => { @@ -856,7 +863,7 @@ fn to_lambda_report<'a>( let doc = alloc.stack([ alloc .reflow(r"I am partway through parsing a function argument list, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I was expecting an argument pattern before this, "), alloc.reflow("so try adding an argument and see if that helps?"), @@ -867,7 +874,7 @@ fn to_lambda_report<'a>( filename, doc, title: "MISSING ARROW".to_string(), - severity: Severity::RuntimeError, + severity, } } }, @@ -934,13 +941,14 @@ fn to_unfinished_lambda_report<'a>( ) -> Report<'a> { let surroundings = Region::new(start, pos); let region = LineColumnRegion::from_pos(lines.convert_pos(pos)); + let severity = Severity::RuntimeError; let doc = alloc.stack([ alloc.concat([ alloc.reflow(r"I was partway through parsing a "), alloc.reflow(r" function, but I got stuck here:"), ]), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), message, ]); @@ -948,7 +956,7 @@ fn to_unfinished_lambda_report<'a>( filename, doc, title: "UNFINISHED FUNCTION".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -961,6 +969,7 @@ fn to_str_report<'a>( start: Position, ) -> Report<'a> { use roc_parse::parser::EString; + let severity = Severity::RuntimeError; match *parse_problem { EString::Open(_pos) => unreachable!("another branch would be taken"), @@ -992,6 +1001,7 @@ fn to_str_report<'a>( alloc.region_with_subregion( lines.convert_region(surroundings), lines.convert_region(region), + severity, ), alloc.concat([ alloc.reflow(r"This is not an escape sequence I recognize."), @@ -1014,7 +1024,7 @@ fn to_str_report<'a>( filename, doc, title: "WEIRD ESCAPE".to_string(), - severity: Severity::RuntimeError, + severity, } } EString::CodePtOpen(pos) | EString::CodePtEnd(pos) => { @@ -1025,7 +1035,7 @@ fn to_str_report<'a>( alloc.reflow( r"I am partway through parsing a unicode code point, but I got stuck here:", ), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"I was expecting a hexadecimal number, like "), alloc.parser_suggestion("\\u(1100)"), @@ -1040,7 +1050,7 @@ fn to_str_report<'a>( filename, doc, title: "WEIRD CODE POINT".to_string(), - severity: Severity::RuntimeError, + severity, } } EString::FormatEnd(pos) => { @@ -1049,7 +1059,7 @@ fn to_str_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I cannot find the end of this format expression:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"You could change it to something like "), alloc.parser_suggestion("\"The count is $(count)\""), @@ -1061,7 +1071,7 @@ fn to_str_report<'a>( filename, doc, title: "ENDLESS FORMAT".to_string(), - severity: Severity::RuntimeError, + severity, } } EString::EndlessSingleQuote(pos) => { @@ -1070,7 +1080,7 @@ fn to_str_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I cannot find the end of this scalar literal (character literal):"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"You could change it to something like "), alloc.parser_suggestion("'a'"), @@ -1084,7 +1094,7 @@ fn to_str_report<'a>( filename, doc, title: "ENDLESS SCALAR".to_string(), - severity: Severity::RuntimeError, + severity, } } EString::InvalidSingleQuote(e, pos) => { @@ -1098,7 +1108,7 @@ fn to_str_report<'a>( alloc.reflow(r"I am part way through parsing this scalar literal (character literal), "), alloc.reflow(r"but it appears to be empty - which is not a valid scalar."), ]), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"You could change it to something like "), alloc.parser_suggestion("'a'"), @@ -1115,7 +1125,7 @@ fn to_str_report<'a>( alloc.reflow(r"I am part way through parsing this scalar literal (character literal), "), alloc.reflow(r"but it's too long to fit in a U32 so it's not a valid scalar."), ]), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"You could change it to something like "), alloc.parser_suggestion("'a'"), @@ -1133,7 +1143,7 @@ fn to_str_report<'a>( alloc.reflow("but I encountered a string interpolation like \"$(this)\","), alloc.reflow("which is not allowed in single-quote literals."), ]), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"You could change it to something like "), alloc.parser_suggestion("'a'"), @@ -1150,7 +1160,7 @@ fn to_str_report<'a>( filename, doc, title: "INVALID SCALAR".to_string(), - severity: Severity::RuntimeError, + severity, } } EString::EndlessSingleLine(pos) => { @@ -1159,7 +1169,7 @@ fn to_str_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I cannot find the end of this string:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"You could change it to something like "), alloc.parser_suggestion("\"to be or not to be\""), @@ -1173,7 +1183,7 @@ fn to_str_report<'a>( filename, doc, title: "ENDLESS STRING".to_string(), - severity: Severity::RuntimeError, + severity, } } EString::ExpectedDoubleQuoteGotSingleQuote(pos) => { @@ -1182,7 +1192,7 @@ fn to_str_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I was expecting to see a string here, but I got a scalar literal."), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"You could change it to something like "), alloc.parser_suggestion("\"to be or not to be\""), @@ -1197,7 +1207,7 @@ fn to_str_report<'a>( filename, doc, title: "EXPECTED STRING".to_string(), - severity: Severity::RuntimeError, + severity, } } EString::EndlessMultiLine(pos) => { @@ -1206,7 +1216,7 @@ fn to_str_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I cannot find the end of this block string:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"You could change it to something like "), alloc.parser_suggestion("\"\"\"to be or not to be\"\"\""), @@ -1220,7 +1230,7 @@ fn to_str_report<'a>( filename, doc, title: "ENDLESS STRING".to_string(), - severity: Severity::RuntimeError, + severity, } } EString::MultilineInsufficientIndent(pos) => { @@ -1229,7 +1239,7 @@ fn to_str_report<'a>( let doc = alloc.stack([ alloc.reflow(r"This multiline string is not sufficiently indented:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"Lines in a multi-line string must be indented at least as "), alloc.reflow("much as the beginning \"\"\". This extra indentation is automatically removed "), @@ -1241,7 +1251,7 @@ fn to_str_report<'a>( filename, doc, title: "INSUFFICIENT INDENT IN MULTI-LINE STRING".to_string(), - severity: Severity::RuntimeError, + severity, } } } @@ -1255,6 +1265,7 @@ fn to_expr_in_parens_report<'a>( start: Position, ) -> Report<'a> { use roc_parse::parser::EInParens; + let severity = Severity::RuntimeError; match *parse_problem { EInParens::Space(error, pos) => to_space_report(alloc, lines, filename, &error, pos), @@ -1272,7 +1283,7 @@ fn to_expr_in_parens_report<'a>( let doc = alloc.stack([ alloc.reflow("I am partway through parsing a parenthesized expression or tuple:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"I was expecting to see an expression next."), alloc.reflow(r"Note, Roc doesn't use '()' as a null type."), @@ -1283,7 +1294,7 @@ fn to_expr_in_parens_report<'a>( filename, doc, title: "EMPTY PARENTHESES".to_string(), - severity: Severity::RuntimeError, + severity, } } EInParens::End(pos) => { @@ -1293,7 +1304,7 @@ fn to_expr_in_parens_report<'a>( let doc = alloc.stack([ alloc .reflow("I am partway through parsing a record pattern, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow( r"I was expecting to see a closing parenthesis next, so try adding a ", @@ -1307,7 +1318,7 @@ fn to_expr_in_parens_report<'a>( filename, doc, title: "UNFINISHED PARENTHESES".to_string(), - severity: Severity::RuntimeError, + severity, } } EInParens::Open(pos) => { @@ -1318,7 +1329,7 @@ fn to_expr_in_parens_report<'a>( alloc.reflow( r"I just started parsing an expression in parentheses, but I got stuck here:", ), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"An expression in parentheses looks like "), alloc.parser_suggestion("(32)"), @@ -1332,7 +1343,7 @@ fn to_expr_in_parens_report<'a>( filename, doc, title: "UNFINISHED PARENTHESES".to_string(), - severity: Severity::RuntimeError, + severity, } } } @@ -1348,6 +1359,7 @@ fn to_list_report<'a>( ) -> Report<'a> { use roc_parse::parser::EList; + let severity = Severity::RuntimeError; match *parse_problem { EList::Space(error, pos) => to_space_report(alloc, lines, filename, &error, pos), @@ -1370,7 +1382,11 @@ fn to_list_report<'a>( alloc.reflow( r"I am partway through started parsing a list, but I got stuck here:", ), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion( + lines.convert_region(surroundings), + region, + severity, + ), alloc.concat([ alloc .reflow(r"I was expecting to see a list entry before this comma, "), @@ -1382,7 +1398,7 @@ fn to_list_report<'a>( filename, doc, title: "UNFINISHED LIST".to_string(), - severity: Severity::RuntimeError, + severity, } } _ => { @@ -1393,7 +1409,11 @@ fn to_list_report<'a>( alloc.reflow( r"I am partway through started parsing a list, but I got stuck here:", ), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion( + lines.convert_region(surroundings), + region, + severity, + ), alloc.concat([ alloc.reflow( r"I was expecting to see a closing square bracket before this, ", @@ -1415,7 +1435,7 @@ fn to_list_report<'a>( filename, doc, title: "UNFINISHED LIST".to_string(), - severity: Severity::RuntimeError, + severity, } } } @@ -1462,6 +1482,7 @@ fn to_import_report<'a>( ) -> Report<'a> { use roc_parse::parser::EImport::*; use roc_parse::parser::EImportParams; + let severity = Severity::RuntimeError; match parse_problem { Import(_pos) => unreachable!("another branch would be taken"), @@ -1530,7 +1551,7 @@ fn to_import_report<'a>( let doc = alloc.stack([ alloc.reflow("I was partway through parsing module params, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.reflow("This looks like a record builder field, but those are not allowed in module params."), ]); @@ -1538,7 +1559,7 @@ fn to_import_report<'a>( filename, doc, title: "RECORD BUILDER IN MODULE PARAMS".to_string(), - severity: Severity::RuntimeError, + severity, } } Params(EImportParams::RecordUpdateFound(region), _) => { @@ -1547,7 +1568,7 @@ fn to_import_report<'a>( let doc = alloc.stack([ alloc.reflow("I was partway through parsing module params, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.reflow("It looks like you're trying to update a record, but module params require a standalone record literal."), ]); @@ -1555,7 +1576,7 @@ fn to_import_report<'a>( filename, doc, title: "RECORD UPDATE IN MODULE PARAMS".to_string(), - severity: Severity::RuntimeError, + severity, } } IndentAlias(pos) | Alias(pos) => to_unfinished_import_report( @@ -1576,7 +1597,7 @@ fn to_import_report<'a>( let doc = alloc.stack([ alloc.reflow(r"This import is using a lowercase alias:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.reflow(r"Module names and aliases must start with an uppercase letter."), ]); @@ -1584,7 +1605,7 @@ fn to_import_report<'a>( filename, doc, title: "LOWERCASE ALIAS".to_string(), - severity: Severity::RuntimeError, + severity, } } ExposingListStart(pos) => to_unfinished_import_report( @@ -1608,7 +1629,7 @@ fn to_import_report<'a>( let doc = alloc.stack([ alloc .reflow(r"I'm partway through parsing an exposing list, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.reflow(r"I was expecting a type, value, or function name next, like:"), alloc .parser_suggestion("import Svg exposing [Path, arc, rx]") @@ -1619,7 +1640,7 @@ fn to_import_report<'a>( filename, doc, title: "WEIRD EXPOSING".to_string(), - severity: Severity::RuntimeError, + severity, } } IndentIngestedName(pos) | IngestedName(pos) => to_unfinished_import_report( @@ -1665,6 +1686,7 @@ fn to_unfinished_import_report<'a>( ) -> Report<'a> { let surroundings = Region::new(start, pos); let region = LineColumnRegion::from_pos(lines.convert_pos(pos)); + let severity = Severity::RuntimeError; let doc = alloc.stack([ alloc.concat([ @@ -1672,7 +1694,7 @@ fn to_unfinished_import_report<'a>( alloc.keyword("import"), alloc.reflow(r", but I got stuck here:"), ]), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), message, ]); @@ -1680,7 +1702,7 @@ fn to_unfinished_import_report<'a>( filename, doc, title: "UNFINISHED IMPORT".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -1778,6 +1800,7 @@ fn to_unfinished_if_report<'a>( ) -> Report<'a> { let surroundings = Region::new(start, pos); let region = LineColumnRegion::from_pos(lines.convert_pos(pos)); + let severity = Severity::RuntimeError; let doc = alloc.stack([ alloc.concat([ @@ -1785,7 +1808,7 @@ fn to_unfinished_if_report<'a>( alloc.keyword("if"), alloc.reflow(r" expression, but I got stuck here:"), ]), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), message, ]); @@ -1793,7 +1816,7 @@ fn to_unfinished_if_report<'a>( filename, doc, title: "UNFINISHED IF".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -1806,6 +1829,7 @@ fn to_when_report<'a>( start: Position, ) -> Report<'a> { use roc_parse::parser::EWhen; + let severity = Severity::RuntimeError; match *parse_problem { EWhen::IfGuard(nested, pos) => { @@ -1818,7 +1842,11 @@ fn to_when_report<'a>( alloc.reflow( r"I just started parsing an if guard, but there is no guard condition:", ), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion( + lines.convert_region(surroundings), + region, + severity, + ), alloc.concat([alloc.reflow("Try adding an expression before the arrow!")]), ]); @@ -1826,7 +1854,7 @@ fn to_when_report<'a>( filename, doc, title: "IF GUARD NO CONDITION".to_string(), - severity: Severity::RuntimeError, + severity, } } _ => to_expr_report( @@ -1849,7 +1877,7 @@ fn to_when_report<'a>( alloc.keyword("when"), alloc.reflow(r" expression, but got stuck here:"), ]), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([alloc.reflow("I was expecting to see an arrow next.")]), note_for_when_indent_error(alloc), ]); @@ -1858,7 +1886,7 @@ fn to_when_report<'a>( filename, doc, title: "MISSING ARROW".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -1993,8 +2021,8 @@ fn to_unfinished_when_report<'a>( ) -> Report<'a> { match what_is_next(alloc.src_lines, lines.convert_pos(pos)) { Next::Token("->") => to_unexpected_arrow_report(alloc, lines, filename, pos, start), - _ => { + let severity = Severity::RuntimeError; let surroundings = Region::new(start, pos); let region = LineColumnRegion::from_pos(lines.convert_pos(pos)); @@ -2004,7 +2032,7 @@ fn to_unfinished_when_report<'a>( alloc.keyword("when"), alloc.reflow(r" expression, but I got stuck here:"), ]), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), message, note_for_when_error(alloc), ]); @@ -2013,7 +2041,7 @@ fn to_unfinished_when_report<'a>( filename, doc, title: "UNFINISHED WHEN".to_string(), - severity: Severity::RuntimeError, + severity, } } } @@ -2028,6 +2056,7 @@ fn to_unexpected_arrow_report<'a>( ) -> Report<'a> { let surroundings = Region::new(start, pos); let region = Region::new(pos, pos.bump_column(2)); + let severity = Severity::RuntimeError; let doc = alloc.stack([ alloc.concat([ @@ -2038,6 +2067,7 @@ fn to_unexpected_arrow_report<'a>( alloc.region_with_subregion( lines.convert_region(surroundings), lines.convert_region(region), + severity, ), alloc.concat([ alloc.reflow(r"It makes sense to see arrows around here, "), @@ -2053,7 +2083,7 @@ fn to_unexpected_arrow_report<'a>( filename, doc, title: "UNEXPECTED ARROW".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -2113,6 +2143,7 @@ fn to_pattern_report<'a>( start: Position, ) -> Report<'a> { use roc_parse::parser::EPattern; + let severity = Severity::RuntimeError; match parse_problem { EPattern::Start(pos) => { @@ -2121,7 +2152,7 @@ fn to_pattern_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I just started parsing a pattern, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.note("I may be confused by indentation"), ]); @@ -2129,7 +2160,7 @@ fn to_pattern_report<'a>( filename, doc, title: "UNFINISHED PATTERN".to_string(), - severity: Severity::RuntimeError, + severity, } } EPattern::Record(record, pos) => to_precord_report(alloc, lines, filename, record, *pos), @@ -2153,6 +2184,8 @@ fn to_precord_report<'a>( ) -> Report<'a> { use roc_parse::parser::PRecord; + let severity = Severity::RuntimeError; + match *parse_problem { PRecord::Open(pos) => match what_is_next(alloc.src_lines, lines.convert_pos(pos)) { Next::Keyword(keyword) => { @@ -2161,7 +2194,7 @@ fn to_precord_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I just started parsing a record pattern, but I got stuck on this field name:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"Looks like you are trying to use "), alloc.keyword(keyword), @@ -2173,7 +2206,7 @@ fn to_precord_report<'a>( filename, doc, title: "UNFINISHED RECORD PATTERN".to_string(), - severity: Severity::RuntimeError, + severity, } } _ => { @@ -2182,7 +2215,11 @@ fn to_precord_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I just started parsing a record pattern, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion( + lines.convert_region(surroundings), + region, + severity, + ), record_patterns_look_like(alloc), ]); @@ -2190,7 +2227,7 @@ fn to_precord_report<'a>( filename, doc, title: "UNFINISHED RECORD PATTERN".to_string(), - severity: Severity::RuntimeError, + severity, } } }, @@ -2203,7 +2240,7 @@ fn to_precord_report<'a>( Next::Other(Some(c)) if c.is_alphabetic() => { let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a record pattern, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow( r"I was expecting to see a colon, question mark, comma or closing curly brace.", @@ -2215,13 +2252,13 @@ fn to_precord_report<'a>( filename, doc, title: "UNFINISHED RECORD PATTERN".to_string(), - severity: Severity::RuntimeError, + severity, } } _ => { let doc = alloc.stack([ alloc.reflow("I am partway through parsing a record pattern, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow( r"I was expecting to see a closing curly brace before this, so try adding a ", @@ -2235,7 +2272,7 @@ fn to_precord_report<'a>( filename, doc, title: "UNFINISHED RECORD PATTERN".to_string(), - severity: Severity::RuntimeError, + severity, } } } @@ -2248,7 +2285,7 @@ fn to_precord_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I just started parsing a record pattern, but I got stuck on this field name:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"Looks like you are trying to use "), alloc.keyword(keyword), @@ -2260,7 +2297,7 @@ fn to_precord_report<'a>( filename, doc, title: "UNFINISHED RECORD PATTERN".to_string(), - severity: Severity::RuntimeError, + severity, } } Next::Other(Some(',')) => todo!(), @@ -2271,7 +2308,7 @@ fn to_precord_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a record pattern, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"I was expecting to see another record field defined next, so I am looking for a name like "), alloc.parser_suggestion("userName"), @@ -2285,7 +2322,7 @@ fn to_precord_report<'a>( filename, doc, title: "PROBLEM IN RECORD PATTERN".to_string(), - severity: Severity::RuntimeError, + severity, } } }, @@ -2323,6 +2360,7 @@ fn to_plist_report<'a>( parse_problem: &PList<'a>, start: Position, ) -> Report<'a> { + let severity = Severity::RuntimeError; match *parse_problem { PList::Open(pos) => { let surroundings = Region::new(start, pos); @@ -2330,7 +2368,7 @@ fn to_plist_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I just started parsing a list pattern, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), list_patterns_look_like(alloc), ]); @@ -2338,7 +2376,7 @@ fn to_plist_report<'a>( filename, doc, title: "UNFINISHED LIST PATTERN".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -2347,7 +2385,7 @@ fn to_plist_report<'a>( let region = LineColumnRegion::from_pos(lines.convert_pos(pos)); let doc = alloc.stack([ alloc.reflow("I am partway through parsing a list pattern, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow( r"I was expecting to see a closing square brace before this, so try adding a ", @@ -2360,7 +2398,7 @@ fn to_plist_report<'a>( filename, doc, title: "UNFINISHED LIST PATTERN".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -2369,7 +2407,7 @@ fn to_plist_report<'a>( let region = LineColumnRegion::from_pos(lines.convert_pos(pos)); let doc = alloc.stack([ alloc.reflow("It looks like you may trying to write a list rest pattern, but it's not the form I expect:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow( r"List rest patterns, which match zero or more elements in a list, are denoted with ", @@ -2382,7 +2420,7 @@ fn to_plist_report<'a>( filename, doc, title: "INCORRECT REST PATTERN".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -2401,9 +2439,11 @@ fn to_pattern_in_parens_report<'a>( ) -> Report<'a> { use roc_parse::parser::PInParens; + let severity = Severity::RuntimeError; + match *parse_problem { PInParens::Open(pos) => { - // `Open` case is for exhaustiveness, this case shouldn not be reachable practically. + // `Open` case is for exhaustiveness, this case shouldn't not be reachable practically. let surroundings = Region::new(start, pos); let region = LineColumnRegion::from_pos(lines.convert_pos(pos)); @@ -2411,7 +2451,7 @@ fn to_pattern_in_parens_report<'a>( alloc.reflow( r"I just started parsing a pattern in parentheses, but I got stuck here:", ), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"A pattern in parentheses looks like "), alloc.parser_suggestion("(Ok 32)"), @@ -2425,17 +2465,18 @@ fn to_pattern_in_parens_report<'a>( filename, doc, title: "UNFINISHED PARENTHESES".to_string(), - severity: Severity::RuntimeError, + severity, } } PInParens::Empty(pos) => { let surroundings = Region::new(start, pos); let region = LineColumnRegion::from_pos(lines.convert_pos(pos)); + let severity = Severity::RuntimeError; let doc = alloc.stack([ alloc.reflow("I am partway through parsing a parenthesized pattern or tuple:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"I was expecting to see a pattern next."), alloc.reflow(r"Note, Roc doesn't use '()' as a null type."), @@ -2446,7 +2487,7 @@ fn to_pattern_in_parens_report<'a>( filename, doc, title: "EMPTY PARENTHESES".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -2456,7 +2497,7 @@ fn to_pattern_in_parens_report<'a>( let doc = alloc.stack([ alloc.reflow("I am partway through parsing a pattern in parentheses, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow( r"I was expecting to see a closing parenthesis before this, so try adding a ", @@ -2470,7 +2511,7 @@ fn to_pattern_in_parens_report<'a>( filename, doc, title: "UNFINISHED PARENTHESES".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -2488,17 +2529,18 @@ fn to_malformed_number_literal_report<'a>( ) -> Report<'a> { let surroundings = Region::new(start, start); let region = LineColumnRegion::from_pos(lines.convert_pos(start)); + let severity = Severity::RuntimeError; let doc = alloc.stack([ alloc.reflow(r"This number literal is malformed:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), ]); Report { filename, doc, title: "INVALID NUMBER LITERAL".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -2510,6 +2552,7 @@ fn to_type_report<'a>( start: Position, ) -> Report<'a> { use roc_parse::parser::EType; + let severity = Severity::RuntimeError; match parse_problem { EType::TRecord(record, pos) => to_trecord_report(alloc, lines, filename, record, *pos), @@ -2530,7 +2573,7 @@ fn to_type_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I just started parsing a function argument type, but I encountered two commas in a row:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([alloc.reflow("Try removing one of them.")]), ]); @@ -2538,7 +2581,7 @@ fn to_type_report<'a>( filename, doc, title: "DOUBLE COMMA".to_string(), - severity: Severity::RuntimeError, + severity, } } _ => todo!(), @@ -2551,7 +2594,7 @@ fn to_type_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I just started parsing a type, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"I am expecting a type next, like "), alloc.parser_suggestion("Bool"), @@ -2565,7 +2608,7 @@ fn to_type_report<'a>( filename, doc, title: "UNFINISHED TYPE".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -2575,7 +2618,7 @@ fn to_type_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I just started parsing a type, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.note("I may be confused by indentation"), ]); @@ -2583,7 +2626,7 @@ fn to_type_report<'a>( filename, doc, title: "UNFINISHED TYPE".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -2593,7 +2636,7 @@ fn to_type_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a type, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.note("I may be confused by indentation"), ]); @@ -2601,7 +2644,7 @@ fn to_type_report<'a>( filename, doc, title: "UNFINISHED TYPE".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -2611,7 +2654,7 @@ fn to_type_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I just started parsing an inline type alias, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.note("I may be confused by indentation"), ]); @@ -2619,7 +2662,7 @@ fn to_type_report<'a>( filename, doc, title: "UNFINISHED INLINE ALIAS".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -2629,14 +2672,14 @@ fn to_type_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am expecting a type variable, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), ]); Report { filename, doc, title: "BAD TYPE VARIABLE".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -2653,6 +2696,8 @@ fn to_trecord_report<'a>( ) -> Report<'a> { use roc_parse::parser::ETypeRecord; + let severity = Severity::RuntimeError; + match *parse_problem { ETypeRecord::Open(pos) => match what_is_next(alloc.src_lines, lines.convert_pos(pos)) { Next::Keyword(keyword) => { @@ -2661,7 +2706,7 @@ fn to_trecord_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I just started parsing a record type, but I got stuck on this field name:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"Looks like you are trying to use "), alloc.keyword(keyword), @@ -2673,7 +2718,7 @@ fn to_trecord_report<'a>( filename, doc, title: "UNFINISHED RECORD TYPE".to_string(), - severity: Severity::RuntimeError, + severity, } } _ => { @@ -2682,7 +2727,11 @@ fn to_trecord_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I just started parsing a record type, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion( + lines.convert_region(surroundings), + region, + severity, + ), alloc.concat([ alloc.reflow(r"Record types look like "), alloc.parser_suggestion("{ name : String, age : Int },"), @@ -2694,7 +2743,7 @@ fn to_trecord_report<'a>( filename, doc, title: "UNFINISHED RECORD TYPE".to_string(), - severity: Severity::RuntimeError, + severity, } } }, @@ -2707,7 +2756,7 @@ fn to_trecord_report<'a>( Next::Other(Some(c)) if c.is_alphabetic() => { let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a record type, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow( r"I was expecting to see a colon, question mark, comma or closing curly brace.", @@ -2719,13 +2768,13 @@ fn to_trecord_report<'a>( filename, doc, title: "UNFINISHED RECORD TYPE".to_string(), - severity: Severity::RuntimeError, + severity, } } _ => { let doc = alloc.stack([ alloc.reflow("I am partway through parsing a record type, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow( r"I was expecting to see a closing curly brace before this, so try adding a ", @@ -2739,7 +2788,7 @@ fn to_trecord_report<'a>( filename, doc, title: "UNFINISHED RECORD TYPE".to_string(), - severity: Severity::RuntimeError, + severity, } } } @@ -2752,7 +2801,7 @@ fn to_trecord_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I just started parsing a record type, but I got stuck on this field name:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"Looks like you are trying to use "), alloc.keyword(keyword), @@ -2764,7 +2813,7 @@ fn to_trecord_report<'a>( filename, doc, title: "UNFINISHED RECORD TYPE".to_string(), - severity: Severity::RuntimeError, + severity, } } Next::Other(Some(',')) => todo!(), @@ -2775,7 +2824,7 @@ fn to_trecord_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a record type, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"I was expecting to see another record field defined next, so I am looking for a name like "), alloc.parser_suggestion("userName"), @@ -2789,7 +2838,7 @@ fn to_trecord_report<'a>( filename, doc, title: "PROBLEM IN RECORD TYPE".to_string(), - severity: Severity::RuntimeError, + severity, } } }, @@ -2809,7 +2858,7 @@ fn to_trecord_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I just started parsing a record type, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"Record types look like "), alloc.parser_suggestion("{ name : String, age : Int },"), @@ -2822,7 +2871,7 @@ fn to_trecord_report<'a>( filename, doc, title: "UNFINISHED RECORD TYPE".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -2836,7 +2885,7 @@ fn to_trecord_report<'a>( alloc.reflow( "I am partway through parsing a record type, but I got stuck here:", ), - alloc.region_with_subregion(surroundings, region), + alloc.region_with_subregion(surroundings, region, severity), alloc.concat([ alloc.reflow("I need this curly brace to be indented more. Try adding more spaces before it!"), ]), @@ -2846,7 +2895,7 @@ fn to_trecord_report<'a>( filename, doc, title: "NEED MORE INDENTATION".to_string(), - severity: Severity::RuntimeError, + severity, } } None => { @@ -2857,7 +2906,11 @@ fn to_trecord_report<'a>( alloc.reflow( r"I am partway through parsing a record type, but I got stuck here:", ), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion( + lines.convert_region(surroundings), + region, + severity, + ), alloc.concat([ alloc.reflow("I was expecting to see a closing curly "), alloc.reflow("brace before this, so try adding a "), @@ -2871,7 +2924,7 @@ fn to_trecord_report<'a>( filename, doc, title: "UNFINISHED RECORD TYPE".to_string(), - severity: Severity::RuntimeError, + severity, } } } @@ -2898,6 +2951,8 @@ fn to_ttag_union_report<'a>( ) -> Report<'a> { use roc_parse::parser::ETypeTagUnion; + let severity = Severity::RuntimeError; + match *parse_problem { ETypeTagUnion::Open(pos) => match what_is_next(alloc.src_lines, lines.convert_pos(pos)) { Next::Keyword(keyword) => { @@ -2906,7 +2961,7 @@ fn to_ttag_union_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I just started parsing a tag union, but I got stuck on this field name:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"Looks like you are trying to use "), alloc.keyword(keyword), @@ -2918,7 +2973,7 @@ fn to_ttag_union_report<'a>( filename, doc, title: "UNFINISHED TAG UNION TYPE".to_string(), - severity: Severity::RuntimeError, + severity, } } Next::Other(Some(c)) if c.is_alphabetic() => { @@ -2931,7 +2986,11 @@ fn to_ttag_union_report<'a>( alloc.reflow( r"I am partway through parsing a tag union type, but I got stuck here:", ), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion( + lines.convert_region(surroundings), + region, + severity, + ), alloc.reflow(r"I was expecting to see a tag name."), hint_for_tag_name(alloc), ]); @@ -2940,7 +2999,7 @@ fn to_ttag_union_report<'a>( filename, doc, title: "WEIRD TAG NAME".to_string(), - severity: Severity::RuntimeError, + severity, } } _ => { @@ -2949,7 +3008,11 @@ fn to_ttag_union_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I just started parsing a tag union type, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion( + lines.convert_region(surroundings), + region, + severity, + ), alloc.concat([ alloc.reflow(r"Tag unions look like "), alloc.parser_suggestion("[Many I64, None],"), @@ -2961,7 +3024,7 @@ fn to_ttag_union_report<'a>( filename, doc, title: "UNFINISHED TAG UNION TYPE".to_string(), - severity: Severity::RuntimeError, + severity, } } }, @@ -2978,7 +3041,11 @@ fn to_ttag_union_report<'a>( alloc.reflow( r"I am partway through parsing a tag union type, but I got stuck here:", ), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion( + lines.convert_region(surroundings), + region, + severity, + ), alloc.reflow(r"I was expecting to see a tag name."), hint_for_tag_name(alloc), ]); @@ -2987,13 +3054,13 @@ fn to_ttag_union_report<'a>( filename, doc, title: "WEIRD TAG NAME".to_string(), - severity: Severity::RuntimeError, + severity, } } _ => { let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a tag union type, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow( r"I was expecting to see a closing square bracket before this, so try adding a ", @@ -3007,7 +3074,7 @@ fn to_ttag_union_report<'a>( filename, doc, title: "UNFINISHED TAG UNION TYPE".to_string(), - severity: Severity::RuntimeError, + severity, } } } @@ -3028,6 +3095,8 @@ fn to_tinparens_report<'a>( ) -> Report<'a> { use roc_parse::parser::ETypeInParens; + let severity = Severity::RuntimeError; + match *parse_problem { ETypeInParens::Open(pos) => { match what_is_next(alloc.src_lines, lines.convert_pos(pos)) { @@ -3037,7 +3106,7 @@ fn to_tinparens_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I just saw an open parenthesis, so I was expecting to see a type next."), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"Something like "), alloc.parser_suggestion("(List Person)"), @@ -3050,7 +3119,7 @@ fn to_tinparens_report<'a>( filename, doc, title: "UNFINISHED PARENTHESES".to_string(), - severity: Severity::RuntimeError, + severity, } } Next::Other(Some(c)) if c.is_alphabetic() => { @@ -3063,7 +3132,7 @@ fn to_tinparens_report<'a>( alloc.reflow( r"I am partway through parsing a type in parentheses, but I got stuck here:", ), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.reflow(r"I was expecting to see a tag name."), hint_for_tag_name(alloc), ]); @@ -3072,7 +3141,7 @@ fn to_tinparens_report<'a>( filename, doc, title: "WEIRD TAG NAME".to_string(), - severity: Severity::RuntimeError, + severity, } } _ => { @@ -3083,7 +3152,11 @@ fn to_tinparens_report<'a>( alloc.reflow( r"I just started parsing a type in parentheses, but I got stuck here:", ), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion( + lines.convert_region(surroundings), + region, + severity, + ), alloc.concat([ alloc.reflow(r"Tag unions look like "), alloc.parser_suggestion("[Many I64, None],"), @@ -3095,7 +3168,7 @@ fn to_tinparens_report<'a>( filename, doc, title: "UNFINISHED PARENTHESES".to_string(), - severity: Severity::RuntimeError, + severity, } } } @@ -3107,7 +3180,7 @@ fn to_tinparens_report<'a>( let doc = alloc.stack([ alloc.reflow("I am partway through parsing a parenthesized type:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"I was expecting to see an expression next."), alloc.reflow(r"Note, Roc doesn't use '()' as a null type."), @@ -3118,7 +3191,7 @@ fn to_tinparens_report<'a>( filename, doc, title: "EMPTY PARENTHESES".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3135,7 +3208,7 @@ fn to_tinparens_report<'a>( alloc.reflow( r"I am partway through parsing a type in parentheses, but I got stuck here:", ), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.reflow(r"I was expecting to see a tag name."), hint_for_tag_name(alloc), ]); @@ -3144,13 +3217,13 @@ fn to_tinparens_report<'a>( filename, doc, title: "WEIRD TAG NAME".to_string(), - severity: Severity::RuntimeError, + severity, } } _ => { let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a type in parentheses, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow( r"I was expecting to see a closing parenthesis before this, so try adding a ", @@ -3164,7 +3237,7 @@ fn to_tinparens_report<'a>( filename, doc, title: "UNFINISHED PARENTHESES".to_string(), - severity: Severity::RuntimeError, + severity, } } } @@ -3179,7 +3252,7 @@ fn to_tinparens_report<'a>( let doc = alloc.stack([ alloc .reflow(r"I just started parsing a type in parentheses, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow(r"Tag unions look like "), alloc.parser_suggestion("[Many I64, None],"), @@ -3192,7 +3265,7 @@ fn to_tinparens_report<'a>( filename, doc, title: "UNFINISHED PARENTHESES".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3206,7 +3279,7 @@ fn to_tinparens_report<'a>( alloc.reflow( "I am partway through parsing a type in parentheses, but I got stuck here:", ), - alloc.region_with_subregion(surroundings, region), + alloc.region_with_subregion(surroundings, region, severity), alloc.concat([ alloc.reflow("I need this parenthesis to be indented more. Try adding more spaces before it!"), ]), @@ -3216,7 +3289,7 @@ fn to_tinparens_report<'a>( filename, doc, title: "NEED MORE INDENTATION".to_string(), - severity: Severity::RuntimeError, + severity, } } None => { @@ -3227,7 +3300,7 @@ fn to_tinparens_report<'a>( alloc.reflow( r"I am partway through parsing a type in parentheses, but I got stuck here:", ), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I was expecting to see a parenthesis "), alloc.reflow("before this, so try adding a "), @@ -3241,7 +3314,7 @@ fn to_tinparens_report<'a>( filename, doc, title: "UNFINISHED PARENTHESES".to_string(), - severity: Severity::RuntimeError, + severity, } } } @@ -3259,6 +3332,7 @@ fn to_tapply_report<'a>( _start: Position, ) -> Report<'a> { use roc_parse::parser::ETypeApply; + let severity = Severity::RuntimeError; match *parse_problem { ETypeApply::DoubleDot(pos) => { @@ -3266,7 +3340,7 @@ fn to_tapply_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I encountered two dots in a row:"), - alloc.region(region), + alloc.region(region, severity), alloc.concat([alloc.reflow("Try removing one of them.")]), ]); @@ -3274,7 +3348,7 @@ fn to_tapply_report<'a>( filename, doc, title: "DOUBLE DOT".to_string(), - severity: Severity::RuntimeError, + severity, } } ETypeApply::TrailingDot(pos) => { @@ -3282,7 +3356,7 @@ fn to_tapply_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I encountered a dot with nothing after it:"), - alloc.region(region), + alloc.region(region, severity), alloc.concat([ alloc.reflow("Dots are used to refer to a type in a qualified way, like "), alloc.parser_suggestion("Num.I64"), @@ -3296,7 +3370,7 @@ fn to_tapply_report<'a>( filename, doc, title: "TRAILING DOT".to_string(), - severity: Severity::RuntimeError, + severity, } } ETypeApply::StartIsNumber(pos) => { @@ -3304,7 +3378,7 @@ fn to_tapply_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I encountered a number at the start of a qualified name segment:"), - alloc.region(region), + alloc.region(region, severity), alloc.concat([ alloc.reflow("All parts of a qualified type name must start with an uppercase letter, like "), alloc.parser_suggestion("Num.I64"), @@ -3318,7 +3392,7 @@ fn to_tapply_report<'a>( filename, doc, title: "WEIRD QUALIFIED NAME".to_string(), - severity: Severity::RuntimeError, + severity, } } ETypeApply::StartNotUppercase(pos) => { @@ -3326,7 +3400,7 @@ fn to_tapply_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I encountered a lowercase letter at the start of a qualified name segment:"), - alloc.region(region), + alloc.region(region, severity), alloc.concat([ alloc.reflow("All parts of a qualified type name must start with an uppercase letter, like "), alloc.parser_suggestion("Num.I64"), @@ -3340,7 +3414,7 @@ fn to_tapply_report<'a>( filename, doc, title: "WEIRD QUALIFIED NAME".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3351,14 +3425,14 @@ fn to_tapply_report<'a>( alloc.reflow( r"I reached the end of the input file while parsing a qualified type name", ), - alloc.region(region), + alloc.region(region, severity), ]); Report { filename, doc, title: "END OF FILE".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3373,6 +3447,7 @@ fn to_talias_report<'a>( parse_problem: &roc_parse::parser::ETypeInlineAlias, ) -> Report<'a> { use roc_parse::parser::ETypeInlineAlias; + let severity = Severity::RuntimeError; match *parse_problem { ETypeInlineAlias::NotAnAlias(pos) => { @@ -3384,7 +3459,7 @@ fn to_talias_report<'a>( alloc.keyword("as"), alloc.reflow(" is not a type alias:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.reflow("Inline alias types must start with an uppercase identifier and be followed by zero or more type arguments, like "), alloc.type_str("Point"), @@ -3398,7 +3473,7 @@ fn to_talias_report<'a>( filename, doc, title: "NOT AN INLINE ALIAS".to_string(), - severity: Severity::RuntimeError, + severity, } } ETypeInlineAlias::Qualified(pos) => { @@ -3406,7 +3481,7 @@ fn to_talias_report<'a>( let doc = alloc.stack([ alloc.reflow(r"This type alias has a qualified name:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("An alias introduces a new name to the current scope, so it must be unqualified."), ]); @@ -3414,7 +3489,7 @@ fn to_talias_report<'a>( filename, doc, title: "QUALIFIED ALIAS NAME".to_string(), - severity: Severity::RuntimeError, + severity, } } ETypeInlineAlias::ArgumentNotLowercase(pos) => { @@ -3422,7 +3497,7 @@ fn to_talias_report<'a>( let doc = alloc.stack([ alloc.reflow(r"This alias type argument is not lowercase:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("All type arguments must be lowercase."), ]); @@ -3430,7 +3505,7 @@ fn to_talias_report<'a>( filename, doc, title: "TYPE ARGUMENT NOT LOWERCASE".to_string(), - severity: Severity::RuntimeError, + severity, } } } @@ -3445,6 +3520,8 @@ fn to_header_report<'a>( ) -> Report<'a> { use roc_parse::parser::EHeader; + let severity = Severity::RuntimeError; + match parse_problem { EHeader::Provides(provides, pos) => { to_provides_report(alloc, lines, filename, provides, *pos) @@ -3470,7 +3547,7 @@ fn to_header_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a header, but got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([alloc.reflow("I may be confused by indentation.")]), ]); @@ -3478,7 +3555,7 @@ fn to_header_report<'a>( filename, doc, title: "INCOMPLETE HEADER".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3494,7 +3571,11 @@ fn to_header_report<'a>( let preamble = if is_utf8 { vec![ alloc.reflow(r"I am expecting a header, but got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion( + lines.convert_region(surroundings), + region, + severity, + ), ] } else { vec![alloc.reflow(r"I am expecting a header, but the file is not UTF-8 encoded.")] @@ -3516,7 +3597,7 @@ fn to_header_report<'a>( filename, doc, title: "MISSING HEADER".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3526,7 +3607,7 @@ fn to_header_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a header, but got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I am expecting a module name next, like "), alloc.parser_suggestion("BigNum"), @@ -3540,7 +3621,7 @@ fn to_header_report<'a>( filename, doc, title: "WEIRD MODULE NAME".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3549,7 +3630,7 @@ fn to_header_report<'a>( alloc.reflow( r"This module name does not correspond with the file path it is defined in:", ), - alloc.region(lines.convert_region(*region)), + alloc.region(lines.convert_region(*region), severity), alloc.concat([ alloc.reflow("Module names must correspond with the file paths they are defined in. For example, I expect to see "), alloc.parser_suggestion("BigNum"), @@ -3567,7 +3648,7 @@ fn to_header_report<'a>( filename, doc, title: "WEIRD MODULE NAME".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3577,7 +3658,7 @@ fn to_header_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a header, but got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I am expecting an application name next, like "), alloc.parser_suggestion("app \"main\""), @@ -3591,7 +3672,7 @@ fn to_header_report<'a>( filename, doc, title: "WEIRD APP NAME".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3601,7 +3682,7 @@ fn to_header_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a package header, but got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I am expecting a package name next, like "), alloc.parser_suggestion("\"roc/core\""), @@ -3613,7 +3694,7 @@ fn to_header_report<'a>( filename, doc, title: "INVALID PACKAGE NAME".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3624,7 +3705,7 @@ fn to_header_report<'a>( let doc = alloc.stack([ alloc .reflow(r"I am partway through parsing a platform header, but got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I am expecting a platform name next, like "), alloc.parser_suggestion("\"roc/core\""), @@ -3636,7 +3717,7 @@ fn to_header_report<'a>( filename, doc, title: "INVALID PLATFORM NAME".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3647,7 +3728,7 @@ fn to_header_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a header, but got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I am expecting a type name next, like "), alloc.parser_suggestion("Effect"), @@ -3659,7 +3740,7 @@ fn to_header_report<'a>( filename, doc, title: "WEIRD GENERATED TYPE NAME".to_string(), - severity: Severity::RuntimeError, + severity, } } EHeader::GeneratesWith(generates_with, pos) => { @@ -3677,6 +3758,8 @@ fn to_generates_with_report<'a>( ) -> Report<'a> { use roc_parse::parser::EGeneratesWith; + let severity = Severity::RuntimeError; + match *parse_problem { EGeneratesWith::ListEnd(pos) | // TODO: give this its own error message EGeneratesWith::Identifier(pos) => { @@ -3686,7 +3769,7 @@ fn to_generates_with_report<'a>( let doc = alloc.stack([ alloc .reflow(r"I am partway through parsing a provides list, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([alloc.reflow( "I was expecting a type name, value name or function name next, like", )]), @@ -3699,7 +3782,7 @@ fn to_generates_with_report<'a>( filename, doc, title: "WEIRD GENERATES".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3709,7 +3792,7 @@ fn to_generates_with_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a header, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I am expecting the "), alloc.keyword("with"), @@ -3724,7 +3807,7 @@ fn to_generates_with_report<'a>( filename, doc, title: "WEIRD GENERATES".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3743,6 +3826,8 @@ fn to_provides_report<'a>( ) -> Report<'a> { use roc_parse::parser::EProvides; + let severity = Severity::RuntimeError; + match *parse_problem { EProvides::ListEnd(pos) | // TODO: give this its own error message EProvides::Identifier(pos) => { @@ -3752,7 +3837,7 @@ fn to_provides_report<'a>( let doc = alloc.stack([ alloc .reflow(r"I am partway through parsing a provides list, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([alloc.reflow( "I was expecting a type name, value name or function name next, like", )]), @@ -3765,7 +3850,7 @@ fn to_provides_report<'a>( filename, doc, title: "WEIRD PROVIDES".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3775,7 +3860,7 @@ fn to_provides_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a header, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I am expecting the "), alloc.keyword("provides"), @@ -3790,7 +3875,7 @@ fn to_provides_report<'a>( filename, doc, title: "WEIRD PROVIDES".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3802,7 +3887,7 @@ fn to_provides_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a header, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I am expecting the "), alloc.keyword("to"), @@ -3817,7 +3902,7 @@ fn to_provides_report<'a>( filename, doc, title: "WEIRD PROVIDES".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3827,7 +3912,7 @@ fn to_provides_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a header, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.reflow("I am expecting the platform name next, like:"), alloc .parser_suggestion("to pf") @@ -3838,7 +3923,7 @@ fn to_provides_report<'a>( filename, doc, title: "WEIRD PROVIDES".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3855,6 +3940,8 @@ fn to_params_report<'a>( ) -> Report<'a> { use roc_parse::parser::EParams; + let severity = Severity::RuntimeError; + match parse_problem { EParams::Pattern(error, pos) => to_precord_report(alloc, lines, filename, error, *pos), @@ -3865,7 +3952,7 @@ fn to_params_report<'a>( let doc = alloc.stack([ alloc .reflow(r"I am partway through parsing a module header, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I am expecting "), alloc.keyword("->"), @@ -3880,7 +3967,7 @@ fn to_params_report<'a>( filename, doc, title: "WEIRD MODULE PARAMS".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3897,6 +3984,8 @@ fn to_exposes_report<'a>( ) -> Report<'a> { use roc_parse::parser::EExposes; + let severity = Severity::RuntimeError; + match *parse_problem { EExposes::ListEnd(pos) | // TODO: give this its own error message EExposes::Identifier(pos) => { @@ -3905,7 +3994,7 @@ fn to_exposes_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing an `exposes` list, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([alloc.reflow( "I was expecting a type name, value name or function name next, like", )]), @@ -3918,7 +4007,7 @@ fn to_exposes_report<'a>( filename, doc, title: "WEIRD EXPOSES".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3928,7 +4017,7 @@ fn to_exposes_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a header, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I am expecting the "), alloc.keyword("exposes"), @@ -3943,7 +4032,7 @@ fn to_exposes_report<'a>( filename, doc, title: "WEIRD EXPOSES".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3962,6 +4051,8 @@ fn to_imports_report<'a>( ) -> Report<'a> { use roc_parse::parser::EImports; + let severity = Severity::RuntimeError; + match *parse_problem { EImports::Identifier(pos) => { let surroundings = Region::new(start, pos); @@ -3969,7 +4060,7 @@ fn to_imports_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a imports list, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([alloc.reflow( "I was expecting a type name, value name or function name next, like ", )]), @@ -3982,7 +4073,7 @@ fn to_imports_report<'a>( filename, doc, title: "WEIRD IMPORTS".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -3992,7 +4083,7 @@ fn to_imports_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a header, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I am expecting the "), alloc.keyword("imports"), @@ -4007,7 +4098,7 @@ fn to_imports_report<'a>( filename, doc, title: "WEIRD IMPORTS".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -4019,7 +4110,7 @@ fn to_imports_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a header, but got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I am expecting a module name next, like "), alloc.parser_suggestion("BigNum"), @@ -4033,7 +4124,7 @@ fn to_imports_report<'a>( filename, doc, title: "WEIRD MODULE NAME".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -4043,7 +4134,7 @@ fn to_imports_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a imports list, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([alloc.reflow("I am expecting a comma or end of list, like")]), alloc.parser_suggestion("imports [Shape, Vector]").indent(4), ]); @@ -4052,7 +4143,7 @@ fn to_imports_report<'a>( filename, doc, title: "WEIRD IMPORTS".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -4069,6 +4160,8 @@ fn to_requires_report<'a>( ) -> Report<'a> { use roc_parse::parser::ERequires; + let severity = Severity::RuntimeError; + match *parse_problem { ERequires::Requires(pos) => { let surroundings = Region::new(start, pos); @@ -4076,7 +4169,7 @@ fn to_requires_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a header, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I am expecting the "), alloc.keyword("requires"), @@ -4091,7 +4184,7 @@ fn to_requires_report<'a>( filename, doc, title: "MISSING REQUIRES".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -4103,7 +4196,7 @@ fn to_requires_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a header, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I am expecting the "), alloc.keyword("requires"), @@ -4118,7 +4211,7 @@ fn to_requires_report<'a>( filename, doc, title: "MISSING REQUIRES".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -4128,7 +4221,7 @@ fn to_requires_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a header, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I am expecting a list of rigids like "), alloc.keyword("{}"), @@ -4147,7 +4240,7 @@ fn to_requires_report<'a>( filename, doc, title: "BAD REQUIRES RIGIDS".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -4157,7 +4250,7 @@ fn to_requires_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a header, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I am expecting a list of type names like "), alloc.keyword("{}"), @@ -4176,7 +4269,7 @@ fn to_requires_report<'a>( filename, doc, title: "BAD REQUIRES".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -4193,6 +4286,8 @@ fn to_packages_report<'a>( ) -> Report<'a> { use roc_parse::parser::EPackages; + let severity = Severity::RuntimeError; + match *parse_problem { EPackages::Packages(pos) => { let surroundings = Region::new(start, pos); @@ -4200,7 +4295,7 @@ fn to_packages_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I am partway through parsing a header, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([ alloc.reflow("I am expecting the "), alloc.keyword("packages"), @@ -4213,7 +4308,7 @@ fn to_packages_report<'a>( filename, doc, title: "MISSING PACKAGES".to_string(), - severity: Severity::RuntimeError, + severity, } } EPackages::ListEnd(pos) => { @@ -4224,7 +4319,7 @@ fn to_packages_report<'a>( alloc.reflow( r"I am partway through parsing a list of packages, but I got stuck here:", ), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), alloc.concat([alloc.reflow("I am expecting a comma or end of list, like")]), alloc .parser_suggestion("packages { package_name: \"url-or-path\", }") @@ -4235,7 +4330,7 @@ fn to_packages_report<'a>( filename, doc, title: "WEIRD PACKAGES LIST".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -4254,13 +4349,15 @@ fn to_space_report<'a>( ) -> Report<'a> { use roc_parse::parser::BadInputError; + let severity = Severity::RuntimeError; + match parse_problem { BadInputError::HasTab => { let region = LineColumnRegion::from_pos(lines.convert_pos(pos)); let doc = alloc.stack([ alloc.reflow("I encountered a tab character:"), - alloc.region(region), + alloc.region(region, severity), alloc.reflow( "Tab characters are not allowed in Roc code. Please use spaces instead!", ), @@ -4270,7 +4367,7 @@ fn to_space_report<'a>( filename, doc, title: "TAB CHARACTER".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -4279,7 +4376,7 @@ fn to_space_report<'a>( let doc = alloc.stack([ alloc.reflow("I encountered an ASCII control character:"), - alloc.region(region), + alloc.region(region, severity), alloc.reflow("ASCII control characters are not allowed."), ]); @@ -4287,7 +4384,7 @@ fn to_space_report<'a>( filename, doc, title: "ASCII CONTROL CHARACTER".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -4296,7 +4393,7 @@ fn to_space_report<'a>( let doc = alloc.stack([ alloc.reflow(r"I encountered a stray carriage return (\r):"), - alloc.region(region), + alloc.region(region, severity), alloc.reflow(r"A carriage return (\r) has to be followed by a newline (\n)."), ]); @@ -4304,7 +4401,7 @@ fn to_space_report<'a>( filename, doc, title: "MISPLACED CARRIAGE RETURN".to_string(), - severity: Severity::RuntimeError, + severity, } } @@ -4374,10 +4471,11 @@ fn to_unfinished_ability_report<'a>( ) -> Report<'a> { let surroundings = Region::new(start, pos); let region = LineColumnRegion::from_pos(lines.convert_pos(pos)); + let severity = Severity::RuntimeError; let doc = alloc.stack([ alloc.reflow(r"I was partway through parsing an ability definition, but I got stuck here:"), - alloc.region_with_subregion(lines.convert_region(surroundings), region), + alloc.region_with_subregion(lines.convert_region(surroundings), region, severity), message, ]); @@ -4385,7 +4483,7 @@ fn to_unfinished_ability_report<'a>( filename, doc, title: "UNFINISHED ABILITY".to_string(), - severity: Severity::RuntimeError, + severity, } } diff --git a/crates/reporting/src/error/type.rs b/crates/reporting/src/error/type.rs index e831346621..1b3d9e4062 100644 --- a/crates/reporting/src/error/type.rs +++ b/crates/reporting/src/error/type.rs @@ -85,7 +85,7 @@ pub fn type_problem<'b>( UnfulfilledAbility(incomplete) => { let title = "INCOMPLETE ABILITY IMPLEMENTATION".to_string(); - let doc = report_unfulfilled_ability(alloc, lines, incomplete); + let doc = report_unfulfilled_ability(alloc, lines, incomplete, severity); report(title, doc, filename) } @@ -96,9 +96,9 @@ pub fn type_problem<'b>( let incomplete = incomplete .into_iter() - .map(|unfulfilled| report_unfulfilled_ability(alloc, lines, unfulfilled)); + .map(|unfulfilled| report_unfulfilled_ability(alloc, lines, unfulfilled, severity)); let note = alloc.stack(incomplete); - let snippet = alloc.region(lines.convert_region(region)); + let snippet = alloc.region(lines.convert_region(region), severity); let stack = [ alloc.text( "This expression has a type that does not implement the abilities it's expected to:", @@ -118,9 +118,9 @@ pub fn type_problem<'b>( BadPatternMissingAbility(region, _category, _found, incomplete) => { let incomplete = incomplete .into_iter() - .map(|unfulfilled| report_unfulfilled_ability(alloc, lines, unfulfilled)); + .map(|unfulfilled| report_unfulfilled_ability(alloc, lines, unfulfilled, severity)); let note = alloc.stack(incomplete); - let snippet = alloc.region(lines.convert_region(region)); + let snippet = alloc.region(lines.convert_region(region), severity); let stack = [ alloc.text( "This expression has a type does not implement the abilities it's expected to:", @@ -139,7 +139,7 @@ pub fn type_problem<'b>( } Exhaustive(problem) => Some(exhaustive_problem(alloc, lines, filename, problem)), CircularDef(entries) => { - let doc = to_circular_def_doc(alloc, lines, &entries); + let doc = to_circular_def_doc(alloc, lines, &entries, severity); let title = CIRCULAR_DEF.to_string(); Some(Report { @@ -161,7 +161,7 @@ pub fn type_problem<'b>( alloc.symbol_unqualified(member), alloc.reflow(" is for a non-opaque type:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("It is specialized for"), alloc.type_block(error_type_to_doc(alloc, typ)), alloc.reflow("but structural types can never specialize abilities!"), @@ -191,7 +191,7 @@ pub fn type_problem<'b>( alloc.symbol_unqualified(ability_member), alloc.reflow(" is not for the expected type:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.concat([ alloc.reflow("It was previously claimed to be a specialization for "), alloc.symbol_unqualified(expected_opaque), @@ -254,6 +254,7 @@ fn report_unfulfilled_ability<'a>( alloc: &'a RocDocAllocator<'a>, lines: &LineInfo, unfulfilled: Unfulfilled, + severity: Severity, ) -> RocDocBuilder<'a> { match unfulfilled { Unfulfilled::OpaqueDoesNotImplement { typ, ability } => { @@ -302,7 +303,7 @@ fn report_unfulfilled_ability<'a>( alloc.symbol_foreign_qualified(opaque), alloc.reflow(":"), ]), - alloc.region(lines.convert_region(derive_region)), + alloc.region(lines.convert_region(derive_region), severity), ] .into_iter() .chain(reason) @@ -446,6 +447,7 @@ pub fn cyclic_alias<'b>( region: roc_region::all::Region, others: Vec, alias_kind: AliasKind, + severity: Severity, ) -> (RocDocBuilder<'b>, String) { let when_is_recursion_legal = alloc.reflow("Recursion in ") @@ -460,7 +462,7 @@ pub fn cyclic_alias<'b>( .append(alloc.reflow(" ")) .append(alloc.reflow(alias_kind.as_str())) .append(alloc.reflow(" is self-recursive in an invalid way:")), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), when_is_recursion_legal, ]) } else { @@ -471,7 +473,7 @@ pub fn cyclic_alias<'b>( .append(alloc.reflow(" ")) .append(alloc.reflow(alias_kind.as_str())) .append(alloc.reflow(" is recursive in an invalid way:")), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc .reflow("The ") .append(alloc.symbol_unqualified(symbol)) @@ -515,9 +517,10 @@ fn report_mismatch<'b>( alloc.region_with_subregion( lines.convert_region(highlight), lines.convert_region(region), + severity, ) } else { - alloc.region(lines.convert_region(region)) + alloc.region(lines.convert_region(region), severity) }; let lines = vec![ problem, @@ -559,9 +562,10 @@ fn report_bad_type<'b>( alloc.region_with_subregion( lines.convert_region(highlight), lines.convert_region(region), + severity, ) } else { - alloc.region(lines.convert_region(region)) + alloc.region(lines.convert_region(region), severity) }; let lines = vec![ problem, @@ -664,7 +668,7 @@ fn to_expr_report<'b>( title: "TYPE MISMATCH".to_string(), doc: alloc.stack([ alloc.text("This expression is used in an unexpected way:"), - alloc.region(lines.convert_region(expr_region)), + alloc.region(lines.convert_region(expr_region), severity), comparison, ]), severity, @@ -786,6 +790,7 @@ fn to_expr_report<'b>( alloc.region_with_subregion( lines.convert_region(joined), lines.convert_region(expr_region), + severity, ) }, comparison, @@ -1138,7 +1143,7 @@ fn to_expr_report<'b>( " is an opaque type, so it cannot be called with an argument:", ), ]), - alloc.region(lines.convert_region(expr_region)), + alloc.region(lines.convert_region(expr_region), severity), match called_via { CalledVia::RecordBuilder => { alloc.hint("Did you mean to apply it to a function first?") @@ -1160,7 +1165,7 @@ fn to_expr_report<'b>( } )), ]), - alloc.region(lines.convert_region(expr_region)), + alloc.region(lines.convert_region(expr_region), severity), match called_via { CalledVia::RecordBuilder => { alloc.concat([ @@ -1208,7 +1213,7 @@ fn to_expr_report<'b>( arity )), ]), - alloc.region(lines.convert_region(expr_region)), + alloc.region(lines.convert_region(expr_region), severity), alloc.reflow("Are there any missing commas? Or missing parentheses?"), ]; @@ -1232,7 +1237,7 @@ fn to_expr_report<'b>( arity )), ]), - alloc.region(lines.convert_region(expr_region)), + alloc.region(lines.convert_region(expr_region), severity), alloc.reflow( "Roc does not allow functions to be partially applied. \ Use a closure to make partial application explicit.", @@ -1407,6 +1412,7 @@ fn to_expr_report<'b>( let snippet = alloc.region_with_subregion( lines.convert_region(region), lines.convert_region(expr_region), + severity, ); let this_is = alloc.concat([ @@ -1460,7 +1466,7 @@ fn to_expr_report<'b>( .append(alloc.text(" argument to ")) .append(name.clone()) .append(alloc.text(" is weird:")), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), pattern_type_comparison( alloc, expected_type, @@ -1501,7 +1507,7 @@ fn to_expr_report<'b>( .reflow("This value passed to ") .append(alloc.keyword("crash")) .append(alloc.reflow(" is not a string:")), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), type_comparison( alloc, found, @@ -1915,7 +1921,7 @@ fn to_pattern_report<'b>( PExpected::NoExpectation(expected_type) => { let doc = alloc.stack([ alloc.text("This pattern is being used in an unexpected way:"), - alloc.region(lines.convert_region(expr_region)), + alloc.region(lines.convert_region(expr_region), severity), pattern_type_comparison( alloc, found, @@ -1948,7 +1954,7 @@ fn to_pattern_report<'b>( .append(alloc.text(" argument to ")) .append(name.clone()) .append(alloc.text(" is weird:")), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), pattern_type_comparison( alloc, found, @@ -1986,6 +1992,7 @@ fn to_pattern_report<'b>( alloc.region_with_subregion( lines.convert_region(region), lines.convert_region(expr_region), + severity, ), pattern_type_comparison( alloc, @@ -2030,6 +2037,7 @@ fn to_pattern_report<'b>( alloc.region_with_subregion( lines.convert_region(region), lines.convert_region(expr_region), + severity, ), pattern_type_comparison( alloc, @@ -2059,7 +2067,7 @@ fn to_pattern_report<'b>( PReason::ListElem => { let doc = alloc.stack([ alloc.concat([alloc.reflow("This list element doesn't match the types of other elements in the pattern:")]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), pattern_type_comparison( alloc, found, @@ -2170,7 +2178,7 @@ fn to_circular_report<'b>( .reflow("I'm inferring a weird self-referential type for ") .append(alloc.symbol_unqualified(symbol)) .append(alloc.text(":")), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.stack([ alloc.reflow( "Here is my best effort at writing down the type. \ @@ -4810,7 +4818,7 @@ fn report_record_field_typo<'b>( let doc = alloc.stack([ header, - alloc.region(lines.convert_region(field_region)), + alloc.region(lines.convert_region(field_region), severity), if suggestions.is_empty() { let r_doc = match opt_sym { Some(symbol) => alloc.symbol_unqualified(symbol).append(" is"), @@ -4875,7 +4883,7 @@ fn exhaustive_problem<'a>( BadArg => { let doc = alloc.stack([ alloc.reflow("This pattern does not cover all the possibilities:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("Other possibilities include:"), unhandled_patterns_to_doc_block(alloc, missing), alloc.concat([ @@ -4898,7 +4906,7 @@ fn exhaustive_problem<'a>( BadDestruct => { let doc = alloc.stack([ alloc.reflow("This pattern does not cover all the possibilities:"), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("Other possibilities include:"), unhandled_patterns_to_doc_block(alloc, missing), alloc.concat([ @@ -4926,7 +4934,7 @@ fn exhaustive_problem<'a>( alloc.keyword("when"), alloc.reflow(" does not cover all the possibilities:"), ]), - alloc.region(lines.convert_region(region)), + alloc.region(lines.convert_region(region), severity), alloc.reflow("Other possibilities include:"), unhandled_patterns_to_doc_block(alloc, missing), alloc.reflow( @@ -4958,6 +4966,7 @@ fn exhaustive_problem<'a>( alloc.region_with_subregion( lines.convert_region(overall_region), lines.convert_region(branch_region), + severity, ), alloc.reflow( "Any value of this shape will be handled by \ @@ -4986,6 +4995,7 @@ fn exhaustive_problem<'a>( alloc.region_with_subregion( lines.convert_region(overall_region), lines.convert_region(branch_region), + severity, ), alloc.reflow( "It's impossible to create a value of this shape, \ diff --git a/crates/reporting/src/report.rs b/crates/reporting/src/report.rs index 0f18f94c20..e74013f415 100644 --- a/crates/reporting/src/report.rs +++ b/crates/reporting/src/report.rs @@ -223,6 +223,7 @@ pub struct Palette { pub bold: &'static str, pub underline: &'static str, pub reset: &'static str, + pub warning: &'static str, } /// Set the default styles for various semantic elements, @@ -250,6 +251,7 @@ const fn default_palette_from_style_codes(codes: StyleCodes) -> Palette { bold: codes.bold, underline: codes.underline, reset: codes.reset, + warning: codes.yellow, } } @@ -675,6 +677,7 @@ impl<'a> RocDocAllocator<'a> { &'a self, region: LineColumnRegion, sub_region: LineColumnRegion, + severity: Severity, ) -> DocBuilder<'a, Self, Annotation> { // debug_assert!(region.contains(&sub_region)); @@ -684,10 +687,15 @@ impl<'a> RocDocAllocator<'a> { // attempting this will recurse forever, so don't do that! Instead, give up and // accept that this report will take up more than 1 full screen. if !sub_region.contains(®ion) { - return self.region_with_subregion(sub_region, sub_region); + return self.region_with_subregion(sub_region, sub_region, severity); } } + let annotation = match severity { + Severity::RuntimeError | Severity::Fatal => Annotation::Error, + Severity::Warning => Annotation::Warning, + }; + // if true, the final line of the snippet will be some ^^^ that point to the region where // the problem is. Otherwise, the snippet will have a > on the lines that are in the region // where the problem is. @@ -727,7 +735,7 @@ impl<'a> RocDocAllocator<'a> { self.text(" ".repeat(max_line_number_length - this_line_number_length)) .append(self.text(line_number).annotate(Annotation::LineNumber)) .append(self.text(GUTTER_BAR).annotate(Annotation::GutterBar)) - .append(self.text(">").annotate(Annotation::Error)) + .append(self.text(">").annotate(annotation)) .append(rest_of_line) } else if error_highlight_line { self.text(" ".repeat(max_line_number_length - this_line_number_length)) @@ -769,7 +777,7 @@ impl<'a> RocDocAllocator<'a> { } else { self.text(" ".repeat(sub_region.start().column as usize)) .indent(indent) - .append(self.text(highlight_text).annotate(Annotation::Error)) + .append(self.text(highlight_text).annotate(annotation)) }); result = result.append(highlight_line); @@ -778,8 +786,12 @@ impl<'a> RocDocAllocator<'a> { result } - pub fn region(&'a self, region: LineColumnRegion) -> DocBuilder<'a, Self, Annotation> { - self.region_with_subregion(region, region) + pub fn region( + &'a self, + region: LineColumnRegion, + severity: Severity, + ) -> DocBuilder<'a, Self, Annotation> { + self.region_with_subregion(region, region, severity) } pub fn region_without_error( @@ -884,6 +896,7 @@ pub enum Annotation { Tip, Header, ParserSuggestion, + Warning, } /// Render with minimal formatting @@ -1094,6 +1107,9 @@ where ParserSuggestion => { self.write_str(self.palette.parser_suggestion)?; } + Warning => { + self.write_str(self.palette.warning)?; + } TypeBlock | InlineTypeBlock | Tag | RecordField | TupleElem => { /* nothing yet */ } } self.style_stack.push(*annotation); @@ -1108,7 +1124,8 @@ where Some(annotation) => match annotation { Emphasized | Url | TypeVariable | Alias | Symbol | BinOp | UnaryOp | Error | GutterBar | Ellipsis | Typo | TypoSuggestion | ParserSuggestion | Structure - | CodeBlock | PlainText | LineNumber | Tip | Module | Header | Keyword => { + | CodeBlock | PlainText | LineNumber | Tip | Module | Header | Keyword + | Warning => { self.write_str(self.palette.reset)?; }