summaryrefslogtreecommitdiffstats
path: root/vendor/syn/src/item.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/syn/src/item.rs')
-rw-r--r--vendor/syn/src/item.rs949
1 files changed, 468 insertions, 481 deletions
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<Attribute>,
pub vis: Visibility,
pub const_token: Token![const],
pub ident: Ident,
+ pub generics: Generics,
pub colon_token: Token![:],
pub ty: Box<Type>,
pub eq_token: Token![=],
@@ -116,8 +105,6 @@ ast_struct! {
ast_struct! {
/// An enum definition: `enum Foo<A, B> { 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<Attribute>,
@@ -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<Attribute>,
@@ -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<Attribute>,
@@ -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<Attribute>,
+ pub unsafety: Option<Token![unsafe]>,
pub abi: Abi,
pub brace_token: token::Brace,
pub items: Vec<ForeignItem>,
@@ -176,8 +157,6 @@ ast_struct! {
ast_struct! {
/// An impl block providing trait or associated items: `impl<A> Trait
/// for Data<A> { ... }`.
- ///
- /// *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<Attribute>,
@@ -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<Attribute>,
@@ -209,27 +186,12 @@ 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<Attribute>,
- 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<Attribute>,
pub vis: Visibility,
+ pub unsafety: Option<Token![unsafe]>,
pub mod_token: Token![mod],
pub ident: Ident,
pub content: Option<(token::Brace, Vec<Item>)>,
@@ -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<Attribute>,
pub vis: Visibility,
pub static_token: Token![static],
- pub mutability: Option<Token![mut]>,
+ pub mutability: StaticMutability,
pub ident: Ident,
pub colon_token: Token![:],
pub ty: Box<Type>,
@@ -258,8 +218,6 @@ ast_struct! {
ast_struct! {
/// A struct definition: `struct Foo<A> { 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<Attribute>,
@@ -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<Attribute>,
pub vis: Visibility,
pub unsafety: Option<Token![unsafe]>,
pub auto_token: Option<Token![auto]>,
+ pub restriction: Option<ImplRestriction>,
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<Attribute>,
@@ -311,8 +266,6 @@ ast_struct! {
ast_struct! {
/// A type alias: `type Result<T> = std::result::Result<T, MyError>`.
- ///
- /// *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<Attribute>,
@@ -328,8 +281,6 @@ ast_struct! {
ast_struct! {
/// A union definition: `union Foo<A, B> { 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<Attribute>,
@@ -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<Attribute>,
@@ -360,26 +309,22 @@ impl Item {
#[cfg(feature = "parsing")]
pub(crate) fn replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute> {
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<ItemUnion> 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<Attribute>,
@@ -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<Attribute>,
pub vis: Visibility,
pub static_token: Token![static],
- pub mutability: Option<Token![mut]>,
+ pub mutability: StaticMutability,
pub ident: Ident,
pub colon_token: Token![:],
pub ty: Box<Type>,
@@ -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<Attribute>,
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<Attribute>,
@@ -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<Attribute>,
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<Attribute>,
pub sig: Signature,
pub default: Option<Block>,
@@ -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<Attribute>,
@@ -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<Attribute>,
@@ -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<Attribute>,
@@ -829,6 +725,7 @@ ast_struct! {
pub defaultness: Option<Token![default]>,
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<Attribute>,
pub vis: Visibility,
pub defaultness: Option<Token![default]>,
@@ -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<Attribute>,
@@ -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<Attribute>,
@@ -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<Token![const]>,
@@ -904,33 +793,20 @@ ast_struct! {
impl Signature {
/// A method's `self` receiver, such as `&self` or `self: Box<Self>`.
- 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<Self>`, 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<Self>`, 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<Self>`. 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<Attribute>,
pub reference: Option<(Token![&], Option<Lifetime>)>,
pub mutability: Option<Token![mut]>,
pub self_token: Token![self],
+ pub colon_token: Option<Token![:]>,
+ pub ty: Box<Type>,
}
}
@@ -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<Attribute>,
+ pub pat: Option<(Box<Pat>, Token![:])>,
+ pub dots: Token![...],
+ pub comma: Option<Token![,]>,
+ }
+}
+
+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<Token![in]>,
+ // pub path: Box<Path>,
+ // }
+}
+
#[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::<Visibility>()?;
- input.parse::<Token![unsafe]>()?;
- input.parse::<ItemForeignMod>()?;
- Ok(Item::Verbatim(verbatim::between(begin, input)))
+ input.parse().map(Item::ForeignMod)
} else if lookahead.peek(Token![mod]) {
- input.parse::<Visibility>()?;
- input.parse::<Token![unsafe]>()?;
- input.parse::<ItemMod>()?;
- 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::<ItemMacro>()?;
- Ok(Item::Verbatim(verbatim::between(begin, input)))
} else {
Err(lookahead.error())
}?;
@@ -1167,7 +1087,6 @@ pub mod parsing {
// type Ty<T> where T: 'static = T;
BeforeEq,
// type Ty<T> = 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<Ident> = input.parse()?;
+ let ident: Option<Ident> = 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<Token![;]> = 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<Self> {
- 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<Item> {
+ input.parse::<Token![macro]>()?;
+ input.parse::<Ident>()?;
- 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::<TokenStream>()?;
+ 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::<TokenStream>()?;
+ } 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<Self> {
- 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<Option<ItemUse>> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let vis: Visibility = input.parse()?;
+ let use_token: Token![use] = input.parse()?;
+ let leading_colon: Option<Token![::]> = 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<UseTree> {
- 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::<Token![_]>()?)
- } 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<Option<UseTree>> {
+ 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::<Token![_]>()?)
+ } 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::<Option<Token![::]>>()?.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<FnArg, Token![,]>) -> Option<Variadic> {
- 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::<Option<Token![const]>>().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<Self> {
+ let allow_variadic = false;
let attrs = input.call(Attribute::parse_outer)?;
-
- let ahead = input.fork();
- if let Ok(mut receiver) = ahead.parse::<Receiver>() {
- 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<Attribute>,
+ allow_variadic: bool,
+ ) -> Result<FnArgOrVariadic> {
+ let ahead = input.fork();
+ if let Ok(mut receiver) = ahead.parse::<Receiver>() {
+ 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::<Ident>()?.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::<Option<Token![...]>>()? {
+ 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<Self> {
+ let reference = if input.peek(Token![&]) {
+ let ampersand: Token![&] = input.parse()?;
+ let lifetime: Option<Lifetime> = input.parse()?;
+ Some((ampersand, lifetime))
+ } else {
+ None
+ };
+ let mutability: Option<Token![mut]> = input.parse()?;
+ let self_token: Token![self] = input.parse()?;
+ let colon_token: Option<Token![:]> = 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<Punctuated<FnArg, Token![,]>> {
+ fn parse_fn_args(
+ input: ParseStream,
+ ) -> Result<(Punctuated<FnArg, Token![,]>, Option<Variadic>)> {
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::<Option<Token![...]>>()? {
- FnArg::Typed(PatType {
+ if let Some(dots) = input.parse::<Option<Token![...]>>()? {
+ 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<PatType> {
- // 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::<Ident>()?.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::<Option<Token![...]>>()? {
- 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<Self> {
let mut attrs = input.call(Attribute::parse_outer)?;
let vis: Visibility = input.parse()?;
+ let unsafety: Option<Token![unsafe]> = 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<Self> {
let mut attrs = input.call(Attribute::parse_outer)?;
+ let unsafety: Option<Token![unsafe]> = 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::<Token![const]>()?;
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<Self> {
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<Self> {
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::<Option<Token![;]>>()? {
- // 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<Self> {
+ let mut_token: Option<Token![mut]> = 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());
@@ -3021,17 +3005,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) {
self.ident.to_tokens(tokens);
@@ -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() {
<Token![,]>::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 {
+ <Token![:]>::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),
+ }
}
}
}