Enumerate severity on problem variants

This commit is contained in:
Ayaz Hafiz 2022-12-02 11:14:17 -06:00
parent 0a4ec1958b
commit e438fbf37c
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
9 changed files with 92 additions and 74 deletions

View file

@ -46,7 +46,7 @@ use roc_parse::ident::UppercaseIdent;
use roc_parse::module::module_defs; use roc_parse::module::module_defs;
use roc_parse::parser::{FileError, Parser, SourceError, SyntaxError}; use roc_parse::parser::{FileError, Parser, SourceError, SyntaxError};
use roc_region::all::{LineInfo, Loc, Region}; use roc_region::all::{LineInfo, Loc, Region};
use roc_reporting::report::{Annotation, Palette, RenderTarget}; use roc_reporting::report::{Annotation, Palette, RenderTarget, Severity};
use roc_solve::module::{extract_module_owned_implementations, Solved, SolvedModule}; use roc_solve::module::{extract_module_owned_implementations, Solved, SolvedModule};
use roc_solve_problem::TypeError; use roc_solve_problem::TypeError;
use roc_target::TargetInfo; use roc_target::TargetInfo;

View file

@ -7,6 +7,8 @@ use roc_parse::pattern::PatternType;
use roc_region::all::{Loc, Region}; use roc_region::all::{Loc, Region};
use roc_types::types::AliasKind; use roc_types::types::AliasKind;
use crate::Severity;
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct CycleEntry { pub struct CycleEntry {
pub symbol: Symbol, pub symbol: Symbol,
@ -205,6 +207,70 @@ pub enum Problem {
} }
impl Problem { impl Problem {
pub fn severity(&self) -> Severity {
use Severity::{RuntimeError, Warning};
match self {
Problem::UnusedDef(_, _) => Warning,
Problem::UnusedImport(_, _) => Warning,
Problem::UnusedModuleImport(_, _) => Warning,
Problem::ExposedButNotDefined(_) => Warning,
Problem::UnknownGeneratesWith(_) => RuntimeError,
Problem::UnusedArgument(_, _, _, _) => Warning,
Problem::UnusedBranchDef(_, _) => Warning,
Problem::PrecedenceProblem(_) => RuntimeError,
Problem::UnsupportedPattern(_, _) => RuntimeError,
Problem::Shadowing { .. } => RuntimeError,
Problem::CyclicAlias(..) => RuntimeError,
Problem::BadRecursion(_) => RuntimeError,
Problem::PhantomTypeArgument { .. } => Warning,
Problem::UnboundTypeVariable { .. } => RuntimeError,
Problem::DuplicateRecordFieldValue { .. } => Warning,
Problem::DuplicateRecordFieldType { .. } => RuntimeError,
Problem::InvalidOptionalValue { .. } => RuntimeError,
Problem::DuplicateTag { .. } => RuntimeError,
Problem::RuntimeError(_) => RuntimeError,
Problem::SignatureDefMismatch { .. } => RuntimeError,
Problem::InvalidAliasRigid { .. } => RuntimeError,
Problem::InvalidInterpolation(_) => RuntimeError,
Problem::InvalidHexadecimal(_) => RuntimeError,
Problem::InvalidUnicodeCodePt(_) => RuntimeError,
Problem::NestedDatatype { .. } => RuntimeError,
Problem::InvalidExtensionType { .. } => RuntimeError,
Problem::AbilityHasTypeVariables { .. } => RuntimeError,
Problem::HasClauseIsNotAbility { .. } => RuntimeError,
Problem::IllegalHasClause { .. } => RuntimeError,
Problem::DuplicateHasAbility { .. } => Warning,
Problem::AbilityMemberMissingHasClause { .. } => RuntimeError,
Problem::AbilityMemberMultipleBoundVars { .. } => RuntimeError,
Problem::AbilityNotOnToplevel { .. } => RuntimeError, // Ideally, could be compiled
Problem::AbilityUsedAsType(_, _, _) => RuntimeError,
Problem::NestedSpecialization(_, _) => RuntimeError, // Ideally, could be compiled
Problem::IllegalDerivedAbility(_) => RuntimeError,
Problem::ImplementationNotFound { .. } => RuntimeError,
Problem::NotAnAbilityMember { .. } => RuntimeError,
Problem::OptionalAbilityImpl { .. } => RuntimeError,
Problem::QualifiedAbilityImpl { .. } => RuntimeError,
Problem::AbilityImplNotIdent { .. } => RuntimeError,
Problem::DuplicateImpl { .. } => Warning, // First impl is used at runtime
Problem::NotAnAbility(_) => Warning,
Problem::ImplementsNonRequired { .. } => Warning,
Problem::DoesNotImplementAbility { .. } => RuntimeError,
Problem::NotBoundInAllPatterns { .. } => RuntimeError,
Problem::NoIdentifiersIntroduced(_) => Warning,
Problem::OverloadedSpecialization { .. } => Warning, // Ideally, will compile
Problem::UnnecessaryOutputWildcard { .. } => Warning,
// TODO: sometimes this can just be a warning, e.g. if you have [1, .., .., 2] but we
// don't catch that yet.
Problem::MultipleListRestPattern { .. } => RuntimeError,
Problem::BadTypeArguments { .. } => RuntimeError,
// TODO: this can be a warning instead if we recover the program by
// injecting a crash message
Problem::UnappliedCrash { .. } => RuntimeError,
Problem::OverAppliedCrash { .. } => RuntimeError,
}
}
/// Returns a Region value from the Problem, if possible. /// Returns a Region value from the Problem, if possible.
/// Some problems have more than one region; in those cases, /// Some problems have more than one region; in those cases,
/// this tries to pick the one that's closest to the original /// this tries to pick the one that's closest to the original

View file

@ -3,3 +3,15 @@
// See github.com/roc-lang/roc/issues/800 for discussion of the large_enum_variant check. // See github.com/roc-lang/roc/issues/800 for discussion of the large_enum_variant check.
#![allow(clippy::large_enum_variant)] #![allow(clippy::large_enum_variant)]
pub mod can; pub mod can;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Severity {
/// This will cause a runtime error if some code get srun
/// (e.g. type mismatch, naming error)
RuntimeError,
/// This will never cause the code to misbehave,
/// but should be cleaned up
/// (e.g. unused def, unused import)
Warning,
}

View file

@ -29,9 +29,8 @@ pub fn report_problems(
can_problems: &mut MutMap<ModuleId, Vec<roc_problem::can::Problem>>, can_problems: &mut MutMap<ModuleId, Vec<roc_problem::can::Problem>>,
type_problems: &mut MutMap<ModuleId, Vec<TypeError>>, type_problems: &mut MutMap<ModuleId, Vec<TypeError>>,
) -> Problems { ) -> Problems {
use crate::report::{ use crate::report::{can_problem, type_problem, Report, RocDocAllocator, DEFAULT_PALETTE};
can_problem, type_problem, Report, RocDocAllocator, Severity::*, DEFAULT_PALETTE, use roc_problem::Severity::*;
};
let palette = DEFAULT_PALETTE; let palette = DEFAULT_PALETTE;
// This will often over-allocate total memory, but it means we definitely // This will often over-allocate total memory, but it means we definitely

View file

@ -6,12 +6,13 @@ use roc_problem::can::{
BadPattern, CycleEntry, ExtensionTypeKind, FloatErrorKind, IntErrorKind, Problem, RuntimeError, BadPattern, CycleEntry, ExtensionTypeKind, FloatErrorKind, IntErrorKind, Problem, RuntimeError,
ShadowKind, ShadowKind,
}; };
use roc_problem::Severity;
use roc_region::all::{LineColumn, LineColumnRegion, LineInfo, Loc, Region}; use roc_region::all::{LineColumn, LineColumnRegion, LineInfo, Loc, Region};
use roc_types::types::AliasKind; use roc_types::types::AliasKind;
use std::path::PathBuf; use std::path::PathBuf;
use crate::error::r#type::suggest; use crate::error::r#type::suggest;
use crate::report::{Annotation, Report, RocDocAllocator, RocDocBuilder, Severity}; use crate::report::{Annotation, Report, RocDocAllocator, RocDocBuilder};
use ven_pretty::DocAllocator; use ven_pretty::DocAllocator;
const SYNTAX_PROBLEM: &str = "SYNTAX PROBLEM"; const SYNTAX_PROBLEM: &str = "SYNTAX PROBLEM";
@ -67,7 +68,7 @@ pub fn can_problem<'b>(
) -> Report<'b> { ) -> Report<'b> {
let doc; let doc;
let title; let title;
let severity; let severity = problem.severity();
match problem { match problem {
Problem::UnusedDef(symbol, region) => { Problem::UnusedDef(symbol, region) => {
@ -86,7 +87,6 @@ pub fn can_problem<'b>(
]); ]);
title = UNUSED_DEF.to_string(); title = UNUSED_DEF.to_string();
severity = Severity::Warning;
} }
Problem::UnusedImport(symbol, region) => { Problem::UnusedImport(symbol, region) => {
doc = alloc.stack([ doc = alloc.stack([
@ -103,7 +103,6 @@ pub fn can_problem<'b>(
]); ]);
title = UNUSED_IMPORT.to_string(); title = UNUSED_IMPORT.to_string();
severity = Severity::Warning;
} }
Problem::UnusedModuleImport(module_id, region) => { Problem::UnusedModuleImport(module_id, region) => {
doc = alloc.stack([ doc = alloc.stack([
@ -121,7 +120,6 @@ pub fn can_problem<'b>(
]); ]);
title = UNUSED_IMPORT.to_string(); title = UNUSED_IMPORT.to_string();
severity = Severity::Warning;
} }
Problem::DefsOnlyUsedInRecursion(1, region) => { Problem::DefsOnlyUsedInRecursion(1, region) => {
doc = alloc.stack([ doc = alloc.stack([
@ -165,7 +163,6 @@ pub fn can_problem<'b>(
]); ]);
title = MISSING_DEFINITION.to_string(); title = MISSING_DEFINITION.to_string();
severity = Severity::RuntimeError;
} }
Problem::UnknownGeneratesWith(loc_ident) => { Problem::UnknownGeneratesWith(loc_ident) => {
doc = alloc.stack([ doc = alloc.stack([
@ -180,7 +177,6 @@ pub fn can_problem<'b>(
]); ]);
title = UNKNOWN_GENERATES_WITH.to_string(); title = UNKNOWN_GENERATES_WITH.to_string();
severity = Severity::RuntimeError;
} }
Problem::UnusedArgument(closure_symbol, is_anonymous, argument_symbol, region) => { Problem::UnusedArgument(closure_symbol, is_anonymous, argument_symbol, region) => {
let line = "\". Adding an underscore at the start of a variable name is a way of saying that the variable is not used."; let line = "\". Adding an underscore at the start of a variable name is a way of saying that the variable is not used.";
@ -215,7 +211,6 @@ pub fn can_problem<'b>(
]); ]);
title = UNUSED_ARG.to_string(); title = UNUSED_ARG.to_string();
severity = Severity::Warning;
} }
Problem::UnusedBranchDef(symbol, region) => { Problem::UnusedBranchDef(symbol, region) => {
doc = alloc.stack([ doc = alloc.stack([
@ -236,7 +231,6 @@ pub fn can_problem<'b>(
]); ]);
title = UNUSED_DEF.to_string(); title = UNUSED_DEF.to_string();
severity = Severity::Warning;
} }
Problem::PrecedenceProblem(BothNonAssociative(region, left_bin_op, right_bin_op)) => { Problem::PrecedenceProblem(BothNonAssociative(region, left_bin_op, right_bin_op)) => {
doc = alloc.stack([ doc = alloc.stack([
@ -265,7 +259,6 @@ pub fn can_problem<'b>(
]); ]);
title = SYNTAX_PROBLEM.to_string(); title = SYNTAX_PROBLEM.to_string();
severity = Severity::RuntimeError;
} }
Problem::UnsupportedPattern(BadPattern::Unsupported(pattern_type), region) => { Problem::UnsupportedPattern(BadPattern::Unsupported(pattern_type), region) => {
use roc_parse::pattern::PatternType::*; use roc_parse::pattern::PatternType::*;
@ -296,7 +289,6 @@ pub fn can_problem<'b>(
]); ]);
title = SYNTAX_PROBLEM.to_string(); title = SYNTAX_PROBLEM.to_string();
severity = Severity::RuntimeError;
} }
Problem::Shadowing { Problem::Shadowing {
original_region, original_region,
@ -308,7 +300,6 @@ pub fn can_problem<'b>(
doc = res_doc; doc = res_doc;
title = res_title.to_string(); title = res_title.to_string();
severity = Severity::RuntimeError;
} }
Problem::CyclicAlias(symbol, region, others, alias_kind) => { Problem::CyclicAlias(symbol, region, others, alias_kind) => {
let answer = crate::error::r#type::cyclic_alias( let answer = crate::error::r#type::cyclic_alias(
@ -317,7 +308,6 @@ pub fn can_problem<'b>(
doc = answer.0; doc = answer.0;
title = answer.1; title = answer.1;
severity = Severity::RuntimeError;
} }
Problem::PhantomTypeArgument { Problem::PhantomTypeArgument {
typ: alias, typ: alias,
@ -345,7 +335,6 @@ pub fn can_problem<'b>(
]); ]);
title = UNUSED_ALIAS_PARAM.to_string(); title = UNUSED_ALIAS_PARAM.to_string();
severity = Severity::RuntimeError;
} }
Problem::UnboundTypeVariable { Problem::UnboundTypeVariable {
typ: alias, typ: alias,
@ -382,12 +371,10 @@ pub fn can_problem<'b>(
doc = alloc.stack(stack); doc = alloc.stack(stack);
title = UNBOUND_TYPE_VARIABLE.to_string(); title = UNBOUND_TYPE_VARIABLE.to_string();
severity = Severity::RuntimeError;
} }
Problem::BadRecursion(entries) => { Problem::BadRecursion(entries) => {
doc = to_circular_def_doc(alloc, lines, &entries); doc = to_circular_def_doc(alloc, lines, &entries);
title = CIRCULAR_DEF.to_string(); title = CIRCULAR_DEF.to_string();
severity = Severity::RuntimeError;
} }
Problem::DuplicateRecordFieldValue { Problem::DuplicateRecordFieldValue {
field_name, field_name,
@ -422,7 +409,6 @@ pub fn can_problem<'b>(
]); ]);
title = DUPLICATE_FIELD_NAME.to_string(); title = DUPLICATE_FIELD_NAME.to_string();
severity = Severity::Warning;
} }
Problem::InvalidOptionalValue { Problem::InvalidOptionalValue {
field_name, field_name,
@ -471,7 +457,6 @@ pub fn can_problem<'b>(
]); ]);
title = DUPLICATE_FIELD_NAME.to_string(); title = DUPLICATE_FIELD_NAME.to_string();
severity = Severity::Warning;
} }
Problem::DuplicateTag { Problem::DuplicateTag {
tag_name, tag_name,
@ -506,7 +491,6 @@ pub fn can_problem<'b>(
]); ]);
title = DUPLICATE_TAG_NAME.to_string(); title = DUPLICATE_TAG_NAME.to_string();
severity = Severity::Warning;
} }
Problem::SignatureDefMismatch { Problem::SignatureDefMismatch {
ref annotation_pattern, ref annotation_pattern,
@ -523,7 +507,6 @@ pub fn can_problem<'b>(
]); ]);
title = NAMING_PROBLEM.to_string(); title = NAMING_PROBLEM.to_string();
severity = Severity::RuntimeError;
} }
Problem::InvalidAliasRigid { Problem::InvalidAliasRigid {
alias_name: type_name, alias_name: type_name,
@ -546,7 +529,6 @@ pub fn can_problem<'b>(
]); ]);
title = SYNTAX_PROBLEM.to_string(); title = SYNTAX_PROBLEM.to_string();
severity = Severity::RuntimeError;
} }
Problem::InvalidHexadecimal(region) => { Problem::InvalidHexadecimal(region) => {
doc = alloc.stack([ doc = alloc.stack([
@ -563,7 +545,6 @@ pub fn can_problem<'b>(
]); ]);
title = INVALID_UNICODE.to_string(); title = INVALID_UNICODE.to_string();
severity = Severity::RuntimeError;
} }
Problem::InvalidUnicodeCodePt(region) => { Problem::InvalidUnicodeCodePt(region) => {
doc = alloc.stack([ doc = alloc.stack([
@ -573,7 +554,6 @@ pub fn can_problem<'b>(
]); ]);
title = INVALID_UNICODE.to_string(); title = INVALID_UNICODE.to_string();
severity = Severity::RuntimeError;
} }
Problem::InvalidInterpolation(region) => { Problem::InvalidInterpolation(region) => {
doc = alloc.stack([ doc = alloc.stack([
@ -590,14 +570,12 @@ pub fn can_problem<'b>(
]); ]);
title = SYNTAX_PROBLEM.to_string(); title = SYNTAX_PROBLEM.to_string();
severity = Severity::RuntimeError;
} }
Problem::RuntimeError(runtime_error) => { Problem::RuntimeError(runtime_error) => {
let answer = pretty_runtime_error(alloc, lines, runtime_error); let answer = pretty_runtime_error(alloc, lines, runtime_error);
doc = answer.0; doc = answer.0;
title = answer.1.to_string(); title = answer.1.to_string();
severity = Severity::RuntimeError;
} }
Problem::NestedDatatype { Problem::NestedDatatype {
alias, alias,
@ -625,7 +603,6 @@ pub fn can_problem<'b>(
]); ]);
title = NESTED_DATATYPE.to_string(); title = NESTED_DATATYPE.to_string();
severity = Severity::RuntimeError;
} }
Problem::InvalidExtensionType { region, kind } => { Problem::InvalidExtensionType { region, kind } => {
@ -653,7 +630,6 @@ pub fn can_problem<'b>(
]); ]);
title = INVALID_EXTENSION_TYPE.to_string(); title = INVALID_EXTENSION_TYPE.to_string();
severity = Severity::RuntimeError;
} }
Problem::AbilityHasTypeVariables { Problem::AbilityHasTypeVariables {
@ -672,7 +648,6 @@ pub fn can_problem<'b>(
), ),
]); ]);
title = ABILITY_HAS_TYPE_VARIABLES.to_string(); title = ABILITY_HAS_TYPE_VARIABLES.to_string();
severity = Severity::RuntimeError;
} }
Problem::HasClauseIsNotAbility { Problem::HasClauseIsNotAbility {
@ -683,7 +658,6 @@ pub fn can_problem<'b>(
alloc.region(lines.convert_region(clause_region)), alloc.region(lines.convert_region(clause_region)),
]); ]);
title = HAS_CLAUSE_IS_NOT_AN_ABILITY.to_string(); title = HAS_CLAUSE_IS_NOT_AN_ABILITY.to_string();
severity = Severity::RuntimeError;
} }
Problem::IllegalHasClause { region } => { Problem::IllegalHasClause { region } => {
@ -702,7 +676,6 @@ pub fn can_problem<'b>(
]), ]),
]); ]);
title = ILLEGAL_HAS_CLAUSE.to_string(); title = ILLEGAL_HAS_CLAUSE.to_string();
severity = Severity::RuntimeError;
} }
Problem::DuplicateHasAbility { ability, region } => { Problem::DuplicateHasAbility { ability, region } => {
@ -720,7 +693,6 @@ pub fn can_problem<'b>(
]), ]),
]); ]);
title = "DUPLICATE BOUND ABILITY".to_string(); title = "DUPLICATE BOUND ABILITY".to_string();
severity = Severity::Warning;
} }
Problem::AbilityMemberMissingHasClause { Problem::AbilityMemberMissingHasClause {
@ -755,7 +727,6 @@ pub fn can_problem<'b>(
.reflow("Otherwise, the function does not need to be part of the ability!")]), .reflow("Otherwise, the function does not need to be part of the ability!")]),
]); ]);
title = ABILITY_MEMBER_MISSING_HAS_CLAUSE.to_string(); title = ABILITY_MEMBER_MISSING_HAS_CLAUSE.to_string();
severity = Severity::RuntimeError;
} }
Problem::AbilityMemberMultipleBoundVars { Problem::AbilityMemberMultipleBoundVars {
@ -783,7 +754,6 @@ pub fn can_problem<'b>(
]) ])
]); ]);
title = ABILITY_MEMBER_BINDS_MULTIPLE_VARIABLES.to_string(); title = ABILITY_MEMBER_BINDS_MULTIPLE_VARIABLES.to_string();
severity = Severity::RuntimeError;
} }
Problem::AbilityNotOnToplevel { region } => { Problem::AbilityNotOnToplevel { region } => {
@ -795,7 +765,6 @@ pub fn can_problem<'b>(
alloc.reflow("Abilities can only be defined on the top-level of a Roc module."), alloc.reflow("Abilities can only be defined on the top-level of a Roc module."),
]); ]);
title = ABILITY_NOT_ON_TOPLEVEL.to_string(); title = ABILITY_NOT_ON_TOPLEVEL.to_string();
severity = Severity::RuntimeError;
} }
Problem::AbilityUsedAsType(suggested_var_name, ability, region) => { Problem::AbilityUsedAsType(suggested_var_name, ability, region) => {
@ -823,7 +792,6 @@ pub fn can_problem<'b>(
])), ])),
]); ]);
title = ABILITY_USED_AS_TYPE.to_string(); title = ABILITY_USED_AS_TYPE.to_string();
severity = Severity::RuntimeError;
} }
Problem::NestedSpecialization(member, region) => { Problem::NestedSpecialization(member, region) => {
doc = alloc.stack([ doc = alloc.stack([
@ -836,7 +804,6 @@ pub fn can_problem<'b>(
alloc.reflow("Specializations can only be defined on the top-level of a module."), alloc.reflow("Specializations can only be defined on the top-level of a module."),
]); ]);
title = SPECIALIZATION_NOT_ON_TOPLEVEL.to_string(); title = SPECIALIZATION_NOT_ON_TOPLEVEL.to_string();
severity = Severity::Warning;
} }
Problem::IllegalDerivedAbility(region) => { Problem::IllegalDerivedAbility(region) => {
doc = alloc.stack([ doc = alloc.stack([
@ -848,7 +815,6 @@ pub fn can_problem<'b>(
.append(list_builtin_abilities(alloc)), .append(list_builtin_abilities(alloc)),
]); ]);
title = ILLEGAL_DERIVE.to_string(); title = ILLEGAL_DERIVE.to_string();
severity = Severity::Warning;
} }
Problem::NotAnAbility(region) => { Problem::NotAnAbility(region) => {
doc = alloc.stack([ doc = alloc.stack([
@ -857,7 +823,6 @@ pub fn can_problem<'b>(
alloc.reflow("Only abilities can be implemented."), alloc.reflow("Only abilities can be implemented."),
]); ]);
title = NOT_AN_ABILITY.to_string(); title = NOT_AN_ABILITY.to_string();
severity = Severity::Warning;
} }
Problem::NotAnAbilityMember { Problem::NotAnAbilityMember {
ability, ability,
@ -872,7 +837,6 @@ pub fn can_problem<'b>(
alloc.reflow("Only implementations for members an ability has can be specified in this location.") alloc.reflow("Only implementations for members an ability has can be specified in this location.")
]); ]);
title = NOT_AN_ABILITY_MEMBER.to_string(); title = NOT_AN_ABILITY_MEMBER.to_string();
severity = Severity::RuntimeError;
} }
Problem::ImplementationNotFound { member, region } => { Problem::ImplementationNotFound { member, region } => {
let member_str = member.as_str(alloc.interns); let member_str = member.as_str(alloc.interns);
@ -884,7 +848,6 @@ pub fn can_problem<'b>(
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!("{{ {}: my{} }}", member_str, member_str))])) 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!("{{ {}: my{} }}", member_str, member_str))]))
]); ]);
title = IMPLEMENTATION_NOT_FOUND.to_string(); title = IMPLEMENTATION_NOT_FOUND.to_string();
severity = Severity::RuntimeError;
} }
Problem::OptionalAbilityImpl { ability, region } => { Problem::OptionalAbilityImpl { ability, region } => {
let hint = if ability.is_builtin() { let hint = if ability.is_builtin() {
@ -903,7 +866,6 @@ pub fn can_problem<'b>(
hint, hint,
]); ]);
title = OPTIONAL_ABILITY_IMPLEMENTATION.to_string(); title = OPTIONAL_ABILITY_IMPLEMENTATION.to_string();
severity = Severity::RuntimeError;
} }
Problem::QualifiedAbilityImpl { region } => { Problem::QualifiedAbilityImpl { region } => {
doc = alloc.stack([ doc = alloc.stack([
@ -914,7 +876,6 @@ pub fn can_problem<'b>(
), ),
]); ]);
title = QUALIFIED_ABILITY_IMPLEMENTATION.to_string(); title = QUALIFIED_ABILITY_IMPLEMENTATION.to_string();
severity = Severity::RuntimeError;
} }
Problem::AbilityImplNotIdent { region } => { Problem::AbilityImplNotIdent { region } => {
doc = alloc.stack([ doc = alloc.stack([
@ -926,7 +887,6 @@ pub fn can_problem<'b>(
alloc.tip().append(alloc.reflow("consider defining this expression as a variable.")) alloc.tip().append(alloc.reflow("consider defining this expression as a variable."))
]); ]);
title = ABILITY_IMPLEMENTATION_NOT_IDENTIFIER.to_string(); title = ABILITY_IMPLEMENTATION_NOT_IDENTIFIER.to_string();
severity = Severity::RuntimeError;
} }
Problem::DuplicateImpl { Problem::DuplicateImpl {
original, original,
@ -941,7 +901,6 @@ pub fn can_problem<'b>(
.reflow("Only one custom implementation can be defined for an ability member."), .reflow("Only one custom implementation can be defined for an ability member."),
]); ]);
title = DUPLICATE_IMPLEMENTATION.to_string(); title = DUPLICATE_IMPLEMENTATION.to_string();
severity = Severity::RuntimeError;
} }
Problem::ImplementsNonRequired { Problem::ImplementsNonRequired {
region, region,
@ -966,7 +925,6 @@ pub fn can_problem<'b>(
), ),
]); ]);
title = UNNECESSARY_IMPLEMENTATIONS.to_string(); title = UNNECESSARY_IMPLEMENTATIONS.to_string();
severity = Severity::Warning;
} }
Problem::DoesNotImplementAbility { Problem::DoesNotImplementAbility {
region, region,
@ -991,7 +949,6 @@ pub fn can_problem<'b>(
), ),
]); ]);
title = INCOMPLETE_ABILITY_IMPLEMENTATION.to_string(); title = INCOMPLETE_ABILITY_IMPLEMENTATION.to_string();
severity = Severity::RuntimeError;
} }
Problem::NotBoundInAllPatterns { Problem::NotBoundInAllPatterns {
unbound_symbol, unbound_symbol,
@ -1012,7 +969,6 @@ pub fn can_problem<'b>(
]), ]),
]); ]);
title = "NAME NOT BOUND IN ALL PATTERNS".to_string(); title = "NAME NOT BOUND IN ALL PATTERNS".to_string();
severity = Severity::RuntimeError;
} }
Problem::NoIdentifiersIntroduced(region) => { Problem::NoIdentifiersIntroduced(region) => {
doc = alloc.stack([ doc = alloc.stack([
@ -1021,7 +977,6 @@ pub fn can_problem<'b>(
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!"), 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(); title = "UNNECESSARY DEFINITION".to_string();
severity = Severity::Warning;
} }
Problem::OverloadedSpecialization { Problem::OverloadedSpecialization {
ability_member, ability_member,
@ -1041,7 +996,6 @@ pub fn can_problem<'b>(
alloc.reflow("Ability specializations can only provide implementations for one opaque type, since all opaque types are different!"), alloc.reflow("Ability specializations can only provide implementations for one opaque type, since all opaque types are different!"),
]); ]);
title = "OVERLOADED SPECIALIZATION".to_string(); title = "OVERLOADED SPECIALIZATION".to_string();
severity = Severity::Warning;
} }
Problem::UnnecessaryOutputWildcard { region } => { Problem::UnnecessaryOutputWildcard { region } => {
doc = alloc.stack([ doc = alloc.stack([
@ -1061,7 +1015,6 @@ pub fn can_problem<'b>(
alloc.reflow("You can safely remove this to make the code more concise without changing what it means."), alloc.reflow("You can safely remove this to make the code more concise without changing what it means."),
]); ]);
title = "UNNECESSARY WILDCARD".to_string(); title = "UNNECESSARY WILDCARD".to_string();
severity = Severity::Warning;
} }
Problem::MultipleListRestPattern { region } => { Problem::MultipleListRestPattern { region } => {
doc = alloc.stack([ doc = alloc.stack([
@ -1074,7 +1027,6 @@ pub fn can_problem<'b>(
]), ]),
]); ]);
title = "MULTIPLE LIST REST PATTERNS".to_string(); title = "MULTIPLE LIST REST PATTERNS".to_string();
severity = Severity::RuntimeError;
} }
Problem::BadTypeArguments { Problem::BadTypeArguments {
symbol, symbol,
@ -1114,7 +1066,6 @@ pub fn can_problem<'b>(
} else { } else {
"TOO FEW TYPE ARGUMENTS".to_string() "TOO FEW TYPE ARGUMENTS".to_string()
}; };
severity = Severity::RuntimeError;
} }
Problem::UnappliedCrash { region } => { Problem::UnappliedCrash { region } => {
doc = alloc.stack([ doc = alloc.stack([
@ -1128,7 +1079,6 @@ pub fn can_problem<'b>(
]) ])
]); ]);
title = "UNAPPLIED CRASH".to_string(); title = "UNAPPLIED CRASH".to_string();
severity = Severity::RuntimeError;
} }
Problem::OverAppliedCrash { region } => { Problem::OverAppliedCrash { region } => {
doc = alloc.stack([ doc = alloc.stack([
@ -1144,7 +1094,6 @@ pub fn can_problem<'b>(
]), ]),
]); ]);
title = "OVERAPPLIED CRASH".to_string(); title = "OVERAPPLIED CRASH".to_string();
severity = Severity::RuntimeError;
} }
}; };

View file

@ -3,6 +3,7 @@ use std::path::PathBuf;
use bumpalo::Bump; use bumpalo::Bump;
use roc_module::symbol::{Interns, ModuleId, Symbol}; use roc_module::symbol::{Interns, ModuleId, Symbol};
use roc_parse::ast::Expr; use roc_parse::ast::Expr;
use roc_problem::Severity;
use roc_region::all::{LineColumnRegion, LineInfo, Region}; use roc_region::all::{LineColumnRegion, LineInfo, Region};
use roc_types::{ use roc_types::{
subs::{Subs, Variable}, subs::{Subs, Variable},
@ -154,7 +155,7 @@ impl<'a> Renderer<'a> {
title: "EXPECT FAILED".into(), title: "EXPECT FAILED".into(),
doc, doc,
filename: self.filename.clone(), filename: self.filename.clone(),
severity: crate::report::Severity::RuntimeError, severity: Severity::RuntimeError,
}; };
let mut buf = String::new(); let mut buf = String::new();
@ -225,7 +226,7 @@ impl<'a> Renderer<'a> {
title: "EXPECT PANICKED".into(), title: "EXPECT PANICKED".into(),
doc, doc,
filename: self.filename.clone(), filename: self.filename.clone(),
severity: crate::report::Severity::RuntimeError, severity: Severity::RuntimeError,
}; };
let mut buf = String::new(); let mut buf = String::new();

View file

@ -1,8 +1,9 @@
use roc_parse::parser::{ENumber, FileError, PList, SyntaxError}; use roc_parse::parser::{ENumber, FileError, PList, SyntaxError};
use roc_problem::Severity;
use roc_region::all::{LineColumn, LineColumnRegion, LineInfo, Position, Region}; use roc_region::all::{LineColumn, LineColumnRegion, LineInfo, Position, Region};
use std::path::PathBuf; use std::path::PathBuf;
use crate::report::{Report, RocDocAllocator, RocDocBuilder, Severity}; use crate::report::{Report, RocDocAllocator, RocDocBuilder};
use ven_pretty::DocAllocator; use ven_pretty::DocAllocator;
pub fn parse_problem<'a>( pub fn parse_problem<'a>(

View file

@ -1,5 +1,5 @@
use crate::error::canonicalize::{to_circular_def_doc, CIRCULAR_DEF}; use crate::error::canonicalize::{to_circular_def_doc, CIRCULAR_DEF};
use crate::report::{Annotation, Report, RocDocAllocator, RocDocBuilder, Severity}; use crate::report::{Annotation, Report, RocDocAllocator, RocDocBuilder};
use roc_can::expected::{Expected, PExpected}; use roc_can::expected::{Expected, PExpected};
use roc_collections::all::{HumanIndex, MutSet, SendMap}; use roc_collections::all::{HumanIndex, MutSet, SendMap};
use roc_collections::VecMap; use roc_collections::VecMap;
@ -8,6 +8,7 @@ use roc_exhaustive::{CtorName, ListArity};
use roc_module::called_via::{BinOp, CalledVia}; use roc_module::called_via::{BinOp, CalledVia};
use roc_module::ident::{IdentStr, Lowercase, TagName}; use roc_module::ident::{IdentStr, Lowercase, TagName};
use roc_module::symbol::Symbol; use roc_module::symbol::Symbol;
use roc_problem::Severity;
use roc_region::all::{LineInfo, Region}; use roc_region::all::{LineInfo, Region};
use roc_solve_problem::{ use roc_solve_problem::{
NotDerivableContext, NotDerivableDecode, NotDerivableEq, TypeError, UnderivableReason, NotDerivableContext, NotDerivableDecode, NotDerivableEq, TypeError, UnderivableReason,

View file

@ -1,6 +1,7 @@
use roc_module::ident::Ident; use roc_module::ident::Ident;
use roc_module::ident::{Lowercase, ModuleName, TagName, Uppercase}; use roc_module::ident::{Lowercase, ModuleName, TagName, Uppercase};
use roc_module::symbol::{Interns, ModuleId, PQModuleName, PackageQualified, Symbol}; use roc_module::symbol::{Interns, ModuleId, PQModuleName, PackageQualified, Symbol};
use roc_problem::Severity;
use roc_region::all::LineColumnRegion; use roc_region::all::LineColumnRegion;
use std::fmt; use std::fmt;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -99,18 +100,6 @@ pub fn pretty_header_with_path(title: &str, path: &Path) -> String {
header header
} }
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Severity {
/// This will cause a runtime error if some code get srun
/// (e.g. type mismatch, naming error)
RuntimeError,
/// This will never cause the code to misbehave,
/// but should be cleaned up
/// (e.g. unused def, unused import)
Warning,
}
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub enum RenderTarget { pub enum RenderTarget {
ColorTerminal, ColorTerminal,