aboutsummaryrefslogtreecommitdiff
path: root/vendor/syn/src/pat.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/syn/src/pat.rs')
-rw-r--r--vendor/syn/src/pat.rs917
1 files changed, 0 insertions, 917 deletions
diff --git a/vendor/syn/src/pat.rs b/vendor/syn/src/pat.rs
deleted file mode 100644
index ce6399d..0000000
--- a/vendor/syn/src/pat.rs
+++ /dev/null
@@ -1,917 +0,0 @@
-use super::*;
-use crate::punctuated::Punctuated;
-use proc_macro2::TokenStream;
-
-ast_enum_of_structs! {
- /// A pattern in a local binding, function signature, match expression, or
- /// various other places.
- ///
- /// # Syntax tree enum
- ///
- /// This type is a [syntax tree enum].
- ///
- /// [syntax tree enum]: Expr#syntax-tree-enums
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- #[non_exhaustive]
- pub enum Pat {
- /// A const block: `const { ... }`.
- Const(PatConst),
-
- /// A pattern that binds a new variable: `ref mut binding @ SUBPATTERN`.
- Ident(PatIdent),
-
- /// A literal pattern: `0`.
- Lit(PatLit),
-
- /// A macro in pattern position.
- Macro(PatMacro),
-
- /// A pattern that matches any one of a set of cases.
- Or(PatOr),
-
- /// A parenthesized pattern: `(A | B)`.
- Paren(PatParen),
-
- /// A path pattern like `Color::Red`, optionally qualified with a
- /// self-type.
- ///
- /// Unqualified path patterns can legally refer to variants, structs,
- /// constants or associated constants. Qualified path patterns like
- /// `<A>::B::C` and `<A as Trait>::B::C` can only legally refer to
- /// associated constants.
- Path(PatPath),
-
- /// A range pattern: `1..=2`.
- Range(PatRange),
-
- /// A reference pattern: `&mut var`.
- Reference(PatReference),
-
- /// The dots in a tuple or slice pattern: `[0, 1, ..]`.
- Rest(PatRest),
-
- /// A dynamically sized slice pattern: `[a, b, ref i @ .., y, z]`.
- Slice(PatSlice),
-
- /// A struct or struct variant pattern: `Variant { x, y, .. }`.
- Struct(PatStruct),
-
- /// A tuple pattern: `(a, b)`.
- Tuple(PatTuple),
-
- /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`.
- TupleStruct(PatTupleStruct),
-
- /// A type ascription pattern: `foo: f64`.
- Type(PatType),
-
- /// Tokens in pattern position not interpreted by Syn.
- Verbatim(TokenStream),
-
- /// A pattern that matches any value: `_`.
- Wild(PatWild),
-
- // For testing exhaustiveness in downstream code, use the following idiom:
- //
- // match pat {
- // #![cfg_attr(test, deny(non_exhaustive_omitted_patterns))]
- //
- // Pat::Box(pat) => {...}
- // Pat::Ident(pat) => {...}
- // ...
- // Pat::Wild(pat) => {...}
- //
- // _ => { /* some sane fallback */ }
- // }
- //
- // This way we fail your tests but don't break your library when adding
- // a variant. You will be notified by a test failure when a variant is
- // added, so that you can add code to handle it, but your library will
- // continue to compile and work for downstream users in the interim.
- }
-}
-
-ast_struct! {
- /// A pattern that binds a new variable: `ref mut binding @ SUBPATTERN`.
- ///
- /// It may also be a unit struct or struct variant (e.g. `None`), or a
- /// constant; these cannot be distinguished syntactically.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct PatIdent {
- pub attrs: Vec<Attribute>,
- pub by_ref: Option<Token![ref]>,
- pub mutability: Option<Token![mut]>,
- pub ident: Ident,
- pub subpat: Option<(Token![@], Box<Pat>)>,
- }
-}
-
-ast_struct! {
- /// A pattern that matches any one of a set of cases.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct PatOr {
- pub attrs: Vec<Attribute>,
- pub leading_vert: Option<Token![|]>,
- pub cases: Punctuated<Pat, Token![|]>,
- }
-}
-
-ast_struct! {
- /// A parenthesized pattern: `(A | B)`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct PatParen {
- pub attrs: Vec<Attribute>,
- pub paren_token: token::Paren,
- pub pat: Box<Pat>,
- }
-}
-
-ast_struct! {
- /// A reference pattern: `&mut var`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct PatReference {
- pub attrs: Vec<Attribute>,
- pub and_token: Token![&],
- pub mutability: Option<Token![mut]>,
- pub pat: Box<Pat>,
- }
-}
-
-ast_struct! {
- /// The dots in a tuple or slice pattern: `[0, 1, ..]`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct PatRest {
- pub attrs: Vec<Attribute>,
- pub dot2_token: Token![..],
- }
-}
-
-ast_struct! {
- /// A dynamically sized slice pattern: `[a, b, ref i @ .., y, z]`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct PatSlice {
- pub attrs: Vec<Attribute>,
- pub bracket_token: token::Bracket,
- pub elems: Punctuated<Pat, Token![,]>,
- }
-}
-
-ast_struct! {
- /// A struct or struct variant pattern: `Variant { x, y, .. }`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct PatStruct {
- pub attrs: Vec<Attribute>,
- pub qself: Option<QSelf>,
- pub path: Path,
- pub brace_token: token::Brace,
- pub fields: Punctuated<FieldPat, Token![,]>,
- pub rest: Option<PatRest>,
- }
-}
-
-ast_struct! {
- /// A tuple pattern: `(a, b)`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct PatTuple {
- pub attrs: Vec<Attribute>,
- pub paren_token: token::Paren,
- pub elems: Punctuated<Pat, Token![,]>,
- }
-}
-
-ast_struct! {
- /// A tuple struct or tuple variant pattern: `Variant(x, y, .., z)`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct PatTupleStruct {
- pub attrs: Vec<Attribute>,
- pub qself: Option<QSelf>,
- pub path: Path,
- pub paren_token: token::Paren,
- pub elems: Punctuated<Pat, Token![,]>,
- }
-}
-
-ast_struct! {
- /// A type ascription pattern: `foo: f64`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct PatType {
- pub attrs: Vec<Attribute>,
- pub pat: Box<Pat>,
- pub colon_token: Token![:],
- pub ty: Box<Type>,
- }
-}
-
-ast_struct! {
- /// A pattern that matches any value: `_`.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct PatWild {
- pub attrs: Vec<Attribute>,
- pub underscore_token: Token![_],
- }
-}
-
-ast_struct! {
- /// A single field in a struct pattern.
- ///
- /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` are treated
- /// the same as `x: x, y: ref y, z: ref mut z` but there is no colon token.
- #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
- pub struct FieldPat {
- pub attrs: Vec<Attribute>,
- pub member: Member,
- pub colon_token: Option<Token![:]>,
- pub pat: Box<Pat>,
- }
-}
-
-#[cfg(feature = "parsing")]
-pub(crate) mod parsing {
- use super::*;
- use crate::ext::IdentExt as _;
- use crate::parse::{Parse, ParseBuffer, ParseStream, Result};
- use crate::path;
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Pat {
- /// Parse a pattern that does _not_ involve `|` at the top level.
- ///
- /// This parser matches the behavior of the `$:pat_param` macro_rules
- /// matcher, and on editions prior to Rust 2021, the behavior of
- /// `$:pat`.
- ///
- /// In Rust syntax, some examples of where this syntax would occur are
- /// in the argument pattern of functions and closures. Patterns using
- /// `|` are not allowed to occur in these positions.
- ///
- /// ```compile_fail
- /// fn f(Some(_) | None: Option<T>) {
- /// let _ = |Some(_) | None: Option<T>| {};
- /// // ^^^^^^^^^^^^^^^^^^^^^^^^^??? :(
- /// }
- /// ```
- ///
- /// ```console
- /// error: top-level or-patterns are not allowed in function parameters
- /// --> src/main.rs:1:6
- /// |
- /// 1 | fn f(Some(_) | None: Option<T>) {
- /// | ^^^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(Some(_) | None)`
- /// ```
- pub fn parse_single(input: ParseStream) -> Result<Self> {
- let begin = input.fork();
- let lookahead = input.lookahead1();
- if lookahead.peek(Ident)
- && (input.peek2(Token![::])
- || input.peek2(Token![!])
- || input.peek2(token::Brace)
- || input.peek2(token::Paren)
- || input.peek2(Token![..]))
- || input.peek(Token![self]) && input.peek2(Token![::])
- || lookahead.peek(Token![::])
- || lookahead.peek(Token![<])
- || input.peek(Token![Self])
- || input.peek(Token![super])
- || input.peek(Token![crate])
- {
- pat_path_or_macro_or_struct_or_range(input)
- } else if lookahead.peek(Token![_]) {
- input.call(pat_wild).map(Pat::Wild)
- } else if input.peek(Token![box]) {
- pat_box(begin, input)
- } else if input.peek(Token![-]) || lookahead.peek(Lit) || lookahead.peek(Token![const])
- {
- pat_lit_or_range(input)
- } else if lookahead.peek(Token![ref])
- || lookahead.peek(Token![mut])
- || input.peek(Token![self])
- || input.peek(Ident)
- {
- input.call(pat_ident).map(Pat::Ident)
- } else if lookahead.peek(Token![&]) {
- input.call(pat_reference).map(Pat::Reference)
- } else if lookahead.peek(token::Paren) {
- input.call(pat_paren_or_tuple)
- } else if lookahead.peek(token::Bracket) {
- input.call(pat_slice).map(Pat::Slice)
- } else if lookahead.peek(Token![..]) && !input.peek(Token![...]) {
- pat_range_half_open(input)
- } else if lookahead.peek(Token![const]) {
- input.call(pat_const).map(Pat::Verbatim)
- } else {
- Err(lookahead.error())
- }
- }
-
- /// Parse a pattern, possibly involving `|`, but not a leading `|`.
- pub fn parse_multi(input: ParseStream) -> Result<Self> {
- multi_pat_impl(input, None)
- }
-
- /// Parse a pattern, possibly involving `|`, possibly including a
- /// leading `|`.
- ///
- /// This parser matches the behavior of the Rust 2021 edition's `$:pat`
- /// macro_rules matcher.
- ///
- /// In Rust syntax, an example of where this syntax would occur is in
- /// the pattern of a `match` arm, where the language permits an optional
- /// leading `|`, although it is not idiomatic to write one there in
- /// handwritten code.
- ///
- /// ```
- /// # let wat = None;
- /// match wat {
- /// | None | Some(false) => {}
- /// | Some(true) => {}
- /// }
- /// ```
- ///
- /// The compiler accepts it only to facilitate some situations in
- /// macro-generated code where a macro author might need to write:
- ///
- /// ```
- /// # macro_rules! doc {
- /// # ($value:expr, ($($conditions1:pat),*), ($($conditions2:pat),*), $then:expr) => {
- /// match $value {
- /// $(| $conditions1)* $(| $conditions2)* => $then
- /// }
- /// # };
- /// # }
- /// #
- /// # doc!(true, (true), (false), {});
- /// # doc!(true, (), (true, false), {});
- /// # doc!(true, (true, false), (), {});
- /// ```
- ///
- /// Expressing the same thing correctly in the case that either one (but
- /// not both) of `$conditions1` and `$conditions2` might be empty,
- /// without leading `|`, is complex.
- ///
- /// Use [`Pat::parse_multi`] instead if you are not intending to support
- /// macro-generated macro input.
- pub fn parse_multi_with_leading_vert(input: ParseStream) -> Result<Self> {
- let leading_vert: Option<Token![|]> = input.parse()?;
- multi_pat_impl(input, leading_vert)
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
- impl Parse for PatType {
- fn parse(input: ParseStream) -> Result<Self> {
- Ok(PatType {
- attrs: Vec::new(),
- pat: Box::new(Pat::parse_single(input)?),
- colon_token: input.parse()?,
- ty: input.parse()?,
- })
- }
- }
-
- fn multi_pat_impl(input: ParseStream, leading_vert: Option<Token![|]>) -> Result<Pat> {
- let mut pat = Pat::parse_single(input)?;
- if leading_vert.is_some()
- || input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=])
- {
- let mut cases = Punctuated::new();
- cases.push_value(pat);
- while input.peek(Token![|]) && !input.peek(Token![||]) && !input.peek(Token![|=]) {
- let punct = input.parse()?;
- cases.push_punct(punct);
- let pat = Pat::parse_single(input)?;
- cases.push_value(pat);
- }
- pat = Pat::Or(PatOr {
- attrs: Vec::new(),
- leading_vert,
- cases,
- });
- }
- Ok(pat)
- }
-
- fn pat_path_or_macro_or_struct_or_range(input: ParseStream) -> Result<Pat> {
- let (qself, path) = path::parsing::qpath(input, true)?;
-
- if qself.is_none()
- && input.peek(Token![!])
- && !input.peek(Token![!=])
- && path.is_mod_style()
- {
- let bang_token: Token![!] = input.parse()?;
- let (delimiter, tokens) = mac::parse_delimiter(input)?;
- return Ok(Pat::Macro(ExprMacro {
- attrs: Vec::new(),
- mac: Macro {
- path,
- bang_token,
- delimiter,
- tokens,
- },
- }));
- }
-
- if input.peek(token::Brace) {
- pat_struct(input, qself, path).map(Pat::Struct)
- } else if input.peek(token::Paren) {
- pat_tuple_struct(input, qself, path).map(Pat::TupleStruct)
- } else if input.peek(Token![..]) {
- pat_range(input, qself, path)
- } else {
- Ok(Pat::Path(ExprPath {
- attrs: Vec::new(),
- qself,
- path,
- }))
- }
- }
-
- fn pat_wild(input: ParseStream) -> Result<PatWild> {
- Ok(PatWild {
- attrs: Vec::new(),
- underscore_token: input.parse()?,
- })
- }
-
- fn pat_box(begin: ParseBuffer, input: ParseStream) -> Result<Pat> {
- input.parse::<Token![box]>()?;
- Pat::parse_single(input)?;
- Ok(Pat::Verbatim(verbatim::between(&begin, input)))
- }
-
- fn pat_ident(input: ParseStream) -> Result<PatIdent> {
- Ok(PatIdent {
- attrs: Vec::new(),
- by_ref: input.parse()?,
- mutability: input.parse()?,
- ident: input.call(Ident::parse_any)?,
- subpat: {
- if input.peek(Token![@]) {
- let at_token: Token![@] = input.parse()?;
- let subpat = Pat::parse_single(input)?;
- Some((at_token, Box::new(subpat)))
- } else {
- None
- }
- },
- })
- }
-
- fn pat_tuple_struct(
- input: ParseStream,
- qself: Option<QSelf>,
- path: Path,
- ) -> Result<PatTupleStruct> {
- let content;
- let paren_token = parenthesized!(content in input);
-
- let mut elems = Punctuated::new();
- while !content.is_empty() {
- let value = Pat::parse_multi_with_leading_vert(&content)?;
- elems.push_value(value);
- if content.is_empty() {
- break;
- }
- let punct = content.parse()?;
- elems.push_punct(punct);
- }
-
- Ok(PatTupleStruct {
- attrs: Vec::new(),
- qself,
- path,
- paren_token,
- elems,
- })
- }
-
- fn pat_struct(input: ParseStream, qself: Option<QSelf>, path: Path) -> Result<PatStruct> {
- let content;
- let brace_token = braced!(content in input);
-
- let mut fields = Punctuated::new();
- let mut rest = None;
- while !content.is_empty() {
- let attrs = content.call(Attribute::parse_outer)?;
- if content.peek(Token![..]) {
- rest = Some(PatRest {
- attrs,
- dot2_token: content.parse()?,
- });
- break;
- }
- let mut value = content.call(field_pat)?;
- value.attrs = attrs;
- fields.push_value(value);
- if content.is_empty() {
- break;
- }
- let punct: Token![,] = content.parse()?;
- fields.push_punct(punct);
- }
-
- Ok(PatStruct {
- attrs: Vec::new(),
- qself,
- path,
- brace_token,
- fields,
- rest,
- })
- }
-
- fn field_pat(input: ParseStream) -> Result<FieldPat> {
- let begin = input.fork();
- let boxed: Option<Token![box]> = input.parse()?;
- let by_ref: Option<Token![ref]> = input.parse()?;
- let mutability: Option<Token![mut]> = input.parse()?;
-
- let member = if boxed.is_some() || by_ref.is_some() || mutability.is_some() {
- input.parse().map(Member::Named)
- } else {
- input.parse()
- }?;
-
- if boxed.is_none() && by_ref.is_none() && mutability.is_none() && input.peek(Token![:])
- || !member.is_named()
- {
- return Ok(FieldPat {
- attrs: Vec::new(),
- member,
- colon_token: Some(input.parse()?),
- pat: Box::new(Pat::parse_multi_with_leading_vert(input)?),
- });
- }
-
- let ident = match member {
- Member::Named(ident) => ident,
- Member::Unnamed(_) => unreachable!(),
- };
-
- let pat = if boxed.is_some() {
- Pat::Verbatim(verbatim::between(&begin, input))
- } else {
- Pat::Ident(PatIdent {
- attrs: Vec::new(),
- by_ref,
- mutability,
- ident: ident.clone(),
- subpat: None,
- })
- };
-
- Ok(FieldPat {
- attrs: Vec::new(),
- member: Member::Named(ident),
- colon_token: None,
- pat: Box::new(pat),
- })
- }
-
- fn pat_range(input: ParseStream, qself: Option<QSelf>, path: Path) -> Result<Pat> {
- let limits = RangeLimits::parse_obsolete(input)?;
- let end = input.call(pat_range_bound)?;
- if let (RangeLimits::Closed(_), None) = (&limits, &end) {
- return Err(input.error("expected range upper bound"));
- }
- Ok(Pat::Range(ExprRange {
- attrs: Vec::new(),
- start: Some(Box::new(Expr::Path(ExprPath {
- attrs: Vec::new(),
- qself,
- path,
- }))),
- limits,
- end: end.map(PatRangeBound::into_expr),
- }))
- }
-
- fn pat_range_half_open(input: ParseStream) -> Result<Pat> {
- let limits: RangeLimits = input.parse()?;
- let end = input.call(pat_range_bound)?;
- if end.is_some() {
- Ok(Pat::Range(ExprRange {
- attrs: Vec::new(),
- start: None,
- limits,
- end: end.map(PatRangeBound::into_expr),
- }))
- } else {
- match limits {
- RangeLimits::HalfOpen(dot2_token) => Ok(Pat::Rest(PatRest {
- attrs: Vec::new(),
- dot2_token,
- })),
- RangeLimits::Closed(_) => Err(input.error("expected range upper bound")),
- }
- }
- }
-
- fn pat_paren_or_tuple(input: ParseStream) -> Result<Pat> {
- let content;
- let paren_token = parenthesized!(content in input);
-
- let mut elems = Punctuated::new();
- while !content.is_empty() {
- let value = Pat::parse_multi_with_leading_vert(&content)?;
- if content.is_empty() {
- if elems.is_empty() && !matches!(value, Pat::Rest(_)) {
- return Ok(Pat::Paren(PatParen {
- attrs: Vec::new(),
- paren_token,
- pat: Box::new(value),
- }));
- }
- elems.push_value(value);
- break;
- }
- elems.push_value(value);
- let punct = content.parse()?;
- elems.push_punct(punct);
- }
-
- Ok(Pat::Tuple(PatTuple {
- attrs: Vec::new(),
- paren_token,
- elems,
- }))
- }
-
- fn pat_reference(input: ParseStream) -> Result<PatReference> {
- Ok(PatReference {
- attrs: Vec::new(),
- and_token: input.parse()?,
- mutability: input.parse()?,
- pat: Box::new(Pat::parse_single(input)?),
- })
- }
-
- fn pat_lit_or_range(input: ParseStream) -> Result<Pat> {
- let start = input.call(pat_range_bound)?.unwrap();
- if input.peek(Token![..]) {
- let limits = RangeLimits::parse_obsolete(input)?;
- let end = input.call(pat_range_bound)?;
- if let (RangeLimits::Closed(_), None) = (&limits, &end) {
- return Err(input.error("expected range upper bound"));
- }
- Ok(Pat::Range(ExprRange {
- attrs: Vec::new(),
- start: Some(start.into_expr()),
- limits,
- end: end.map(PatRangeBound::into_expr),
- }))
- } else {
- Ok(start.into_pat())
- }
- }
-
- // Patterns that can appear on either side of a range pattern.
- enum PatRangeBound {
- Const(ExprConst),
- Lit(ExprLit),
- Path(ExprPath),
- }
-
- impl PatRangeBound {
- fn into_expr(self) -> Box<Expr> {
- Box::new(match self {
- PatRangeBound::Const(pat) => Expr::Const(pat),
- PatRangeBound::Lit(pat) => Expr::Lit(pat),
- PatRangeBound::Path(pat) => Expr::Path(pat),
- })
- }
-
- fn into_pat(self) -> Pat {
- match self {
- PatRangeBound::Const(pat) => Pat::Const(pat),
- PatRangeBound::Lit(pat) => Pat::Lit(pat),
- PatRangeBound::Path(pat) => Pat::Path(pat),
- }
- }
- }
-
- fn pat_range_bound(input: ParseStream) -> Result<Option<PatRangeBound>> {
- if input.is_empty()
- || input.peek(Token![|])
- || input.peek(Token![=])
- || input.peek(Token![:]) && !input.peek(Token![::])
- || input.peek(Token![,])
- || input.peek(Token![;])
- || input.peek(Token![if])
- {
- return Ok(None);
- }
-
- let lookahead = input.lookahead1();
- let expr = if lookahead.peek(Lit) {
- PatRangeBound::Lit(input.parse()?)
- } else if lookahead.peek(Ident)
- || lookahead.peek(Token![::])
- || lookahead.peek(Token![<])
- || lookahead.peek(Token![self])
- || lookahead.peek(Token![Self])
- || lookahead.peek(Token![super])
- || lookahead.peek(Token![crate])
- {
- PatRangeBound::Path(input.parse()?)
- } else if lookahead.peek(Token![const]) {
- PatRangeBound::Const(input.parse()?)
- } else {
- return Err(lookahead.error());
- };
-
- Ok(Some(expr))
- }
-
- fn pat_slice(input: ParseStream) -> Result<PatSlice> {
- let content;
- let bracket_token = bracketed!(content in input);
-
- let mut elems = Punctuated::new();
- while !content.is_empty() {
- let value = Pat::parse_multi_with_leading_vert(&content)?;
- match value {
- Pat::Range(pat) if pat.start.is_none() || pat.end.is_none() => {
- let (start, end) = match pat.limits {
- RangeLimits::HalfOpen(dot_dot) => (dot_dot.spans[0], dot_dot.spans[1]),
- RangeLimits::Closed(dot_dot_eq) => {
- (dot_dot_eq.spans[0], dot_dot_eq.spans[2])
- }
- };
- let msg = "range pattern is not allowed unparenthesized inside slice pattern";
- return Err(error::new2(start, end, msg));
- }
- _ => {}
- }
- elems.push_value(value);
- if content.is_empty() {
- break;
- }
- let punct = content.parse()?;
- elems.push_punct(punct);
- }
-
- Ok(PatSlice {
- attrs: Vec::new(),
- bracket_token,
- elems,
- })
- }
-
- fn pat_const(input: ParseStream) -> Result<TokenStream> {
- let begin = input.fork();
- input.parse::<Token![const]>()?;
-
- let content;
- braced!(content in input);
- content.call(Attribute::parse_inner)?;
- content.call(Block::parse_within)?;
-
- Ok(verbatim::between(&begin, input))
- }
-}
-
-#[cfg(feature = "printing")]
-mod printing {
- use super::*;
- use crate::attr::FilterAttrs;
- use proc_macro2::TokenStream;
- use quote::{ToTokens, TokenStreamExt};
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for PatIdent {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.by_ref.to_tokens(tokens);
- self.mutability.to_tokens(tokens);
- self.ident.to_tokens(tokens);
- if let Some((at_token, subpat)) = &self.subpat {
- at_token.to_tokens(tokens);
- subpat.to_tokens(tokens);
- }
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for PatOr {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.leading_vert.to_tokens(tokens);
- self.cases.to_tokens(tokens);
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for PatParen {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.paren_token.surround(tokens, |tokens| {
- self.pat.to_tokens(tokens);
- });
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for PatReference {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.and_token.to_tokens(tokens);
- self.mutability.to_tokens(tokens);
- self.pat.to_tokens(tokens);
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for PatRest {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.dot2_token.to_tokens(tokens);
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for PatSlice {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.bracket_token.surround(tokens, |tokens| {
- self.elems.to_tokens(tokens);
- });
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for PatStruct {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- path::printing::print_path(tokens, &self.qself, &self.path);
- self.brace_token.surround(tokens, |tokens| {
- self.fields.to_tokens(tokens);
- // NOTE: We need a comma before the dot2 token if it is present.
- if !self.fields.empty_or_trailing() && self.rest.is_some() {
- <Token![,]>::default().to_tokens(tokens);
- }
- self.rest.to_tokens(tokens);
- });
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for PatTuple {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.paren_token.surround(tokens, |tokens| {
- self.elems.to_tokens(tokens);
- // If there is only one element, a trailing comma is needed to
- // distinguish PatTuple from PatParen, unless this is `(..)`
- // which is a tuple pattern even without comma.
- if self.elems.len() == 1
- && !self.elems.trailing_punct()
- && !matches!(self.elems[0], Pat::Rest { .. })
- {
- <Token![,]>::default().to_tokens(tokens);
- }
- });
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for PatTupleStruct {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- path::printing::print_path(tokens, &self.qself, &self.path);
- self.paren_token.surround(tokens, |tokens| {
- self.elems.to_tokens(tokens);
- });
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for PatType {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.pat.to_tokens(tokens);
- self.colon_token.to_tokens(tokens);
- self.ty.to_tokens(tokens);
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for PatWild {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- self.underscore_token.to_tokens(tokens);
- }
- }
-
- #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
- impl ToTokens for FieldPat {
- fn to_tokens(&self, tokens: &mut TokenStream) {
- tokens.append_all(self.attrs.outer());
- if let Some(colon_token) = &self.colon_token {
- self.member.to_tokens(tokens);
- colon_token.to_tokens(tokens);
- }
- self.pat.to_tokens(tokens);
- }
- }
-}