1
Fork 0

Disallow &a..=b and box a..=b in pattern.

They are disallowed because they have different precedence than
expressions. I assume parenthesis in pattern will be soon stabilized and
thus write that as suggestion directly.
This commit is contained in:
kennytm 2018-03-03 06:05:54 +08:00
parent a4d80336c9
commit 6399d16cfd
No known key found for this signature in database
GPG key ID: FEF6C8051D0E013C
5 changed files with 131 additions and 2 deletions

View file

@ -3804,6 +3804,12 @@ impl<'a> Parser<'a> {
/// Parse a pattern.
pub fn parse_pat(&mut self) -> PResult<'a, P<Pat>> {
self.parse_pat_with_range_pat(true)
}
/// Parse a pattern, with a setting whether modern range patterns e.g. `a..=b`, `a..b` are
/// allowed.
fn parse_pat_with_range_pat(&mut self, allow_range_pat: bool) -> PResult<'a, P<Pat>> {
maybe_whole!(self, NtPat, |x| x);
let lo = self.span;
@ -3824,7 +3830,7 @@ impl<'a> Parser<'a> {
err.span_label(self.span, "unexpected lifetime");
return Err(err);
}
let subpat = self.parse_pat()?;
let subpat = self.parse_pat_with_range_pat(false)?;
pat = PatKind::Ref(subpat, mutbl);
}
token::OpenDelim(token::Paren) => {
@ -3863,7 +3869,7 @@ impl<'a> Parser<'a> {
pat = self.parse_pat_ident(BindingMode::ByRef(mutbl))?;
} else if self.eat_keyword(keywords::Box) {
// Parse box pat
let subpat = self.parse_pat()?;
let subpat = self.parse_pat_with_range_pat(false)?;
pat = PatKind::Box(subpat);
} else if self.token.is_ident() && !self.token.is_reserved_ident() &&
self.parse_as_ident() {
@ -3968,6 +3974,25 @@ impl<'a> Parser<'a> {
let pat = Pat { node: pat, span: lo.to(self.prev_span), id: ast::DUMMY_NODE_ID };
let pat = self.maybe_recover_from_bad_qpath(pat, true)?;
if !allow_range_pat {
match pat.node {
PatKind::Range(_, _, RangeEnd::Included(RangeSyntax::DotDotDot)) => {}
PatKind::Range(..) => {
let mut err = self.struct_span_err(
pat.span,
"the range pattern here has ambiguous interpretation",
);
err.span_suggestion(
pat.span,
"add parentheses to clarify the precedence",
format!("({})", pprust::pat_to_string(&pat)),
);
return Err(err);
}
_ => {}
}
}
Ok(P(pat))
}