const WHILE_PARSING_OR_MSG: &str = "while parsing this or-pattern starting here";
-/// Whether or not an or-pattern should be gated when occurring in the current context.
-#[derive(PartialEq, Clone, Copy)]
-pub enum GateOr {
- Yes,
- No,
-}
-
/// Whether or not to recover a `,` when parsing or-patterns.
#[derive(PartialEq, Copy, Clone)]
pub enum RecoverComma {
pub fn parse_pat_allow_top_alt(
&mut self,
expected: Expected,
- gate_or: GateOr,
rc: RecoverComma,
) -> PResult<'a, P<Pat>> {
- self.parse_pat_allow_top_alt_inner(expected, gate_or, rc).map(|(pat, _)| pat)
+ self.parse_pat_allow_top_alt_inner(expected, rc).map(|(pat, _)| pat)
}
/// Returns the pattern and a bool indicating whether we recovered from a trailing vert (true =
fn parse_pat_allow_top_alt_inner(
&mut self,
expected: Expected,
- gate_or: GateOr,
rc: RecoverComma,
) -> PResult<'a, (P<Pat>, bool)> {
// Keep track of whether we recovered from a trailing vert so that we can avoid duplicated
// Parse the first pattern (`p_0`).
let first_pat = self.parse_pat_no_top_alt(expected)?;
- self.maybe_recover_unexpected_comma(first_pat.span, rc, gate_or)?;
+ self.maybe_recover_unexpected_comma(first_pat.span, rc)?;
// If the next token is not a `|`,
// this is not an or-pattern and we should exit here.
// then we should really gate the leading `|`.
// This complicated procedure is done purely for diagnostics UX.
if let Some(leading_vert_span) = leading_vert_span {
- if gate_or == GateOr::Yes && self.sess.gated_spans.is_ungated(sym::or_patterns) {
- self.sess.gated_spans.gate(sym::or_patterns, leading_vert_span);
- }
-
// If there was a leading vert, treat this as an or-pattern. This improves
// diagnostics.
let span = leading_vert_span.to(self.prev_token.span);
err.span_label(lo, WHILE_PARSING_OR_MSG);
err
})?;
- self.maybe_recover_unexpected_comma(pat.span, rc, gate_or)?;
+ self.maybe_recover_unexpected_comma(pat.span, rc)?;
pats.push(pat);
}
let or_pattern_span = lo.to(self.prev_token.span);
- // Feature gate the or-pattern if instructed:
- if gate_or == GateOr::Yes {
- self.sess.gated_spans.gate(sym::or_patterns, or_pattern_span);
- }
-
Ok((self.mk_pat(or_pattern_span, PatKind::Or(pats)), trailing_vert))
}
pub(super) fn parse_pat_before_ty(
&mut self,
expected: Expected,
- gate_or: GateOr,
rc: RecoverComma,
syntax_loc: &str,
) -> PResult<'a, (P<Pat>, bool)> {
// We use `parse_pat_allow_top_alt` regardless of whether we actually want top-level
// or-patterns so that we can detect when a user tries to use it. This allows us to print a
// better error message.
- let (pat, trailing_vert) = self.parse_pat_allow_top_alt_inner(expected, gate_or, rc)?;
+ let (pat, trailing_vert) = self.parse_pat_allow_top_alt_inner(expected, rc)?;
let colon = self.eat(&token::Colon);
if let PatKind::Or(pats) = &pat.kind {
self.bump();
}
- self.parse_pat_before_ty(
- PARAM_EXPECTED,
- GateOr::No,
- RecoverComma::No,
- "function parameters",
- )
+ self.parse_pat_before_ty(PARAM_EXPECTED, RecoverComma::No, "function parameters")
}
/// Eat the or-pattern `|` separator.
/// Some special error handling for the "top-level" patterns in a match arm,
/// `for` loop, `let`, &c. (in contrast to subpatterns within such).
- fn maybe_recover_unexpected_comma(
- &mut self,
- lo: Span,
- rc: RecoverComma,
- gate_or: GateOr,
- ) -> PResult<'a, ()> {
+ fn maybe_recover_unexpected_comma(&mut self, lo: Span, rc: RecoverComma) -> PResult<'a, ()> {
if rc == RecoverComma::No || self.token != token::Comma {
return Ok(());
}
if let Ok(seq_snippet) = self.span_to_snippet(seq_span) {
const MSG: &str = "try adding parentheses to match on a tuple...";
- let or_suggestion =
- gate_or == GateOr::No || !self.sess.gated_spans.is_ungated(sym::or_patterns);
err.span_suggestion(
seq_span,
- if or_suggestion { MSG } else { MSG.trim_end_matches('.') },
+ MSG,
format!("({})", seq_snippet),
Applicability::MachineApplicable,
);
- if or_suggestion {
- err.span_suggestion(
- seq_span,
- "...or a vertical bar to match on multiple alternatives",
- seq_snippet.replace(",", " |"),
- Applicability::MachineApplicable,
- );
- }
+ err.span_suggestion(
+ seq_span,
+ "...or a vertical bar to match on multiple alternatives",
+ seq_snippet.replace(",", " |"),
+ Applicability::MachineApplicable,
+ );
}
Err(err)
}
} else if self.check(&token::OpenDelim(token::Bracket)) {
// Parse `[pat, pat,...]` as a slice pattern.
let (pats, _) = self.parse_delim_comma_seq(token::Bracket, |p| {
- p.parse_pat_allow_top_alt(None, GateOr::Yes, RecoverComma::No)
+ p.parse_pat_allow_top_alt(None, RecoverComma::No)
})?;
PatKind::Slice(pats)
} else if self.check(&token::DotDot) && !self.is_pat_range_end_start(1) {
/// Parse a tuple or parenthesis pattern.
fn parse_pat_tuple_or_parens(&mut self) -> PResult<'a, PatKind> {
- let (fields, trailing_comma) = self.parse_paren_comma_seq(|p| {
- p.parse_pat_allow_top_alt(None, GateOr::Yes, RecoverComma::No)
- })?;
+ let (fields, trailing_comma) =
+ self.parse_paren_comma_seq(|p| p.parse_pat_allow_top_alt(None, RecoverComma::No))?;
// Here, `(pat,)` is a tuple pattern.
// For backward compatibility, `(..)` is a tuple pattern as well.
if qself.is_some() {
return self.error_qpath_before_pat(&path, "(");
}
- let (fields, _) = self.parse_paren_comma_seq(|p| {
- p.parse_pat_allow_top_alt(None, GateOr::Yes, RecoverComma::No)
- })?;
+ let (fields, _) =
+ self.parse_paren_comma_seq(|p| p.parse_pat_allow_top_alt(None, RecoverComma::No))?;
Ok(PatKind::TupleStruct(path, fields))
}
// Parsing a pattern of the form `fieldname: pat`.
let fieldname = self.parse_field_name()?;
self.bump();
- let pat = self.parse_pat_allow_top_alt(None, GateOr::Yes, RecoverComma::No)?;
+ let pat = self.parse_pat_allow_top_alt(None, RecoverComma::No)?;
hi = pat.span;
(pat, fieldname, false)
} else {