From 1376c5a617be5c25655d0d7cb63e3beaa5a6e026 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:20:39 +0200 Subject: Merging upstream version 1.70.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/syn/src/item.rs | 949 ++++++++++++++++++++++++------------------------- 1 file changed, 468 insertions(+), 481 deletions(-) (limited to 'vendor/syn/src/item.rs') diff --git a/vendor/syn/src/item.rs b/vendor/syn/src/item.rs index a1ef7ab43..9d724b063 100644 --- a/vendor/syn/src/item.rs +++ b/vendor/syn/src/item.rs @@ -9,15 +9,13 @@ use std::mem; ast_enum_of_structs! { /// Things that can appear directly inside of a module or scope. /// - /// *This type is available only if Syn is built with the `"full"` feature.* - /// /// # 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")))] - #[cfg_attr(not(syn_no_non_exhaustive), non_exhaustive)] + #[non_exhaustive] pub enum Item { /// A constant item: `const MAX: u16 = 65535`. Const(ItemConst), @@ -42,9 +40,6 @@ ast_enum_of_structs! { /// A macro invocation, which includes `macro_rules!` definitions. Macro(ItemMacro), - /// A 2.0-style declarative macro introduced by the `macro` keyword. - Macro2(ItemMacro2), - /// A module or module declaration: `mod m` or `mod m { ... }`. Mod(ItemMod), @@ -72,8 +67,6 @@ ast_enum_of_structs! { /// Tokens forming an item not interpreted by Syn. Verbatim(TokenStream), - // Not public API. - // // For testing exhaustiveness in downstream code, use the following idiom: // // match item { @@ -90,22 +83,18 @@ ast_enum_of_structs! { // 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. - #[cfg(syn_no_non_exhaustive)] - #[doc(hidden)] - __NonExhaustive, } } ast_struct! { /// A constant item: `const MAX: u16 = 65535`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ItemConst { pub attrs: Vec, pub vis: Visibility, pub const_token: Token![const], pub ident: Ident, + pub generics: Generics, pub colon_token: Token![:], pub ty: Box, pub eq_token: Token![=], @@ -116,8 +105,6 @@ ast_struct! { ast_struct! { /// An enum definition: `enum Foo { A(A), B(B) }`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ItemEnum { pub attrs: Vec, @@ -132,8 +119,6 @@ ast_struct! { ast_struct! { /// An `extern crate` item: `extern crate serde`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ItemExternCrate { pub attrs: Vec, @@ -147,10 +132,7 @@ ast_struct! { } ast_struct! { - /// A free-standing function: `fn process(n: usize) -> Result<()> { ... - /// }`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* + /// A free-standing function: `fn process(n: usize) -> Result<()> { ... }`. #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ItemFn { pub attrs: Vec, @@ -162,11 +144,10 @@ ast_struct! { ast_struct! { /// A block of foreign items: `extern "C" { ... }`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ItemForeignMod { pub attrs: Vec, + pub unsafety: Option, pub abi: Abi, pub brace_token: token::Brace, pub items: Vec, @@ -176,8 +157,6 @@ ast_struct! { ast_struct! { /// An impl block providing trait or associated items: `impl Trait /// for Data { ... }`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ItemImpl { pub attrs: Vec, @@ -196,8 +175,6 @@ ast_struct! { ast_struct! { /// A macro invocation, which includes `macro_rules!` definitions. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ItemMacro { pub attrs: Vec, @@ -208,28 +185,13 @@ ast_struct! { } } -ast_struct! { - /// A 2.0-style declarative macro introduced by the `macro` keyword. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] - pub struct ItemMacro2 { - pub attrs: Vec, - pub vis: Visibility, - pub macro_token: Token![macro], - pub ident: Ident, - pub rules: TokenStream, - } -} - ast_struct! { /// A module or module declaration: `mod m` or `mod m { ... }`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ItemMod { pub attrs: Vec, pub vis: Visibility, + pub unsafety: Option, pub mod_token: Token![mod], pub ident: Ident, pub content: Option<(token::Brace, Vec)>, @@ -239,14 +201,12 @@ ast_struct! { ast_struct! { /// A static item: `static BIKE: Shed = Shed(42)`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ItemStatic { pub attrs: Vec, pub vis: Visibility, pub static_token: Token![static], - pub mutability: Option, + pub mutability: StaticMutability, pub ident: Ident, pub colon_token: Token![:], pub ty: Box, @@ -258,8 +218,6 @@ ast_struct! { ast_struct! { /// A struct definition: `struct Foo { x: A }`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ItemStruct { pub attrs: Vec, @@ -274,14 +232,13 @@ ast_struct! { ast_struct! { /// A trait definition: `pub trait Iterator { ... }`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ItemTrait { pub attrs: Vec, pub vis: Visibility, pub unsafety: Option, pub auto_token: Option, + pub restriction: Option, pub trait_token: Token![trait], pub ident: Ident, pub generics: Generics, @@ -294,8 +251,6 @@ ast_struct! { ast_struct! { /// A trait alias: `pub trait SharableIterator = Iterator + Sync`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ItemTraitAlias { pub attrs: Vec, @@ -311,8 +266,6 @@ ast_struct! { ast_struct! { /// A type alias: `type Result = std::result::Result`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ItemType { pub attrs: Vec, @@ -328,8 +281,6 @@ ast_struct! { ast_struct! { /// A union definition: `union Foo { x: A, y: B }`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ItemUnion { pub attrs: Vec, @@ -343,8 +294,6 @@ ast_struct! { ast_struct! { /// A use declaration: `use std::collections::HashMap`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ItemUse { pub attrs: Vec, @@ -360,26 +309,22 @@ impl Item { #[cfg(feature = "parsing")] pub(crate) fn replace_attrs(&mut self, new: Vec) -> Vec { match self { - Item::ExternCrate(ItemExternCrate { attrs, .. }) - | Item::Use(ItemUse { attrs, .. }) - | Item::Static(ItemStatic { attrs, .. }) - | Item::Const(ItemConst { attrs, .. }) + Item::Const(ItemConst { attrs, .. }) + | Item::Enum(ItemEnum { attrs, .. }) + | Item::ExternCrate(ItemExternCrate { attrs, .. }) | Item::Fn(ItemFn { attrs, .. }) - | Item::Mod(ItemMod { attrs, .. }) | Item::ForeignMod(ItemForeignMod { attrs, .. }) - | Item::Type(ItemType { attrs, .. }) + | Item::Impl(ItemImpl { attrs, .. }) + | Item::Macro(ItemMacro { attrs, .. }) + | Item::Mod(ItemMod { attrs, .. }) + | Item::Static(ItemStatic { attrs, .. }) | Item::Struct(ItemStruct { attrs, .. }) - | Item::Enum(ItemEnum { attrs, .. }) - | Item::Union(ItemUnion { attrs, .. }) | Item::Trait(ItemTrait { attrs, .. }) | Item::TraitAlias(ItemTraitAlias { attrs, .. }) - | Item::Impl(ItemImpl { attrs, .. }) - | Item::Macro(ItemMacro { attrs, .. }) - | Item::Macro2(ItemMacro2 { attrs, .. }) => mem::replace(attrs, new), + | Item::Type(ItemType { attrs, .. }) + | Item::Union(ItemUnion { attrs, .. }) + | Item::Use(ItemUse { attrs, .. }) => mem::replace(attrs, new), Item::Verbatim(_) => Vec::new(), - - #[cfg(syn_no_non_exhaustive)] - _ => unreachable!(), } } } @@ -467,8 +412,6 @@ impl From for DeriveInput { ast_enum_of_structs! { /// A suffix of an import tree in a `use` item: `Type as Renamed` or `*`. /// - /// *This type is available only if Syn is built with the `"full"` feature.* - /// /// # Syntax tree enum /// /// This type is a [syntax tree enum]. @@ -495,8 +438,6 @@ ast_enum_of_structs! { ast_struct! { /// A path prefix of imports in a `use` item: `std::...`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct UsePath { pub ident: Ident, @@ -507,8 +448,6 @@ ast_struct! { ast_struct! { /// An identifier imported by a `use` item: `HashMap`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct UseName { pub ident: Ident, @@ -517,8 +456,6 @@ ast_struct! { ast_struct! { /// An renamed identifier imported by a `use` item: `HashMap as Map`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct UseRename { pub ident: Ident, @@ -529,8 +466,6 @@ ast_struct! { ast_struct! { /// A glob import in a `use` item: `*`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct UseGlob { pub star_token: Token![*], @@ -539,8 +474,6 @@ ast_struct! { ast_struct! { /// A braced group of imports in a `use` item: `{A, B, C}`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct UseGroup { pub brace_token: token::Brace, @@ -551,15 +484,13 @@ ast_struct! { ast_enum_of_structs! { /// An item within an `extern` block. /// - /// *This type is available only if Syn is built with the `"full"` feature.* - /// /// # 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")))] - #[cfg_attr(not(syn_no_non_exhaustive), non_exhaustive)] + #[non_exhaustive] pub enum ForeignItem { /// A foreign function in an `extern` block. Fn(ForeignItemFn), @@ -576,8 +507,6 @@ ast_enum_of_structs! { /// Tokens in an `extern` block not interpreted by Syn. Verbatim(TokenStream), - // Not public API. - // // For testing exhaustiveness in downstream code, use the following idiom: // // match item { @@ -594,16 +523,11 @@ ast_enum_of_structs! { // 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. - #[cfg(syn_no_non_exhaustive)] - #[doc(hidden)] - __NonExhaustive, } } ast_struct! { /// A foreign function in an `extern` block. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ForeignItemFn { pub attrs: Vec, @@ -615,14 +539,12 @@ ast_struct! { ast_struct! { /// A foreign static item in an `extern` block: `static ext: u8`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ForeignItemStatic { pub attrs: Vec, pub vis: Visibility, pub static_token: Token![static], - pub mutability: Option, + pub mutability: StaticMutability, pub ident: Ident, pub colon_token: Token![:], pub ty: Box, @@ -632,22 +554,19 @@ ast_struct! { ast_struct! { /// A foreign type in an `extern` block: `type void`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ForeignItemType { pub attrs: Vec, pub vis: Visibility, pub type_token: Token![type], pub ident: Ident, + pub generics: Generics, pub semi_token: Token![;], } } ast_struct! { /// A macro invocation within an extern block. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ForeignItemMacro { pub attrs: Vec, @@ -659,21 +578,19 @@ ast_struct! { ast_enum_of_structs! { /// An item declaration within the definition of a trait. /// - /// *This type is available only if Syn is built with the `"full"` feature.* - /// /// # 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")))] - #[cfg_attr(not(syn_no_non_exhaustive), non_exhaustive)] + #[non_exhaustive] pub enum TraitItem { /// An associated constant within the definition of a trait. Const(TraitItemConst), - /// A trait method within the definition of a trait. - Method(TraitItemMethod), + /// An associated function within the definition of a trait. + Fn(TraitItemFn), /// An associated type within the definition of a trait. Type(TraitItemType), @@ -684,13 +601,11 @@ ast_enum_of_structs! { /// Tokens within the definition of a trait not interpreted by Syn. Verbatim(TokenStream), - // Not public API. - // // For testing exhaustiveness in downstream code, use the following idiom: // // match item { // TraitItem::Const(item) => {...} - // TraitItem::Method(item) => {...} + // TraitItem::Fn(item) => {...} // ... // TraitItem::Verbatim(item) => {...} // @@ -702,21 +617,17 @@ ast_enum_of_structs! { // 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. - #[cfg(syn_no_non_exhaustive)] - #[doc(hidden)] - __NonExhaustive, } } ast_struct! { /// An associated constant within the definition of a trait. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct TraitItemConst { pub attrs: Vec, pub const_token: Token![const], pub ident: Ident, + pub generics: Generics, pub colon_token: Token![:], pub ty: Type, pub default: Option<(Token![=], Expr)>, @@ -725,11 +636,9 @@ ast_struct! { } ast_struct! { - /// A trait method within the definition of a trait. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* + /// An associated function within the definition of a trait. #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] - pub struct TraitItemMethod { + pub struct TraitItemFn { pub attrs: Vec, pub sig: Signature, pub default: Option, @@ -739,8 +648,6 @@ ast_struct! { ast_struct! { /// An associated type within the definition of a trait. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct TraitItemType { pub attrs: Vec, @@ -756,8 +663,6 @@ ast_struct! { ast_struct! { /// A macro invocation within the definition of a trait. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct TraitItemMacro { pub attrs: Vec, @@ -769,21 +674,19 @@ ast_struct! { ast_enum_of_structs! { /// An item within an impl block. /// - /// *This type is available only if Syn is built with the `"full"` feature.* - /// /// # 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")))] - #[cfg_attr(not(syn_no_non_exhaustive), non_exhaustive)] + #[non_exhaustive] pub enum ImplItem { /// An associated constant within an impl block. Const(ImplItemConst), - /// A method within an impl block. - Method(ImplItemMethod), + /// An associated function within an impl block. + Fn(ImplItemFn), /// An associated type within an impl block. Type(ImplItemType), @@ -794,13 +697,11 @@ ast_enum_of_structs! { /// Tokens within an impl block not interpreted by Syn. Verbatim(TokenStream), - // Not public API. - // // For testing exhaustiveness in downstream code, use the following idiom: // // match item { // ImplItem::Const(item) => {...} - // ImplItem::Method(item) => {...} + // ImplItem::Fn(item) => {...} // ... // ImplItem::Verbatim(item) => {...} // @@ -812,16 +713,11 @@ ast_enum_of_structs! { // 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. - #[cfg(syn_no_non_exhaustive)] - #[doc(hidden)] - __NonExhaustive, } } ast_struct! { /// An associated constant within an impl block. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ImplItemConst { pub attrs: Vec, @@ -829,6 +725,7 @@ ast_struct! { pub defaultness: Option, pub const_token: Token![const], pub ident: Ident, + pub generics: Generics, pub colon_token: Token![:], pub ty: Type, pub eq_token: Token![=], @@ -838,11 +735,9 @@ ast_struct! { } ast_struct! { - /// A method within an impl block. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* + /// An associated function within an impl block. #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] - pub struct ImplItemMethod { + pub struct ImplItemFn { pub attrs: Vec, pub vis: Visibility, pub defaultness: Option, @@ -853,8 +748,6 @@ ast_struct! { ast_struct! { /// An associated type within an impl block. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ImplItemType { pub attrs: Vec, @@ -871,8 +764,6 @@ ast_struct! { ast_struct! { /// A macro invocation within an impl block. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct ImplItemMacro { pub attrs: Vec, @@ -884,8 +775,6 @@ ast_struct! { ast_struct! { /// A function signature in a trait or implementation: `unsafe fn /// initialize(&self)`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct Signature { pub constness: Option, @@ -904,33 +793,20 @@ ast_struct! { impl Signature { /// A method's `self` receiver, such as `&self` or `self: Box`. - pub fn receiver(&self) -> Option<&FnArg> { + pub fn receiver(&self) -> Option<&Receiver> { let arg = self.inputs.first()?; match arg { - FnArg::Receiver(_) => Some(arg), - FnArg::Typed(PatType { pat, .. }) => { - if let Pat::Ident(PatIdent { ident, .. }) = &**pat { - if ident == "self" { - return Some(arg); - } - } - None - } + FnArg::Receiver(receiver) => Some(receiver), + FnArg::Typed(_) => None, } } } ast_enum_of_structs! { /// An argument in a function signature: the `n: usize` in `fn f(n: usize)`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub enum FnArg { - /// The `self` argument of an associated method, whether taken by value - /// or by reference. - /// - /// Note that `self` receivers with a specified type, such as `self: - /// Box`, are parsed as a `FnArg::Typed`. + /// The `self` argument of an associated method. Receiver(Receiver), /// A function argument accepted by pattern and type. @@ -939,19 +815,21 @@ ast_enum_of_structs! { } ast_struct! { - /// The `self` argument of an associated method, whether taken by value - /// or by reference. + /// The `self` argument of an associated method. /// - /// Note that `self` receivers with a specified type, such as `self: - /// Box`, are parsed as a `FnArg::Typed`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* + /// If `colon_token` is present, the receiver is written with an explicit + /// type such as `self: Box`. If `colon_token` is absent, the receiver + /// is written in shorthand such as `self` or `&self` or `&mut self`. In the + /// shorthand case, the type in `ty` is reconstructed as one of `Self`, + /// `&Self`, or `&mut Self`. #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] pub struct Receiver { pub attrs: Vec, pub reference: Option<(Token![&], Option)>, pub mutability: Option, pub self_token: Token![self], + pub colon_token: Option, + pub ty: Box, } } @@ -961,17 +839,63 @@ impl Receiver { } } +ast_struct! { + /// The variadic argument of a foreign function. + /// + /// ```rust + /// # struct c_char; + /// # struct c_int; + /// # + /// extern "C" { + /// fn printf(format: *const c_char, ...) -> c_int; + /// // ^^^ + /// } + /// ``` + #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] + pub struct Variadic { + pub attrs: Vec, + pub pat: Option<(Box, Token![:])>, + pub dots: Token![...], + pub comma: Option, + } +} + +ast_enum! { + /// The mutability of an `Item::Static` or `ForeignItem::Static`. + #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] + #[non_exhaustive] + pub enum StaticMutability { + Mut(Token![mut]), + None, + } +} + +ast_enum! { + /// Unused, but reserved for RFC 3323 restrictions. + #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] + #[non_exhaustive] + pub enum ImplRestriction {} + + + // TODO: https://rust-lang.github.io/rfcs/3323-restrictions.html + // + // pub struct ImplRestriction { + // pub impl_token: Token![impl], + // pub paren_token: token::Paren, + // pub in_token: Option, + // pub path: Box, + // } +} + #[cfg(feature = "parsing")] -pub mod parsing { +pub(crate) mod parsing { use super::*; use crate::ext::IdentExt; use crate::parse::discouraged::Speculative; use crate::parse::{Parse, ParseBuffer, ParseStream, Result}; use crate::token::Brace; - use proc_macro2::{Delimiter, Group, Punct, Spacing, TokenTree}; - use std::iter::{self, FromIterator}; - - crate::custom_keyword!(macro_rules); + use proc_macro2::{Punct, Spacing, TokenTree}; + use std::iter::FromIterator; #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for Item { @@ -1010,7 +934,11 @@ pub mod parsing { Err(lookahead.error()) } } else if lookahead.peek(Token![use]) { - input.parse().map(Item::Use) + let allow_crate_root_in_path = true; + match parse_item_use(input, allow_crate_root_in_path)? { + Some(item_use) => Ok(Item::Use(item_use)), + None => Ok(Item::Verbatim(verbatim::between(begin, input))), + } } else if lookahead.peek(Token![static]) { let vis = input.parse()?; let static_token = input.parse()?; @@ -1067,6 +995,7 @@ pub mod parsing { vis, const_token, ident, + generics: Generics::default(), colon_token, ty, eq_token: input.parse()?, @@ -1092,15 +1021,9 @@ pub mod parsing { Ok(Item::Verbatim(verbatim::between(begin, input))) } } else if lookahead.peek(Token![extern]) { - input.parse::()?; - input.parse::()?; - input.parse::()?; - Ok(Item::Verbatim(verbatim::between(begin, input))) + input.parse().map(Item::ForeignMod) } else if lookahead.peek(Token![mod]) { - input.parse::()?; - input.parse::()?; - input.parse::()?; - Ok(Item::Verbatim(verbatim::between(begin, input))) + input.parse().map(Item::Mod) } else { Err(lookahead.error()) } @@ -1128,7 +1051,8 @@ pub mod parsing { Ok(Item::Verbatim(verbatim::between(begin, input))) } } else if lookahead.peek(Token![macro]) { - input.parse().map(Item::Macro2) + input.advance_to(&ahead); + parse_macro2(begin, vis, input) } else if vis.is_inherited() && (lookahead.peek(Ident) || lookahead.peek(Token![self]) @@ -1137,10 +1061,6 @@ pub mod parsing { || lookahead.peek(Token![::])) { input.parse().map(Item::Macro) - } else if ahead.peek(macro_rules) { - input.advance_to(&ahead); - input.parse::()?; - Ok(Item::Verbatim(verbatim::between(begin, input))) } else { Err(lookahead.error()) }?; @@ -1167,7 +1087,6 @@ pub mod parsing { // type Ty where T: 'static = T; BeforeEq, // type Ty = T where T: 'static; - #[allow(dead_code)] AfterEq, // TODO: goes away once the migration period on rust-lang/rust#89122 is over Both, @@ -1200,7 +1119,7 @@ pub mod parsing { WhereClauseLocation::BeforeEq | WhereClauseLocation::Both => { generics.where_clause = input.parse()?; } - _ => {} + WhereClauseLocation::AfterEq => {} } let ty = if let Some(eq_token) = input.parse()? { @@ -1240,7 +1159,11 @@ pub mod parsing { let attrs = input.call(Attribute::parse_outer)?; let path = input.call(Path::parse_mod_style)?; let bang_token: Token![!] = input.parse()?; - let ident: Option = input.parse()?; + let ident: Option = if input.peek(Token![try]) { + input.call(Ident::parse_any).map(Some) + } else { + input.parse() + }?; let (delimiter, tokens) = input.call(mac::parse_delimiter)?; let semi_token: Option = if !delimiter.is_brace() { Some(input.parse()?) @@ -1261,45 +1184,27 @@ pub mod parsing { } } - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - impl Parse for ItemMacro2 { - fn parse(input: ParseStream) -> Result { - let attrs = input.call(Attribute::parse_outer)?; - let vis: Visibility = input.parse()?; - let macro_token: Token![macro] = input.parse()?; - let ident: Ident = input.parse()?; - let mut rules = TokenStream::new(); - - let mut lookahead = input.lookahead1(); - if lookahead.peek(token::Paren) { - let paren_content; - let paren_token = parenthesized!(paren_content in input); - let args: TokenStream = paren_content.parse()?; - let mut args = Group::new(Delimiter::Parenthesis, args); - args.set_span(paren_token.span); - rules.extend(iter::once(TokenTree::Group(args))); - lookahead = input.lookahead1(); - } + fn parse_macro2(begin: ParseBuffer, _vis: Visibility, input: ParseStream) -> Result { + input.parse::()?; + input.parse::()?; - if lookahead.peek(token::Brace) { - let brace_content; - let brace_token = braced!(brace_content in input); - let body: TokenStream = brace_content.parse()?; - let mut body = Group::new(Delimiter::Brace, body); - body.set_span(brace_token.span); - rules.extend(iter::once(TokenTree::Group(body))); - } else { - return Err(lookahead.error()); - } + let mut lookahead = input.lookahead1(); + if lookahead.peek(token::Paren) { + let paren_content; + parenthesized!(paren_content in input); + paren_content.parse::()?; + lookahead = input.lookahead1(); + } - Ok(ItemMacro2 { - attrs, - vis, - macro_token, - ident, - rules, - }) + if lookahead.peek(token::Brace) { + let brace_content; + braced!(brace_content in input); + brace_content.parse::()?; + } else { + return Err(lookahead.error()); } + + Ok(Item::Verbatim(verbatim::between(begin, input))) } #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] @@ -1338,63 +1243,110 @@ pub mod parsing { #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for ItemUse { fn parse(input: ParseStream) -> Result { - Ok(ItemUse { - attrs: input.call(Attribute::parse_outer)?, - vis: input.parse()?, - use_token: input.parse()?, - leading_colon: input.parse()?, - tree: input.parse()?, - semi_token: input.parse()?, - }) + let allow_crate_root_in_path = false; + parse_item_use(input, allow_crate_root_in_path).map(Option::unwrap) } } + fn parse_item_use( + input: ParseStream, + allow_crate_root_in_path: bool, + ) -> Result> { + let attrs = input.call(Attribute::parse_outer)?; + let vis: Visibility = input.parse()?; + let use_token: Token![use] = input.parse()?; + let leading_colon: Option = input.parse()?; + let tree = parse_use_tree(input, allow_crate_root_in_path && leading_colon.is_none())?; + let semi_token: Token![;] = input.parse()?; + + let tree = match tree { + Some(tree) => tree, + None => return Ok(None), + }; + + Ok(Some(ItemUse { + attrs, + vis, + use_token, + leading_colon, + tree, + semi_token, + })) + } + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for UseTree { fn parse(input: ParseStream) -> Result { - let lookahead = input.lookahead1(); - if lookahead.peek(Ident) - || lookahead.peek(Token![self]) - || lookahead.peek(Token![super]) - || lookahead.peek(Token![crate]) - { - let ident = input.call(Ident::parse_any)?; - if input.peek(Token![::]) { - Ok(UseTree::Path(UsePath { - ident, - colon2_token: input.parse()?, - tree: Box::new(input.parse()?), - })) - } else if input.peek(Token![as]) { - Ok(UseTree::Rename(UseRename { - ident, - as_token: input.parse()?, - rename: { - if input.peek(Ident) { - input.parse()? - } else if input.peek(Token![_]) { - Ident::from(input.parse::()?) - } else { - return Err(input.error("expected identifier or underscore")); - } - }, - })) - } else { - Ok(UseTree::Name(UseName { ident })) + let allow_crate_root_in_path = false; + parse_use_tree(input, allow_crate_root_in_path).map(Option::unwrap) + } + } + + fn parse_use_tree( + input: ParseStream, + allow_crate_root_in_path: bool, + ) -> Result> { + let lookahead = input.lookahead1(); + if lookahead.peek(Ident) + || lookahead.peek(Token![self]) + || lookahead.peek(Token![super]) + || lookahead.peek(Token![crate]) + || lookahead.peek(Token![try]) + { + let ident = input.call(Ident::parse_any)?; + if input.peek(Token![::]) { + Ok(Some(UseTree::Path(UsePath { + ident, + colon2_token: input.parse()?, + tree: Box::new(input.parse()?), + }))) + } else if input.peek(Token![as]) { + Ok(Some(UseTree::Rename(UseRename { + ident, + as_token: input.parse()?, + rename: { + if input.peek(Ident) { + input.parse()? + } else if input.peek(Token![_]) { + Ident::from(input.parse::()?) + } else { + return Err(input.error("expected identifier or underscore")); + } + }, + }))) + } else { + Ok(Some(UseTree::Name(UseName { ident }))) + } + } else if lookahead.peek(Token![*]) { + Ok(Some(UseTree::Glob(UseGlob { + star_token: input.parse()?, + }))) + } else if lookahead.peek(token::Brace) { + let content; + let brace_token = braced!(content in input); + let mut items = Punctuated::new(); + let mut has_crate_root_in_path = false; + loop { + if content.is_empty() { + break; } - } else if lookahead.peek(Token![*]) { - Ok(UseTree::Glob(UseGlob { - star_token: input.parse()?, - })) - } else if lookahead.peek(token::Brace) { - let content; - Ok(UseTree::Group(UseGroup { - brace_token: braced!(content in input), - items: content.parse_terminated(UseTree::parse)?, - })) + has_crate_root_in_path |= + allow_crate_root_in_path && content.parse::>()?.is_some(); + let tree: UseTree = content.parse()?; + items.push_value(tree); + if content.is_empty() { + break; + } + let comma: Token![,] = content.parse()?; + items.push_punct(comma); + } + if has_crate_root_in_path { + Ok(None) } else { - Err(lookahead.error()) + Ok(Some(UseTree::Group(UseGroup { brace_token, items }))) } + } else { + Err(lookahead.error()) } } @@ -1431,6 +1383,7 @@ pub mod parsing { return Err(lookahead.error()); } }, + generics: Generics::default(), colon_token: input.parse()?, ty: input.parse()?, eq_token: input.parse()?, @@ -1440,54 +1393,6 @@ pub mod parsing { } } - fn pop_variadic(args: &mut Punctuated) -> Option { - let trailing_punct = args.trailing_punct(); - - let last = match args.last_mut()? { - FnArg::Typed(last) => last, - _ => return None, - }; - - let ty = match last.ty.as_ref() { - Type::Verbatim(ty) => ty, - _ => return None, - }; - - let mut variadic = Variadic { - attrs: Vec::new(), - dots: parse2(ty.clone()).ok()?, - }; - - if let Pat::Verbatim(pat) = last.pat.as_ref() { - if pat.to_string() == "..." && !trailing_punct { - variadic.attrs = mem::replace(&mut last.attrs, Vec::new()); - args.pop(); - } - } - - Some(variadic) - } - - fn variadic_to_tokens(dots: &Token![...]) -> TokenStream { - TokenStream::from_iter(vec![ - TokenTree::Punct({ - let mut dot = Punct::new('.', Spacing::Joint); - dot.set_span(dots.spans[0]); - dot - }), - TokenTree::Punct({ - let mut dot = Punct::new('.', Spacing::Joint); - dot.set_span(dots.spans[1]); - dot - }), - TokenTree::Punct({ - let mut dot = Punct::new('.', Spacing::Alone); - dot.set_span(dots.spans[2]); - dot - }), - ]) - } - fn peek_signature(input: ParseStream) -> bool { let fork = input.fork(); fork.parse::>().is_ok() @@ -1510,8 +1415,7 @@ pub mod parsing { let content; let paren_token = parenthesized!(content in input); - let mut inputs = parse_fn_args(&content)?; - let variadic = pop_variadic(&mut inputs); + let (inputs, variadic) = parse_fn_args(&content)?; let output: ReturnType = input.parse()?; generics.where_clause = input.parse()?; @@ -1564,78 +1468,171 @@ pub mod parsing { #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for FnArg { fn parse(input: ParseStream) -> Result { + let allow_variadic = false; let attrs = input.call(Attribute::parse_outer)?; - - let ahead = input.fork(); - if let Ok(mut receiver) = ahead.parse::() { - if !ahead.peek(Token![:]) { - input.advance_to(&ahead); - receiver.attrs = attrs; - return Ok(FnArg::Receiver(receiver)); - } + match parse_fn_arg_or_variadic(input, attrs, allow_variadic)? { + FnArgOrVariadic::FnArg(arg) => Ok(arg), + FnArgOrVariadic::Variadic(_) => unreachable!(), } + } + } + + enum FnArgOrVariadic { + FnArg(FnArg), + Variadic(Variadic), + } + + fn parse_fn_arg_or_variadic( + input: ParseStream, + attrs: Vec, + allow_variadic: bool, + ) -> Result { + let ahead = input.fork(); + if let Ok(mut receiver) = ahead.parse::() { + input.advance_to(&ahead); + receiver.attrs = attrs; + return Ok(FnArgOrVariadic::FnArg(FnArg::Receiver(receiver))); + } + + // Hack to parse pre-2018 syntax in + // test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs + // because the rest of the test case is valuable. + if input.peek(Ident) && input.peek2(Token![<]) { + let span = input.fork().parse::()?.span(); + return Ok(FnArgOrVariadic::FnArg(FnArg::Typed(PatType { + attrs, + pat: Box::new(Pat::Wild(PatWild { + attrs: Vec::new(), + underscore_token: Token![_](span), + })), + colon_token: Token![:](span), + ty: input.parse()?, + }))); + } + + let pat = Box::new(Pat::parse_single(input)?); + let colon_token: Token![:] = input.parse()?; - let mut typed = input.call(fn_arg_typed)?; - typed.attrs = attrs; - Ok(FnArg::Typed(typed)) + if allow_variadic { + if let Some(dots) = input.parse::>()? { + return Ok(FnArgOrVariadic::Variadic(Variadic { + attrs, + pat: Some((pat, colon_token)), + dots, + comma: None, + })); + } } + + Ok(FnArgOrVariadic::FnArg(FnArg::Typed(PatType { + attrs, + pat, + colon_token, + ty: input.parse()?, + }))) } #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] impl Parse for Receiver { fn parse(input: ParseStream) -> Result { + let reference = if input.peek(Token![&]) { + let ampersand: Token![&] = input.parse()?; + let lifetime: Option = input.parse()?; + Some((ampersand, lifetime)) + } else { + None + }; + let mutability: Option = input.parse()?; + let self_token: Token![self] = input.parse()?; + let colon_token: Option = if reference.is_some() { + None + } else { + input.parse()? + }; + let ty: Type = if colon_token.is_some() { + input.parse()? + } else { + let mut ty = Type::Path(TypePath { + qself: None, + path: Path::from(Ident::new("Self", self_token.span)), + }); + if let Some((ampersand, lifetime)) = reference.as_ref() { + ty = Type::Reference(TypeReference { + and_token: Token![&](ampersand.span), + lifetime: lifetime.clone(), + mutability: mutability.as_ref().map(|m| Token![mut](m.span)), + elem: Box::new(ty), + }); + } + ty + }; Ok(Receiver { attrs: Vec::new(), - reference: { - if input.peek(Token![&]) { - Some((input.parse()?, input.parse()?)) - } else { - None - } - }, - mutability: input.parse()?, - self_token: input.parse()?, + reference, + mutability, + self_token, + colon_token, + ty: Box::new(ty), }) } } - fn parse_fn_args(input: ParseStream) -> Result> { + fn parse_fn_args( + input: ParseStream, + ) -> Result<(Punctuated, Option)> { let mut args = Punctuated::new(); + let mut variadic = None; let mut has_receiver = false; while !input.is_empty() { let attrs = input.call(Attribute::parse_outer)?; - let arg = if let Some(dots) = input.parse::>()? { - FnArg::Typed(PatType { + if let Some(dots) = input.parse::>()? { + variadic = Some(Variadic { attrs, - pat: Box::new(Pat::Verbatim(variadic_to_tokens(&dots))), - colon_token: Token![:](dots.spans[0]), - ty: Box::new(Type::Verbatim(variadic_to_tokens(&dots))), - }) - } else { - let mut arg: FnArg = input.parse()?; - match &mut arg { - FnArg::Receiver(receiver) if has_receiver => { - return Err(Error::new( - receiver.self_token.span, - "unexpected second method receiver", - )); - } - FnArg::Receiver(receiver) if !args.is_empty() => { - return Err(Error::new( - receiver.self_token.span, - "unexpected method receiver", - )); - } - FnArg::Receiver(receiver) => { - has_receiver = true; - receiver.attrs = attrs; - } - FnArg::Typed(arg) => arg.attrs = attrs, + pat: None, + dots, + comma: if input.is_empty() { + None + } else { + Some(input.parse()?) + }, + }); + break; + } + + let allow_variadic = true; + let arg = match parse_fn_arg_or_variadic(input, attrs, allow_variadic)? { + FnArgOrVariadic::FnArg(arg) => arg, + FnArgOrVariadic::Variadic(arg) => { + variadic = Some(Variadic { + comma: if input.is_empty() { + None + } else { + Some(input.parse()?) + }, + ..arg + }); + break; } - arg }; + + match &arg { + FnArg::Receiver(receiver) if has_receiver => { + return Err(Error::new( + receiver.self_token.span, + "unexpected second method receiver", + )); + } + FnArg::Receiver(receiver) if !args.is_empty() => { + return Err(Error::new( + receiver.self_token.span, + "unexpected method receiver", + )); + } + FnArg::Receiver(_) => has_receiver = true, + FnArg::Typed(_) => {} + } args.push_value(arg); if input.is_empty() { @@ -1646,35 +1643,7 @@ pub mod parsing { args.push_punct(comma); } - Ok(args) - } - - fn fn_arg_typed(input: ParseStream) -> Result { - // Hack to parse pre-2018 syntax in - // test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs - // because the rest of the test case is valuable. - if input.peek(Ident) && input.peek2(Token![<]) { - let span = input.fork().parse::()?.span(); - return Ok(PatType { - attrs: Vec::new(), - pat: Box::new(Pat::Wild(PatWild { - attrs: Vec::new(), - underscore_token: Token![_](span), - })), - colon_token: Token![:](span), - ty: input.parse()?, - }); - } - - Ok(PatType { - attrs: Vec::new(), - pat: Box::new(pat::parsing::multi_pat(input)?), - colon_token: input.parse()?, - ty: Box::new(match input.parse::>()? { - Some(dot3) => Type::Verbatim(variadic_to_tokens(&dot3)), - None => input.parse()?, - }), - }) + Ok((args, variadic)) } #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] @@ -1682,14 +1651,20 @@ pub mod parsing { fn parse(input: ParseStream) -> Result { let mut attrs = input.call(Attribute::parse_outer)?; let vis: Visibility = input.parse()?; + let unsafety: Option = input.parse()?; let mod_token: Token![mod] = input.parse()?; - let ident: Ident = input.parse()?; + let ident: Ident = if input.peek(Token![try]) { + input.call(Ident::parse_any) + } else { + input.parse() + }?; let lookahead = input.lookahead1(); if lookahead.peek(Token![;]) { Ok(ItemMod { attrs, vis, + unsafety, mod_token, ident, content: None, @@ -1708,6 +1683,7 @@ pub mod parsing { Ok(ItemMod { attrs, vis, + unsafety, mod_token, ident, content: Some((brace_token, items)), @@ -1723,6 +1699,7 @@ pub mod parsing { impl Parse for ItemForeignMod { fn parse(input: ParseStream) -> Result { let mut attrs = input.call(Attribute::parse_outer)?; + let unsafety: Option = input.parse()?; let abi: Abi = input.parse()?; let content; @@ -1735,6 +1712,7 @@ pub mod parsing { Ok(ItemForeignMod { attrs, + unsafety, abi, brace_token, items, @@ -1813,9 +1791,6 @@ pub mod parsing { ForeignItem::Type(item) => &mut item.attrs, ForeignItem::Macro(item) => &mut item.attrs, ForeignItem::Verbatim(_) => return Ok(item), - - #[cfg(syn_no_non_exhaustive)] - _ => unreachable!(), }; attrs.append(item_attrs); *item_attrs = attrs; @@ -1864,6 +1839,11 @@ pub mod parsing { vis: input.parse()?, type_token: input.parse()?, ident: input.parse()?, + generics: { + let mut generics: Generics = input.parse()?; + generics.where_clause = input.parse()?; + generics + }, semi_token: input.parse()?, }) } @@ -1880,14 +1860,9 @@ pub mod parsing { bounds: _, ty, semi_token, - } = FlexibleItemType::parse(input, WhereClauseLocation::BeforeEq)?; + } = FlexibleItemType::parse(input, WhereClauseLocation::Both)?; - if defaultness.is_some() - || generics.lt_token.is_some() - || generics.where_clause.is_some() - || colon_token.is_some() - || ty.is_some() - { + if defaultness.is_some() || colon_token.is_some() || ty.is_some() { Ok(ForeignItem::Verbatim(verbatim::between(begin, input))) } else { Ok(ForeignItem::Type(ForeignItemType { @@ -1895,6 +1870,7 @@ pub mod parsing { vis, type_token, ident, + generics, semi_token, })) } @@ -2131,6 +2107,7 @@ pub mod parsing { vis, unsafety, auto_token, + restriction: None, trait_token, ident, generics, @@ -2208,7 +2185,7 @@ pub mod parsing { let lookahead = ahead.lookahead1(); let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead) { - input.parse().map(TraitItem::Method) + input.parse().map(TraitItem::Fn) } else if lookahead.peek(Token![const]) { ahead.parse::()?; let lookahead = ahead.lookahead1(); @@ -2219,7 +2196,7 @@ pub mod parsing { || lookahead.peek(Token![extern]) || lookahead.peek(Token![fn]) { - input.parse().map(TraitItem::Method) + input.parse().map(TraitItem::Fn) } else { Err(lookahead.error()) } @@ -2243,13 +2220,10 @@ pub mod parsing { let item_attrs = match &mut item { TraitItem::Const(item) => &mut item.attrs, - TraitItem::Method(item) => &mut item.attrs, + TraitItem::Fn(item) => &mut item.attrs, TraitItem::Type(item) => &mut item.attrs, TraitItem::Macro(item) => &mut item.attrs, TraitItem::Verbatim(_) => unreachable!(), - - #[cfg(syn_no_non_exhaustive)] - _ => unreachable!(), }; attrs.append(item_attrs); *item_attrs = attrs; @@ -2271,6 +2245,7 @@ pub mod parsing { return Err(lookahead.error()); } }, + generics: Generics::default(), colon_token: input.parse()?, ty: input.parse()?, default: { @@ -2288,7 +2263,7 @@ pub mod parsing { } #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - impl Parse for TraitItemMethod { + impl Parse for TraitItemFn { fn parse(input: ParseStream) -> Result { let mut attrs = input.call(Attribute::parse_outer)?; let sig: Signature = input.parse()?; @@ -2307,7 +2282,7 @@ pub mod parsing { return Err(lookahead.error()); }; - Ok(TraitItemMethod { + Ok(TraitItemFn { attrs, sig, default: brace_token.map(|brace_token| Block { brace_token, stmts }), @@ -2371,7 +2346,7 @@ pub mod parsing { bounds, ty, semi_token, - } = FlexibleItemType::parse(input, WhereClauseLocation::Both)?; + } = FlexibleItemType::parse(input, WhereClauseLocation::AfterEq)?; if defaultness.is_some() || vis.is_some() { Ok(TraitItem::Verbatim(verbatim::between(begin, input))) @@ -2537,7 +2512,7 @@ pub mod parsing { }; let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead) { - input.parse().map(ImplItem::Method) + input.parse().map(ImplItem::Fn) } else if lookahead.peek(Token![const]) { let const_token: Token![const] = ahead.parse()?; let lookahead = ahead.lookahead1(); @@ -2553,6 +2528,7 @@ pub mod parsing { defaultness, const_token, ident, + generics: Generics::default(), colon_token, ty, eq_token, @@ -2584,13 +2560,10 @@ pub mod parsing { { let item_attrs = match &mut item { ImplItem::Const(item) => &mut item.attrs, - ImplItem::Method(item) => &mut item.attrs, + ImplItem::Fn(item) => &mut item.attrs, ImplItem::Type(item) => &mut item.attrs, ImplItem::Macro(item) => &mut item.attrs, ImplItem::Verbatim(_) => return Ok(item), - - #[cfg(syn_no_non_exhaustive)] - _ => unreachable!(), }; attrs.append(item_attrs); *item_attrs = attrs; @@ -2616,6 +2589,7 @@ pub mod parsing { return Err(lookahead.error()); } }, + generics: Generics::default(), colon_token: input.parse()?, ty: input.parse()?, eq_token: input.parse()?, @@ -2626,7 +2600,7 @@ pub mod parsing { } #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - impl Parse for ImplItemMethod { + impl Parse for ImplItemFn { fn parse(input: ParseStream) -> Result { let mut attrs = input.call(Attribute::parse_outer)?; let vis: Visibility = input.parse()?; @@ -2634,7 +2608,7 @@ pub mod parsing { let sig: Signature = input.parse()?; let block = if let Some(semi) = input.parse::>()? { - // Accept methods without a body in an impl block because + // Accept functions without a body in an impl block because // rustc's *parser* does not reject them (the compilation error // is emitted later than parsing) and it can be useful for macro // DSLs. @@ -2642,7 +2616,7 @@ pub mod parsing { punct.set_span(semi.span); let tokens = TokenStream::from_iter(vec![TokenTree::Punct(punct)]); Block { - brace_token: Brace { span: semi.span }, + brace_token: Brace(semi.span), stmts: vec![Stmt::Item(Item::Verbatim(tokens))], } } else { @@ -2655,7 +2629,7 @@ pub mod parsing { } }; - Ok(ImplItemMethod { + Ok(ImplItemFn { attrs, vis, defaultness, @@ -2703,7 +2677,7 @@ pub mod parsing { bounds: _, ty, semi_token, - } = FlexibleItemType::parse(input, WhereClauseLocation::Both)?; + } = FlexibleItemType::parse(input, WhereClauseLocation::AfterEq)?; if colon_token.is_some() || ty.is_none() { Ok(ImplItem::Verbatim(verbatim::between(begin, input))) @@ -2743,7 +2717,7 @@ pub mod parsing { impl Visibility { fn is_inherited(&self) -> bool { - match *self { + match self { Visibility::Inherited => true, _ => false, } @@ -2751,13 +2725,21 @@ pub mod parsing { } impl MacroDelimiter { - fn is_brace(&self) -> bool { - match *self { + pub(crate) fn is_brace(&self) -> bool { + match self { MacroDelimiter::Brace(_) => true, MacroDelimiter::Paren(_) | MacroDelimiter::Bracket(_) => false, } } } + + #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] + impl Parse for StaticMutability { + fn parse(input: ParseStream) -> Result { + let mut_token: Option = input.parse()?; + Ok(mut_token.map_or(StaticMutability::None, StaticMutability::Mut)) + } + } } #[cfg(feature = "printing")] @@ -2845,6 +2827,7 @@ mod printing { fn to_tokens(&self, tokens: &mut TokenStream) { tokens.append_all(self.attrs.outer()); self.vis.to_tokens(tokens); + self.unsafety.to_tokens(tokens); self.mod_token.to_tokens(tokens); self.ident.to_tokens(tokens); if let Some((brace, items)) = &self.content { @@ -2862,6 +2845,7 @@ mod printing { impl ToTokens for ItemForeignMod { fn to_tokens(&self, tokens: &mut TokenStream) { tokens.append_all(self.attrs.outer()); + self.unsafety.to_tokens(tokens); self.abi.to_tokens(tokens); self.brace_token.surround(tokens, |tokens| { tokens.append_all(self.attrs.inner()); @@ -3020,17 +3004,6 @@ mod printing { } } - #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ItemMacro2 { - fn to_tokens(&self, tokens: &mut TokenStream) { - tokens.append_all(self.attrs.outer()); - self.vis.to_tokens(tokens); - self.macro_token.to_tokens(tokens); - self.ident.to_tokens(tokens); - self.rules.to_tokens(tokens); - } - } - #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] impl ToTokens for UsePath { fn to_tokens(&self, tokens: &mut TokenStream) { @@ -3089,7 +3062,7 @@ mod printing { } #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for TraitItemMethod { + impl ToTokens for TraitItemFn { fn to_tokens(&self, tokens: &mut TokenStream) { tokens.append_all(self.attrs.outer()); self.sig.to_tokens(tokens); @@ -3153,7 +3126,7 @@ mod printing { } #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for ImplItemMethod { + impl ToTokens for ImplItemFn { fn to_tokens(&self, tokens: &mut TokenStream) { tokens.append_all(self.attrs.outer()); self.vis.to_tokens(tokens); @@ -3230,6 +3203,8 @@ mod printing { self.vis.to_tokens(tokens); self.type_token.to_tokens(tokens); self.ident.to_tokens(tokens); + self.generics.to_tokens(tokens); + self.generics.where_clause.to_tokens(tokens); self.semi_token.to_tokens(tokens); } } @@ -3243,33 +3218,6 @@ mod printing { } } - fn maybe_variadic_to_tokens(arg: &FnArg, tokens: &mut TokenStream) -> bool { - let arg = match arg { - FnArg::Typed(arg) => arg, - FnArg::Receiver(receiver) => { - receiver.to_tokens(tokens); - return false; - } - }; - - match arg.ty.as_ref() { - Type::Verbatim(ty) if ty.to_string() == "..." => { - match arg.pat.as_ref() { - Pat::Verbatim(pat) if pat.to_string() == "..." => { - tokens.append_all(arg.attrs.outer()); - pat.to_tokens(tokens); - } - _ => arg.to_tokens(tokens), - } - true - } - _ => { - arg.to_tokens(tokens); - false - } - } - } - #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] impl ToTokens for Signature { fn to_tokens(&self, tokens: &mut TokenStream) { @@ -3281,16 +3229,12 @@ mod printing { self.ident.to_tokens(tokens); self.generics.to_tokens(tokens); self.paren_token.surround(tokens, |tokens| { - let mut last_is_variadic = false; - for pair in self.inputs.pairs() { - last_is_variadic = maybe_variadic_to_tokens(pair.value(), tokens); - pair.punct().to_tokens(tokens); - } - if self.variadic.is_some() && !last_is_variadic { + self.inputs.to_tokens(tokens); + if let Some(variadic) = &self.variadic { if !self.inputs.empty_or_trailing() { ::default().to_tokens(tokens); } - self.variadic.to_tokens(tokens); + variadic.to_tokens(tokens); } }); self.output.to_tokens(tokens); @@ -3308,6 +3252,49 @@ mod printing { } self.mutability.to_tokens(tokens); self.self_token.to_tokens(tokens); + if let Some(colon_token) = &self.colon_token { + colon_token.to_tokens(tokens); + self.ty.to_tokens(tokens); + } else { + let consistent = match (&self.reference, &self.mutability, &*self.ty) { + (Some(_), mutability, Type::Reference(ty)) => { + mutability.is_some() == ty.mutability.is_some() + && match &*ty.elem { + Type::Path(ty) => ty.qself.is_none() && ty.path.is_ident("Self"), + _ => false, + } + } + (None, _, Type::Path(ty)) => ty.qself.is_none() && ty.path.is_ident("Self"), + _ => false, + }; + if !consistent { + ::default().to_tokens(tokens); + self.ty.to_tokens(tokens); + } + } + } + } + + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] + impl ToTokens for Variadic { + fn to_tokens(&self, tokens: &mut TokenStream) { + tokens.append_all(self.attrs.outer()); + if let Some((pat, colon)) = &self.pat { + pat.to_tokens(tokens); + colon.to_tokens(tokens); + } + self.dots.to_tokens(tokens); + self.comma.to_tokens(tokens); + } + } + + #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] + impl ToTokens for StaticMutability { + fn to_tokens(&self, tokens: &mut TokenStream) { + match self { + StaticMutability::None => {} + StaticMutability::Mut(mut_token) => mut_token.to_tokens(tokens), + } } } } -- cgit v1.2.3