mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
cover all parsed patterns with an error message
but, some invalid patterns are not parsed as expected. See https://github.com/rtfeldman/roc/issues/399
This commit is contained in:
parent
0c7a4179aa
commit
b7d689226c
4 changed files with 53 additions and 24 deletions
|
@ -175,14 +175,12 @@ pub fn canonicalize_pattern<'a>(
|
||||||
}
|
}
|
||||||
Ok(float) => Pattern::FloatLiteral(float),
|
Ok(float) => Pattern::FloatLiteral(float),
|
||||||
},
|
},
|
||||||
ptype @ DefExpr | ptype @ TopLevelDef | ptype @ FunctionArg => {
|
ptype => unsupported_pattern(env, ptype, region),
|
||||||
unsupported_pattern(env, ptype, region)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
Underscore => match pattern_type {
|
Underscore => match pattern_type {
|
||||||
WhenBranch | FunctionArg => Pattern::Underscore,
|
WhenBranch | FunctionArg => Pattern::Underscore,
|
||||||
ptype @ DefExpr | ptype @ TopLevelDef => unsupported_pattern(env, ptype, region),
|
ptype => unsupported_pattern(env, ptype, region),
|
||||||
},
|
},
|
||||||
|
|
||||||
NumLiteral(string) => match pattern_type {
|
NumLiteral(string) => match pattern_type {
|
||||||
|
@ -193,9 +191,7 @@ pub fn canonicalize_pattern<'a>(
|
||||||
}
|
}
|
||||||
Ok(int) => Pattern::NumLiteral(var_store.fresh(), int),
|
Ok(int) => Pattern::NumLiteral(var_store.fresh(), int),
|
||||||
},
|
},
|
||||||
ptype @ DefExpr | ptype @ TopLevelDef | ptype @ FunctionArg => {
|
ptype => unsupported_pattern(env, ptype, region),
|
||||||
unsupported_pattern(env, ptype, region)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
NonBase10Literal {
|
NonBase10Literal {
|
||||||
|
@ -216,19 +212,20 @@ pub fn canonicalize_pattern<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ptype @ DefExpr | ptype @ TopLevelDef | ptype @ FunctionArg => {
|
ptype => unsupported_pattern(env, ptype, region),
|
||||||
unsupported_pattern(env, ptype, region)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
StrLiteral(_string) => match pattern_type {
|
StrLiteral(string) => match pattern_type {
|
||||||
WhenBranch => {
|
WhenBranch => {
|
||||||
// TODO report whether string was malformed
|
// TODO report whether string was malformed
|
||||||
Pattern::StrLiteral((*string).into())
|
Pattern::StrLiteral((*string).into())
|
||||||
}
|
}
|
||||||
ptype @ DefExpr | ptype @ TopLevelDef | ptype @ FunctionArg => {
|
ptype => unsupported_pattern(env, ptype, region),
|
||||||
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) => {
|
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");
|
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 {
|
Located {
|
||||||
|
|
|
@ -92,7 +92,6 @@ pub enum RuntimeError {
|
||||||
InvalidHex(std::num::ParseIntError, Box<str>),
|
InvalidHex(std::num::ParseIntError, Box<str>),
|
||||||
InvalidOctal(std::num::ParseIntError, Box<str>),
|
InvalidOctal(std::num::ParseIntError, Box<str>),
|
||||||
InvalidBinary(std::num::ParseIntError, Box<str>),
|
InvalidBinary(std::num::ParseIntError, Box<str>),
|
||||||
QualifiedPatternIdent(InlinableString),
|
|
||||||
CircularDef(Vec<Symbol>, Vec<(Region /* pattern */, Region /* expr */)>),
|
CircularDef(Vec<Symbol>, Vec<(Region /* pattern */, Region /* expr */)>),
|
||||||
|
|
||||||
/// When the author specifies a type annotation but no implementation
|
/// When the author specifies a type annotation but no implementation
|
||||||
|
@ -104,4 +103,6 @@ pub enum MalformedPatternProblem {
|
||||||
MalformedInt,
|
MalformedInt,
|
||||||
MalformedFloat,
|
MalformedFloat,
|
||||||
MalformedBase(Base),
|
MalformedBase(Base),
|
||||||
|
Unknown,
|
||||||
|
QualifiedIdentifier,
|
||||||
}
|
}
|
||||||
|
|
|
@ -343,20 +343,33 @@ fn pretty_runtime_error<'b>(
|
||||||
use roc_problem::can::MalformedPatternProblem::*;
|
use roc_problem::can::MalformedPatternProblem::*;
|
||||||
|
|
||||||
let name = match problem {
|
let name = match problem {
|
||||||
MalformedInt => "integer",
|
MalformedInt => " integer ",
|
||||||
MalformedFloat => "float",
|
MalformedFloat => " float ",
|
||||||
MalformedBase(Base::Hex) => "hex integer",
|
MalformedBase(Base::Hex) => " hex integer ",
|
||||||
MalformedBase(Base::Binary) => "binary integer",
|
MalformedBase(Base::Binary) => " binary integer ",
|
||||||
MalformedBase(Base::Octal) => "octal 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.stack(vec![
|
||||||
alloc.concat(vec![
|
alloc.concat(vec![
|
||||||
alloc.reflow("This "),
|
alloc.reflow("This"),
|
||||||
alloc.text(name),
|
alloc.text(name),
|
||||||
alloc.reflow(" pattern is malformed:"),
|
alloc.reflow("pattern is malformed:"),
|
||||||
]),
|
]),
|
||||||
alloc.region(region),
|
alloc.region(region),
|
||||||
|
hint,
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1486,6 +1486,8 @@ mod test_reporting {
|
||||||
|
|
||||||
2 ┆ 100A -> 3
|
2 ┆ 100A -> 3
|
||||||
┆ ^^^^
|
┆ ^^^^
|
||||||
|
|
||||||
|
Hint: Learn more about number literals at TODO
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -1509,6 +1511,8 @@ mod test_reporting {
|
||||||
|
|
||||||
2 ┆ 2.X -> 3
|
2 ┆ 2.X -> 3
|
||||||
┆ ^^^
|
┆ ^^^
|
||||||
|
|
||||||
|
Hint: Learn more about number literals at TODO
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -1532,6 +1536,8 @@ mod test_reporting {
|
||||||
|
|
||||||
2 ┆ 0xZ -> 3
|
2 ┆ 0xZ -> 3
|
||||||
┆ ^^^
|
┆ ^^^
|
||||||
|
|
||||||
|
Hint: Learn more about number literals at TODO
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -1555,6 +1561,8 @@ mod test_reporting {
|
||||||
|
|
||||||
2 ┆ 0o9 -> 3
|
2 ┆ 0o9 -> 3
|
||||||
┆ ^^^
|
┆ ^^^
|
||||||
|
|
||||||
|
Hint: Learn more about number literals at TODO
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -1578,6 +1586,8 @@ mod test_reporting {
|
||||||
|
|
||||||
2 ┆ 0b4 -> 3
|
2 ┆ 0b4 -> 3
|
||||||
┆ ^^^
|
┆ ^^^
|
||||||
|
|
||||||
|
Hint: Learn more about number literals at TODO
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue