diff --git a/compiler/can/src/pattern.rs b/compiler/can/src/pattern.rs index c8a5bb1969..97877b208b 100644 --- a/compiler/can/src/pattern.rs +++ b/compiler/can/src/pattern.rs @@ -175,14 +175,12 @@ pub fn canonicalize_pattern<'a>( } Ok(float) => Pattern::FloatLiteral(float), }, - ptype @ DefExpr | ptype @ TopLevelDef | ptype @ FunctionArg => { - unsupported_pattern(env, ptype, region) - } + ptype => unsupported_pattern(env, ptype, region), }, Underscore => match pattern_type { WhenBranch | FunctionArg => Pattern::Underscore, - ptype @ DefExpr | ptype @ TopLevelDef => unsupported_pattern(env, ptype, region), + ptype => unsupported_pattern(env, ptype, region), }, NumLiteral(string) => match pattern_type { @@ -193,9 +191,7 @@ pub fn canonicalize_pattern<'a>( } Ok(int) => Pattern::NumLiteral(var_store.fresh(), int), }, - ptype @ DefExpr | ptype @ TopLevelDef | ptype @ FunctionArg => { - unsupported_pattern(env, ptype, region) - } + ptype => unsupported_pattern(env, ptype, region), }, NonBase10Literal { @@ -216,19 +212,20 @@ pub fn canonicalize_pattern<'a>( } } }, - ptype @ DefExpr | ptype @ TopLevelDef | ptype @ FunctionArg => { - unsupported_pattern(env, ptype, region) - } + ptype => unsupported_pattern(env, ptype, region), }, - StrLiteral(_string) => match pattern_type { + StrLiteral(string) => match pattern_type { WhenBranch => { // TODO report whether string was malformed Pattern::StrLiteral((*string).into()) } - ptype @ DefExpr | ptype @ TopLevelDef | ptype @ FunctionArg => { - unsupported_pattern(env, ptype, region) - } + ptype => unsupported_pattern(env, ptype, region), + }, + + BlockStrLiteral(_lines) => match pattern_type { + WhenBranch => todo!("TODO block string literal pattern"), + ptype => unsupported_pattern(env, ptype, region), }, SpaceBefore(sub_pattern, _) | SpaceAfter(sub_pattern, _) | Nested(sub_pattern) => { @@ -296,7 +293,7 @@ pub fn canonicalize_pattern<'a>( }, }); } - _ => panic!("invalid pattern in record"), + _ => unreachable!("Any other pattern should have given a parse error"), } } @@ -312,7 +309,15 @@ pub fn canonicalize_pattern<'a>( unreachable!("should have been handled in RecordDestructure"); } - _ => panic!("TODO finish restoring can_pattern branch for {:?}", pattern), + Malformed(_str) => { + let problem = MalformedPatternProblem::Unknown; + malformed_pattern(env, problem, region) + } + + QualifiedIdentifier { .. } => { + let problem = MalformedPatternProblem::QualifiedIdentifier; + malformed_pattern(env, problem, region) + } }; Located { diff --git a/compiler/problem/src/can.rs b/compiler/problem/src/can.rs index fc494fcef1..2ace5df59b 100644 --- a/compiler/problem/src/can.rs +++ b/compiler/problem/src/can.rs @@ -92,7 +92,6 @@ pub enum RuntimeError { InvalidHex(std::num::ParseIntError, Box), InvalidOctal(std::num::ParseIntError, Box), InvalidBinary(std::num::ParseIntError, Box), - QualifiedPatternIdent(InlinableString), CircularDef(Vec, Vec<(Region /* pattern */, Region /* expr */)>), /// When the author specifies a type annotation but no implementation @@ -104,4 +103,6 @@ pub enum MalformedPatternProblem { MalformedInt, MalformedFloat, MalformedBase(Base), + Unknown, + QualifiedIdentifier, } diff --git a/compiler/reporting/src/error/canonicalize.rs b/compiler/reporting/src/error/canonicalize.rs index 5890a341fa..90f0d1cc0f 100644 --- a/compiler/reporting/src/error/canonicalize.rs +++ b/compiler/reporting/src/error/canonicalize.rs @@ -343,20 +343,33 @@ fn pretty_runtime_error<'b>( use roc_problem::can::MalformedPatternProblem::*; let name = match problem { - MalformedInt => "integer", - MalformedFloat => "float", - MalformedBase(Base::Hex) => "hex integer", - MalformedBase(Base::Binary) => "binary integer", - MalformedBase(Base::Octal) => "octal integer", + MalformedInt => " integer ", + MalformedFloat => " float ", + MalformedBase(Base::Hex) => " hex integer ", + MalformedBase(Base::Binary) => " binary integer ", + MalformedBase(Base::Octal) => " octal integer ", + Unknown => " ", + QualifiedIdentifier => " qualified ", + }; + + let hint = match problem { + MalformedInt | MalformedFloat | MalformedBase(_) => alloc + .hint() + .append(alloc.reflow("Learn more about number literals at TODO")), + Unknown => alloc.nil(), + QualifiedIdentifier => alloc.hint().append( + alloc.reflow("In patterns, only private and global tags can be qualified"), + ), }; alloc.stack(vec![ alloc.concat(vec![ - alloc.reflow("This "), + alloc.reflow("This"), alloc.text(name), - alloc.reflow(" pattern is malformed:"), + alloc.reflow("pattern is malformed:"), ]), alloc.region(region), + hint, ]) } diff --git a/compiler/reporting/tests/test_reporting.rs b/compiler/reporting/tests/test_reporting.rs index da8fa7ce0a..63fc5c0731 100644 --- a/compiler/reporting/tests/test_reporting.rs +++ b/compiler/reporting/tests/test_reporting.rs @@ -1486,6 +1486,8 @@ mod test_reporting { 2 ┆ 100A -> 3 ┆ ^^^^ + + Hint: Learn more about number literals at TODO "# ), ) @@ -1509,6 +1511,8 @@ mod test_reporting { 2 ┆ 2.X -> 3 ┆ ^^^ + + Hint: Learn more about number literals at TODO "# ), ) @@ -1532,6 +1536,8 @@ mod test_reporting { 2 ┆ 0xZ -> 3 ┆ ^^^ + + Hint: Learn more about number literals at TODO "# ), ) @@ -1555,6 +1561,8 @@ mod test_reporting { 2 ┆ 0o9 -> 3 ┆ ^^^ + + Hint: Learn more about number literals at TODO "# ), ) @@ -1578,6 +1586,8 @@ mod test_reporting { 2 ┆ 0b4 -> 3 ┆ ^^^ + + Hint: Learn more about number literals at TODO "# ), )