stabilize or_patterns
This commit is contained in:
parent
f5f33ec0e0
commit
db5629adcb
36 changed files with 59 additions and 97 deletions
|
@ -34,7 +34,7 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(label_break_value)]
|
#![feature(label_break_value)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
//! in the HIR, especially for multiple identifiers.
|
//! in the HIR, especially for multiple identifiers.
|
||||||
|
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
|
|
|
@ -686,7 +686,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
|
||||||
"to use an async block, remove the `||`: `async {`"
|
"to use an async block, remove the `||`: `async {`"
|
||||||
);
|
);
|
||||||
gate_all!(generators, "yield syntax is experimental");
|
gate_all!(generators, "yield syntax is experimental");
|
||||||
gate_all!(or_patterns, "or-patterns syntax is experimental");
|
|
||||||
gate_all!(raw_ref_op, "raw address of syntax is experimental");
|
gate_all!(raw_ref_op, "raw address of syntax is experimental");
|
||||||
gate_all!(const_trait_bound_opt_out, "`?const` on trait bounds is experimental");
|
gate_all!(const_trait_bound_opt_out, "`?const` on trait bounds is experimental");
|
||||||
gate_all!(const_trait_impl, "const trait impls are experimental");
|
gate_all!(const_trait_impl, "const trait impls are experimental");
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#![feature(bool_to_option)]
|
#![feature(bool_to_option)]
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
//! The goal is to move the definition of `MetaItem` and things that don't need to be in `syntax`
|
//! The goal is to move the definition of `MetaItem` and things that don't need to be in `syntax`
|
||||||
//! to this crate.
|
//! to this crate.
|
||||||
|
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate rustc_macros;
|
extern crate rustc_macros;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(decl_macro)]
|
#![feature(decl_macro)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![feature(proc_macro_internals)]
|
#![feature(proc_macro_internals)]
|
||||||
#![feature(proc_macro_quote)]
|
#![feature(proc_macro_quote)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#![feature(extern_types)]
|
#![feature(extern_types)]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
use back::write::{create_informational_target_machine, create_target_machine};
|
use back::write::{create_informational_target_machine, create_target_machine};
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#![feature(try_blocks)]
|
#![feature(try_blocks)]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![feature(associated_type_bounds)]
|
#![feature(associated_type_bounds)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
|
|
|
@ -22,7 +22,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_errors::{Applicability, PResult};
|
use rustc_errors::{Applicability, PResult};
|
||||||
use rustc_feature::Features;
|
use rustc_feature::Features;
|
||||||
use rustc_parse::parser::{AttemptLocalParseRecovery, ForceCollect, GateOr, Parser, RecoverComma};
|
use rustc_parse::parser::{AttemptLocalParseRecovery, ForceCollect, Parser, RecoverComma};
|
||||||
use rustc_parse::validate_attr;
|
use rustc_parse::validate_attr;
|
||||||
use rustc_session::lint::builtin::UNUSED_DOC_COMMENTS;
|
use rustc_session::lint::builtin::UNUSED_DOC_COMMENTS;
|
||||||
use rustc_session::lint::BuiltinLintDiagnostics;
|
use rustc_session::lint::BuiltinLintDiagnostics;
|
||||||
|
@ -917,7 +917,7 @@ pub fn parse_ast_fragment<'a>(
|
||||||
}
|
}
|
||||||
AstFragmentKind::Ty => AstFragment::Ty(this.parse_ty()?),
|
AstFragmentKind::Ty => AstFragment::Ty(this.parse_ty()?),
|
||||||
AstFragmentKind::Pat => {
|
AstFragmentKind::Pat => {
|
||||||
AstFragment::Pat(this.parse_pat_allow_top_alt(None, GateOr::Yes, RecoverComma::No)?)
|
AstFragment::Pat(this.parse_pat_allow_top_alt(None, RecoverComma::No)?)
|
||||||
}
|
}
|
||||||
AstFragmentKind::Arms
|
AstFragmentKind::Arms
|
||||||
| AstFragmentKind::Fields
|
| AstFragmentKind::Fields
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(decl_macro)]
|
#![feature(decl_macro)]
|
||||||
#![feature(destructuring_assignment)]
|
#![feature(destructuring_assignment)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![feature(proc_macro_diagnostic)]
|
#![feature(proc_macro_diagnostic)]
|
||||||
#![feature(proc_macro_internals)]
|
#![feature(proc_macro_internals)]
|
||||||
#![feature(proc_macro_span)]
|
#![feature(proc_macro_span)]
|
||||||
|
|
|
@ -277,6 +277,8 @@ declare_features! (
|
||||||
(accepted, min_const_generics, "1.51.0", Some(74878), None),
|
(accepted, min_const_generics, "1.51.0", Some(74878), None),
|
||||||
/// The `unsafe_op_in_unsafe_fn` lint (allowed by default): no longer treat an unsafe function as an unsafe block.
|
/// The `unsafe_op_in_unsafe_fn` lint (allowed by default): no longer treat an unsafe function as an unsafe block.
|
||||||
(accepted, unsafe_block_in_unsafe_fn, "1.51.0", Some(71668), None),
|
(accepted, unsafe_block_in_unsafe_fn, "1.51.0", Some(71668), None),
|
||||||
|
/// Allows the use of or-patterns (e.g., `0 | 1`).
|
||||||
|
(accepted, or_patterns, "1.53.0", Some(54883), None),
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// feature-group-end: accepted features
|
// feature-group-end: accepted features
|
||||||
|
|
|
@ -488,9 +488,6 @@ declare_features! (
|
||||||
/// Allows `impl Trait` to be used inside type aliases (RFC 2515).
|
/// Allows `impl Trait` to be used inside type aliases (RFC 2515).
|
||||||
(active, type_alias_impl_trait, "1.38.0", Some(63063), None),
|
(active, type_alias_impl_trait, "1.38.0", Some(63063), None),
|
||||||
|
|
||||||
/// Allows the use of or-patterns (e.g., `0 | 1`).
|
|
||||||
(active, or_patterns, "1.38.0", Some(54883), None),
|
|
||||||
|
|
||||||
/// Allows the definition of `const extern fn` and `const unsafe extern fn`.
|
/// Allows the definition of `const extern fn` and `const unsafe extern fn`.
|
||||||
(active, const_extern_fn, "1.40.0", Some(64926), None),
|
(active, const_extern_fn, "1.40.0", Some(64926), None),
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#![feature(extended_key_value_attributes)]
|
#![feature(extended_key_value_attributes)]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(once_cell)]
|
#![feature(once_cell)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#![feature(const_panic)]
|
#![feature(const_panic)]
|
||||||
#![feature(extend_one)]
|
#![feature(extend_one)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(control_flow_enum)]
|
#![feature(control_flow_enum)]
|
||||||
#![recursion_limit = "512"] // For rustdoc
|
#![recursion_limit = "512"] // For rustdoc
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#![feature(iter_order_by)]
|
#![feature(iter_order_by)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![feature(half_open_range_patterns)]
|
#![feature(half_open_range_patterns)]
|
||||||
#![feature(exclusive_range_pattern)]
|
#![feature(exclusive_range_pattern)]
|
||||||
#![feature(control_flow_enum)]
|
#![feature(control_flow_enum)]
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(once_cell)]
|
#![feature(once_cell)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![feature(proc_macro_internals)]
|
#![feature(proc_macro_internals)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
#![feature(stmt_expr_attributes)]
|
#![feature(stmt_expr_attributes)]
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
#![feature(extern_types)]
|
#![feature(extern_types)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(once_cell)]
|
#![feature(once_cell)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
#![feature(trusted_len)]
|
#![feature(trusted_len)]
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
|
|
|
@ -27,7 +27,7 @@ Rust MIR: a lowered representation of Rust.
|
||||||
#![feature(stmt_expr_attributes)]
|
#![feature(stmt_expr_attributes)]
|
||||||
#![feature(trait_alias)]
|
#![feature(trait_alias)]
|
||||||
#![feature(option_get_or_insert_default)]
|
#![feature(option_get_or_insert_default)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![feature(once_cell)]
|
#![feature(once_cell)]
|
||||||
#![feature(control_flow_enum)]
|
#![feature(control_flow_enum)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(bool_to_option)]
|
#![feature(bool_to_option)]
|
||||||
#![feature(once_cell)]
|
#![feature(once_cell)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(bindings_after_at)]
|
#![feature(bindings_after_at)]
|
||||||
#![feature(iter_order_by)]
|
#![feature(iter_order_by)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::pat::{GateOr, RecoverComma, PARAM_EXPECTED};
|
use super::pat::{RecoverComma, PARAM_EXPECTED};
|
||||||
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
|
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
|
||||||
use super::{AttrWrapper, BlockMode, ForceCollect, Parser, PathStyle, Restrictions, TokenType};
|
use super::{AttrWrapper, BlockMode, ForceCollect, Parser, PathStyle, Restrictions, TokenType};
|
||||||
use super::{SemiColonMode, SeqSep, TokenExpectType, TrailingToken};
|
use super::{SemiColonMode, SeqSep, TokenExpectType, TrailingToken};
|
||||||
|
@ -1803,7 +1803,7 @@ impl<'a> Parser<'a> {
|
||||||
/// The `let` token has already been eaten.
|
/// The `let` token has already been eaten.
|
||||||
fn parse_let_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
|
fn parse_let_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
|
||||||
let lo = self.prev_token.span;
|
let lo = self.prev_token.span;
|
||||||
let pat = self.parse_pat_allow_top_alt(None, GateOr::No, RecoverComma::Yes)?;
|
let pat = self.parse_pat_allow_top_alt(None, RecoverComma::Yes)?;
|
||||||
self.expect(&token::Eq)?;
|
self.expect(&token::Eq)?;
|
||||||
let expr = self.with_res(self.restrictions | Restrictions::NO_STRUCT_LITERAL, |this| {
|
let expr = self.with_res(self.restrictions | Restrictions::NO_STRUCT_LITERAL, |this| {
|
||||||
this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into())
|
this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into())
|
||||||
|
@ -1866,7 +1866,7 @@ impl<'a> Parser<'a> {
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let pat = self.parse_pat_allow_top_alt(None, GateOr::Yes, RecoverComma::Yes)?;
|
let pat = self.parse_pat_allow_top_alt(None, RecoverComma::Yes)?;
|
||||||
if !self.eat_keyword(kw::In) {
|
if !self.eat_keyword(kw::In) {
|
||||||
self.error_missing_in_for_loop();
|
self.error_missing_in_for_loop();
|
||||||
}
|
}
|
||||||
|
@ -2073,7 +2073,7 @@ impl<'a> Parser<'a> {
|
||||||
let attrs = self.parse_outer_attributes()?;
|
let attrs = self.parse_outer_attributes()?;
|
||||||
self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
|
self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
|
||||||
let lo = this.token.span;
|
let lo = this.token.span;
|
||||||
let pat = this.parse_pat_allow_top_alt(None, GateOr::No, RecoverComma::Yes)?;
|
let pat = this.parse_pat_allow_top_alt(None, RecoverComma::Yes)?;
|
||||||
let guard = if this.eat_keyword(kw::If) {
|
let guard = if this.eat_keyword(kw::If) {
|
||||||
let if_span = this.prev_token.span;
|
let if_span = this.prev_token.span;
|
||||||
let cond = this.parse_expr()?;
|
let cond = this.parse_expr()?;
|
||||||
|
|
|
@ -14,7 +14,7 @@ use crate::lexer::UnmatchedBrace;
|
||||||
pub use attr_wrapper::AttrWrapper;
|
pub use attr_wrapper::AttrWrapper;
|
||||||
pub use diagnostics::AttemptLocalParseRecovery;
|
pub use diagnostics::AttemptLocalParseRecovery;
|
||||||
use diagnostics::Error;
|
use diagnostics::Error;
|
||||||
pub use pat::{GateOr, RecoverComma};
|
pub use pat::RecoverComma;
|
||||||
pub use path::PathStyle;
|
pub use path::PathStyle;
|
||||||
|
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
|
|
|
@ -4,7 +4,7 @@ use rustc_ast_pretty::pprust;
|
||||||
use rustc_errors::PResult;
|
use rustc_errors::PResult;
|
||||||
use rustc_span::symbol::{kw, Ident};
|
use rustc_span::symbol::{kw, Ident};
|
||||||
|
|
||||||
use crate::parser::pat::{GateOr, RecoverComma};
|
use crate::parser::pat::RecoverComma;
|
||||||
use crate::parser::{FollowedByType, ForceCollect, Parser, PathStyle};
|
use crate::parser::{FollowedByType, ForceCollect, Parser, PathStyle};
|
||||||
|
|
||||||
impl<'a> Parser<'a> {
|
impl<'a> Parser<'a> {
|
||||||
|
@ -122,7 +122,7 @@ impl<'a> Parser<'a> {
|
||||||
token::NtPat(self.collect_tokens_no_attrs(|this| match kind {
|
token::NtPat(self.collect_tokens_no_attrs(|this| match kind {
|
||||||
NonterminalKind::Pat2018 { .. } => this.parse_pat_no_top_alt(None),
|
NonterminalKind::Pat2018 { .. } => this.parse_pat_no_top_alt(None),
|
||||||
NonterminalKind::Pat2021 { .. } => {
|
NonterminalKind::Pat2021 { .. } => {
|
||||||
this.parse_pat_allow_top_alt(None, GateOr::Yes, RecoverComma::No)
|
this.parse_pat_allow_top_alt(None, RecoverComma::No)
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
})?)
|
})?)
|
||||||
|
|
|
@ -17,13 +17,6 @@ pub(super) const PARAM_EXPECTED: Expected = Some("parameter name");
|
||||||
|
|
||||||
const WHILE_PARSING_OR_MSG: &str = "while parsing this or-pattern starting here";
|
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.
|
/// Whether or not to recover a `,` when parsing or-patterns.
|
||||||
#[derive(PartialEq, Copy, Clone)]
|
#[derive(PartialEq, Copy, Clone)]
|
||||||
pub enum RecoverComma {
|
pub enum RecoverComma {
|
||||||
|
@ -64,10 +57,9 @@ impl<'a> Parser<'a> {
|
||||||
pub fn parse_pat_allow_top_alt(
|
pub fn parse_pat_allow_top_alt(
|
||||||
&mut self,
|
&mut self,
|
||||||
expected: Expected,
|
expected: Expected,
|
||||||
gate_or: GateOr,
|
|
||||||
rc: RecoverComma,
|
rc: RecoverComma,
|
||||||
) -> PResult<'a, P<Pat>> {
|
) -> 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 =
|
/// Returns the pattern and a bool indicating whether we recovered from a trailing vert (true =
|
||||||
|
@ -75,7 +67,6 @@ impl<'a> Parser<'a> {
|
||||||
fn parse_pat_allow_top_alt_inner(
|
fn parse_pat_allow_top_alt_inner(
|
||||||
&mut self,
|
&mut self,
|
||||||
expected: Expected,
|
expected: Expected,
|
||||||
gate_or: GateOr,
|
|
||||||
rc: RecoverComma,
|
rc: RecoverComma,
|
||||||
) -> PResult<'a, (P<Pat>, bool)> {
|
) -> PResult<'a, (P<Pat>, bool)> {
|
||||||
// Keep track of whether we recovered from a trailing vert so that we can avoid duplicated
|
// Keep track of whether we recovered from a trailing vert so that we can avoid duplicated
|
||||||
|
@ -90,7 +81,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
// Parse the first pattern (`p_0`).
|
// Parse the first pattern (`p_0`).
|
||||||
let first_pat = self.parse_pat_no_top_alt(expected)?;
|
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 `|`,
|
// If the next token is not a `|`,
|
||||||
// this is not an or-pattern and we should exit here.
|
// this is not an or-pattern and we should exit here.
|
||||||
|
@ -99,10 +90,6 @@ impl<'a> Parser<'a> {
|
||||||
// then we should really gate the leading `|`.
|
// then we should really gate the leading `|`.
|
||||||
// This complicated procedure is done purely for diagnostics UX.
|
// This complicated procedure is done purely for diagnostics UX.
|
||||||
if let Some(leading_vert_span) = leading_vert_span {
|
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
|
// If there was a leading vert, treat this as an or-pattern. This improves
|
||||||
// diagnostics.
|
// diagnostics.
|
||||||
let span = leading_vert_span.to(self.prev_token.span);
|
let span = leading_vert_span.to(self.prev_token.span);
|
||||||
|
@ -128,16 +115,11 @@ impl<'a> Parser<'a> {
|
||||||
err.span_label(lo, WHILE_PARSING_OR_MSG);
|
err.span_label(lo, WHILE_PARSING_OR_MSG);
|
||||||
err
|
err
|
||||||
})?;
|
})?;
|
||||||
self.maybe_recover_unexpected_comma(pat.span, rc, gate_or)?;
|
self.maybe_recover_unexpected_comma(pat.span, rc)?;
|
||||||
pats.push(pat);
|
pats.push(pat);
|
||||||
}
|
}
|
||||||
let or_pattern_span = lo.to(self.prev_token.span);
|
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))
|
Ok((self.mk_pat(or_pattern_span, PatKind::Or(pats)), trailing_vert))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,14 +134,13 @@ impl<'a> Parser<'a> {
|
||||||
pub(super) fn parse_pat_before_ty(
|
pub(super) fn parse_pat_before_ty(
|
||||||
&mut self,
|
&mut self,
|
||||||
expected: Expected,
|
expected: Expected,
|
||||||
gate_or: GateOr,
|
|
||||||
rc: RecoverComma,
|
rc: RecoverComma,
|
||||||
syntax_loc: &str,
|
syntax_loc: &str,
|
||||||
) -> PResult<'a, (P<Pat>, bool)> {
|
) -> PResult<'a, (P<Pat>, bool)> {
|
||||||
// We use `parse_pat_allow_top_alt` regardless of whether we actually want top-level
|
// 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
|
// or-patterns so that we can detect when a user tries to use it. This allows us to print a
|
||||||
// better error message.
|
// 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);
|
let colon = self.eat(&token::Colon);
|
||||||
|
|
||||||
if let PatKind::Or(pats) = &pat.kind {
|
if let PatKind::Or(pats) = &pat.kind {
|
||||||
|
@ -213,12 +194,7 @@ impl<'a> Parser<'a> {
|
||||||
self.bump();
|
self.bump();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.parse_pat_before_ty(
|
self.parse_pat_before_ty(PARAM_EXPECTED, RecoverComma::No, "function parameters")
|
||||||
PARAM_EXPECTED,
|
|
||||||
GateOr::No,
|
|
||||||
RecoverComma::No,
|
|
||||||
"function parameters",
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Eat the or-pattern `|` separator.
|
/// Eat the or-pattern `|` separator.
|
||||||
|
@ -287,12 +263,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
/// Some special error handling for the "top-level" patterns in a match arm,
|
/// Some special error handling for the "top-level" patterns in a match arm,
|
||||||
/// `for` loop, `let`, &c. (in contrast to subpatterns within such).
|
/// `for` loop, `let`, &c. (in contrast to subpatterns within such).
|
||||||
fn maybe_recover_unexpected_comma(
|
fn maybe_recover_unexpected_comma(&mut self, lo: Span, rc: RecoverComma) -> PResult<'a, ()> {
|
||||||
&mut self,
|
|
||||||
lo: Span,
|
|
||||||
rc: RecoverComma,
|
|
||||||
gate_or: GateOr,
|
|
||||||
) -> PResult<'a, ()> {
|
|
||||||
if rc == RecoverComma::No || self.token != token::Comma {
|
if rc == RecoverComma::No || self.token != token::Comma {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -313,22 +284,18 @@ impl<'a> Parser<'a> {
|
||||||
if let Ok(seq_snippet) = self.span_to_snippet(seq_span) {
|
if let Ok(seq_snippet) = self.span_to_snippet(seq_span) {
|
||||||
const MSG: &str = "try adding parentheses to match on a tuple...";
|
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(
|
err.span_suggestion(
|
||||||
seq_span,
|
seq_span,
|
||||||
if or_suggestion { MSG } else { MSG.trim_end_matches('.') },
|
MSG,
|
||||||
format!("({})", seq_snippet),
|
format!("({})", seq_snippet),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
if or_suggestion {
|
err.span_suggestion(
|
||||||
err.span_suggestion(
|
seq_span,
|
||||||
seq_span,
|
"...or a vertical bar to match on multiple alternatives",
|
||||||
"...or a vertical bar to match on multiple alternatives",
|
seq_snippet.replace(",", " |"),
|
||||||
seq_snippet.replace(",", " |"),
|
Applicability::MachineApplicable,
|
||||||
Applicability::MachineApplicable,
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Err(err)
|
Err(err)
|
||||||
}
|
}
|
||||||
|
@ -383,7 +350,7 @@ impl<'a> Parser<'a> {
|
||||||
} else if self.check(&token::OpenDelim(token::Bracket)) {
|
} else if self.check(&token::OpenDelim(token::Bracket)) {
|
||||||
// Parse `[pat, pat,...]` as a slice pattern.
|
// Parse `[pat, pat,...]` as a slice pattern.
|
||||||
let (pats, _) = self.parse_delim_comma_seq(token::Bracket, |p| {
|
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)
|
PatKind::Slice(pats)
|
||||||
} else if self.check(&token::DotDot) && !self.is_pat_range_end_start(1) {
|
} else if self.check(&token::DotDot) && !self.is_pat_range_end_start(1) {
|
||||||
|
@ -596,9 +563,8 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
/// Parse a tuple or parenthesis pattern.
|
/// Parse a tuple or parenthesis pattern.
|
||||||
fn parse_pat_tuple_or_parens(&mut self) -> PResult<'a, PatKind> {
|
fn parse_pat_tuple_or_parens(&mut self) -> PResult<'a, PatKind> {
|
||||||
let (fields, trailing_comma) = self.parse_paren_comma_seq(|p| {
|
let (fields, trailing_comma) =
|
||||||
p.parse_pat_allow_top_alt(None, GateOr::Yes, RecoverComma::No)
|
self.parse_paren_comma_seq(|p| p.parse_pat_allow_top_alt(None, RecoverComma::No))?;
|
||||||
})?;
|
|
||||||
|
|
||||||
// Here, `(pat,)` is a tuple pattern.
|
// Here, `(pat,)` is a tuple pattern.
|
||||||
// For backward compatibility, `(..)` is a tuple pattern as well.
|
// For backward compatibility, `(..)` is a tuple pattern as well.
|
||||||
|
@ -911,9 +877,8 @@ impl<'a> Parser<'a> {
|
||||||
if qself.is_some() {
|
if qself.is_some() {
|
||||||
return self.error_qpath_before_pat(&path, "(");
|
return self.error_qpath_before_pat(&path, "(");
|
||||||
}
|
}
|
||||||
let (fields, _) = self.parse_paren_comma_seq(|p| {
|
let (fields, _) =
|
||||||
p.parse_pat_allow_top_alt(None, GateOr::Yes, RecoverComma::No)
|
self.parse_paren_comma_seq(|p| p.parse_pat_allow_top_alt(None, RecoverComma::No))?;
|
||||||
})?;
|
|
||||||
Ok(PatKind::TupleStruct(path, fields))
|
Ok(PatKind::TupleStruct(path, fields))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1079,7 +1044,7 @@ impl<'a> Parser<'a> {
|
||||||
// Parsing a pattern of the form `fieldname: pat`.
|
// Parsing a pattern of the form `fieldname: pat`.
|
||||||
let fieldname = self.parse_field_name()?;
|
let fieldname = self.parse_field_name()?;
|
||||||
self.bump();
|
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;
|
hi = pat.span;
|
||||||
(pat, fieldname, false)
|
(pat, fieldname, false)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use super::attr::DEFAULT_INNER_ATTR_FORBIDDEN;
|
use super::attr::DEFAULT_INNER_ATTR_FORBIDDEN;
|
||||||
use super::diagnostics::{AttemptLocalParseRecovery, Error};
|
use super::diagnostics::{AttemptLocalParseRecovery, Error};
|
||||||
use super::expr::LhsExpr;
|
use super::expr::LhsExpr;
|
||||||
use super::pat::{GateOr, RecoverComma};
|
use super::pat::RecoverComma;
|
||||||
use super::path::PathStyle;
|
use super::path::PathStyle;
|
||||||
use super::TrailingToken;
|
use super::TrailingToken;
|
||||||
use super::{AttrWrapper, BlockMode, ForceCollect, Parser, Restrictions, SemiColonMode};
|
use super::{AttrWrapper, BlockMode, ForceCollect, Parser, Restrictions, SemiColonMode};
|
||||||
|
@ -221,8 +221,7 @@ impl<'a> Parser<'a> {
|
||||||
/// Parses a local variable declaration.
|
/// Parses a local variable declaration.
|
||||||
fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P<Local>> {
|
fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P<Local>> {
|
||||||
let lo = self.prev_token.span;
|
let lo = self.prev_token.span;
|
||||||
let (pat, colon) =
|
let (pat, colon) = self.parse_pat_before_ty(None, RecoverComma::Yes, "`let` bindings")?;
|
||||||
self.parse_pat_before_ty(None, GateOr::Yes, RecoverComma::Yes, "`let` bindings")?;
|
|
||||||
|
|
||||||
let (err, ty) = if colon {
|
let (err, ty) = if colon {
|
||||||
// Save the state of the parser before parsing type normally, in case there is a `:`
|
// Save the state of the parser before parsing type normally, in case there is a `:`
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
test(attr(deny(warnings)))
|
test(attr(deny(warnings)))
|
||||||
)]
|
)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![feature(bool_to_option)]
|
#![feature(bool_to_option)]
|
||||||
|
|
||||||
pub use Alignment::*;
|
pub use Alignment::*;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![feature(control_flow_enum)]
|
#![feature(control_flow_enum)]
|
||||||
#![feature(try_blocks)]
|
#![feature(try_blocks)]
|
||||||
#![feature(associated_type_defaults)]
|
#![feature(associated_type_defaults)]
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(format_args_capture)]
|
#![feature(format_args_capture)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
pub use rustc_hir::def::{Namespace, PerNS};
|
pub use rustc_hir::def::{Namespace, PerNS};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
mod dump_visitor;
|
mod dump_visitor;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(once_cell)]
|
#![feature(once_cell)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
|
@ -90,7 +90,7 @@
|
||||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![feature(control_flow_enum)]
|
#![feature(control_flow_enum)]
|
||||||
#![recursion_limit = "512"] // For rustdoc
|
#![recursion_limit = "512"] // For rustdoc
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ This API is completely unstable and subject to change.
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(is_sorted)]
|
#![feature(is_sorted)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(or_patterns)]
|
#![cfg_attr(bootstrap, feature(or_patterns))]
|
||||||
#![feature(try_blocks)]
|
#![feature(try_blocks)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(slice_partition_dedup)]
|
#![feature(slice_partition_dedup)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue