]> git.proxmox.com Git - rustc.git/blame - vendor/syn/src/item.rs
New upstream version 1.51.0+dfsg1
[rustc.git] / vendor / syn / src / item.rs
CommitLineData
e74abb32 1use super::*;
60c5eb7d 2use crate::derive::{Data, DataEnum, DataStruct, DataUnion, DeriveInput};
e74abb32
XL
3use crate::punctuated::Punctuated;
4use proc_macro2::TokenStream;
5
f035d41b
XL
6#[cfg(feature = "parsing")]
7use std::mem;
e74abb32
XL
8
9ast_enum_of_structs! {
10 /// Things that can appear directly inside of a module or scope.
11 ///
f035d41b 12 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
13 ///
14 /// # Syntax tree enum
15 ///
16 /// This type is a [syntax tree enum].
17 ///
5869c6ff
XL
18 /// [syntax tree enum]: Expr#syntax-tree-enums
19 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
1b1a35ee 20 pub enum Item {
e74abb32
XL
21 /// A constant item: `const MAX: u16 = 65535`.
22 Const(ItemConst),
23
24 /// An enum definition: `enum Foo<A, B> { A(A), B(B) }`.
25 Enum(ItemEnum),
26
27 /// An `extern crate` item: `extern crate serde`.
28 ExternCrate(ItemExternCrate),
29
30 /// A free-standing function: `fn process(n: usize) -> Result<()> { ...
31 /// }`.
32 Fn(ItemFn),
33
34 /// A block of foreign items: `extern "C" { ... }`.
35 ForeignMod(ItemForeignMod),
36
37 /// An impl block providing trait or associated items: `impl<A> Trait
38 /// for Data<A> { ... }`.
39 Impl(ItemImpl),
40
41 /// A macro invocation, which includes `macro_rules!` definitions.
42 Macro(ItemMacro),
43
44 /// A 2.0-style declarative macro introduced by the `macro` keyword.
45 Macro2(ItemMacro2),
46
47 /// A module or module declaration: `mod m` or `mod m { ... }`.
48 Mod(ItemMod),
49
50 /// A static item: `static BIKE: Shed = Shed(42)`.
51 Static(ItemStatic),
52
53 /// A struct definition: `struct Foo<A> { x: A }`.
54 Struct(ItemStruct),
55
56 /// A trait definition: `pub trait Iterator { ... }`.
57 Trait(ItemTrait),
58
59 /// A trait alias: `pub trait SharableIterator = Iterator + Sync`.
60 TraitAlias(ItemTraitAlias),
61
62 /// A type alias: `type Result<T> = std::result::Result<T, MyError>`.
63 Type(ItemType),
64
65 /// A union definition: `union Foo<A, B> { x: A, y: B }`.
66 Union(ItemUnion),
67
68 /// A use declaration: `use std::collections::HashMap`.
69 Use(ItemUse),
70
71 /// Tokens forming an item not interpreted by Syn.
72 Verbatim(TokenStream),
73
5869c6ff
XL
74 // The following is the only supported idiom for exhaustive matching of
75 // this enum.
76 //
77 // match expr {
78 // Item::Const(e) => {...}
79 // Item::Enum(e) => {...}
80 // ...
81 // Item::Verbatim(e) => {...}
82 //
83 // #[cfg(test)]
84 // Item::__TestExhaustive(_) => unimplemented!(),
85 // #[cfg(not(test))]
86 // _ => { /* some sane fallback */ }
87 // }
88 //
89 // This way we fail your tests but don't break your library when adding
90 // a variant. You will be notified by a test failure when a variant is
91 // added, so that you can add code to handle it, but your library will
92 // continue to compile and work for downstream users in the interim.
93 //
94 // Once `deny(reachable)` is available in rustc, Item will be
95 // reimplemented as a non_exhaustive enum.
96 // https://github.com/rust-lang/rust/issues/44109#issuecomment-521781237
e74abb32 97 #[doc(hidden)]
5869c6ff 98 __TestExhaustive(crate::private),
e74abb32
XL
99 }
100}
101
102ast_struct! {
103 /// A constant item: `const MAX: u16 = 65535`.
104 ///
f035d41b 105 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 106 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
107 pub struct ItemConst {
108 pub attrs: Vec<Attribute>,
109 pub vis: Visibility,
110 pub const_token: Token![const],
111 pub ident: Ident,
112 pub colon_token: Token![:],
113 pub ty: Box<Type>,
114 pub eq_token: Token![=],
115 pub expr: Box<Expr>,
116 pub semi_token: Token![;],
117 }
118}
119
120ast_struct! {
121 /// An enum definition: `enum Foo<A, B> { A(A), B(B) }`.
122 ///
f035d41b 123 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 124 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
125 pub struct ItemEnum {
126 pub attrs: Vec<Attribute>,
127 pub vis: Visibility,
128 pub enum_token: Token![enum],
129 pub ident: Ident,
130 pub generics: Generics,
131 pub brace_token: token::Brace,
132 pub variants: Punctuated<Variant, Token![,]>,
133 }
134}
135
136ast_struct! {
137 /// An `extern crate` item: `extern crate serde`.
138 ///
f035d41b 139 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 140 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
141 pub struct ItemExternCrate {
142 pub attrs: Vec<Attribute>,
143 pub vis: Visibility,
144 pub extern_token: Token![extern],
145 pub crate_token: Token![crate],
146 pub ident: Ident,
147 pub rename: Option<(Token![as], Ident)>,
148 pub semi_token: Token![;],
149 }
150}
151
152ast_struct! {
153 /// A free-standing function: `fn process(n: usize) -> Result<()> { ...
154 /// }`.
155 ///
f035d41b 156 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 157 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
158 pub struct ItemFn {
159 pub attrs: Vec<Attribute>,
160 pub vis: Visibility,
161 pub sig: Signature,
162 pub block: Box<Block>,
163 }
164}
165
166ast_struct! {
167 /// A block of foreign items: `extern "C" { ... }`.
168 ///
f035d41b 169 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 170 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
171 pub struct ItemForeignMod {
172 pub attrs: Vec<Attribute>,
173 pub abi: Abi,
174 pub brace_token: token::Brace,
175 pub items: Vec<ForeignItem>,
176 }
177}
178
179ast_struct! {
180 /// An impl block providing trait or associated items: `impl<A> Trait
181 /// for Data<A> { ... }`.
182 ///
f035d41b 183 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 184 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
185 pub struct ItemImpl {
186 pub attrs: Vec<Attribute>,
187 pub defaultness: Option<Token![default]>,
188 pub unsafety: Option<Token![unsafe]>,
189 pub impl_token: Token![impl],
190 pub generics: Generics,
191 /// Trait this impl implements.
192 pub trait_: Option<(Option<Token![!]>, Path, Token![for])>,
193 /// The Self type of the impl.
194 pub self_ty: Box<Type>,
195 pub brace_token: token::Brace,
196 pub items: Vec<ImplItem>,
197 }
198}
199
200ast_struct! {
201 /// A macro invocation, which includes `macro_rules!` definitions.
202 ///
f035d41b 203 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 204 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
205 pub struct ItemMacro {
206 pub attrs: Vec<Attribute>,
207 /// The `example` in `macro_rules! example { ... }`.
208 pub ident: Option<Ident>,
209 pub mac: Macro,
210 pub semi_token: Option<Token![;]>,
211 }
212}
213
214ast_struct! {
215 /// A 2.0-style declarative macro introduced by the `macro` keyword.
216 ///
f035d41b 217 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 218 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
1b1a35ee 219 pub struct ItemMacro2 {
e74abb32
XL
220 pub attrs: Vec<Attribute>,
221 pub vis: Visibility,
222 pub macro_token: Token![macro],
223 pub ident: Ident,
224 pub rules: TokenStream,
225 }
226}
227
228ast_struct! {
229 /// A module or module declaration: `mod m` or `mod m { ... }`.
230 ///
f035d41b 231 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 232 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
233 pub struct ItemMod {
234 pub attrs: Vec<Attribute>,
235 pub vis: Visibility,
236 pub mod_token: Token![mod],
237 pub ident: Ident,
238 pub content: Option<(token::Brace, Vec<Item>)>,
239 pub semi: Option<Token![;]>,
240 }
241}
242
243ast_struct! {
244 /// A static item: `static BIKE: Shed = Shed(42)`.
245 ///
f035d41b 246 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 247 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
248 pub struct ItemStatic {
249 pub attrs: Vec<Attribute>,
250 pub vis: Visibility,
251 pub static_token: Token![static],
252 pub mutability: Option<Token![mut]>,
253 pub ident: Ident,
254 pub colon_token: Token![:],
255 pub ty: Box<Type>,
256 pub eq_token: Token![=],
257 pub expr: Box<Expr>,
258 pub semi_token: Token![;],
259 }
260}
261
262ast_struct! {
263 /// A struct definition: `struct Foo<A> { x: A }`.
264 ///
f035d41b 265 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 266 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
267 pub struct ItemStruct {
268 pub attrs: Vec<Attribute>,
269 pub vis: Visibility,
270 pub struct_token: Token![struct],
271 pub ident: Ident,
272 pub generics: Generics,
273 pub fields: Fields,
274 pub semi_token: Option<Token![;]>,
275 }
276}
277
278ast_struct! {
279 /// A trait definition: `pub trait Iterator { ... }`.
280 ///
f035d41b 281 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 282 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
283 pub struct ItemTrait {
284 pub attrs: Vec<Attribute>,
285 pub vis: Visibility,
286 pub unsafety: Option<Token![unsafe]>,
287 pub auto_token: Option<Token![auto]>,
288 pub trait_token: Token![trait],
289 pub ident: Ident,
290 pub generics: Generics,
291 pub colon_token: Option<Token![:]>,
292 pub supertraits: Punctuated<TypeParamBound, Token![+]>,
293 pub brace_token: token::Brace,
294 pub items: Vec<TraitItem>,
295 }
296}
297
298ast_struct! {
299 /// A trait alias: `pub trait SharableIterator = Iterator + Sync`.
300 ///
f035d41b 301 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 302 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
303 pub struct ItemTraitAlias {
304 pub attrs: Vec<Attribute>,
305 pub vis: Visibility,
306 pub trait_token: Token![trait],
307 pub ident: Ident,
308 pub generics: Generics,
309 pub eq_token: Token![=],
310 pub bounds: Punctuated<TypeParamBound, Token![+]>,
311 pub semi_token: Token![;],
312 }
313}
314
315ast_struct! {
316 /// A type alias: `type Result<T> = std::result::Result<T, MyError>`.
317 ///
f035d41b 318 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 319 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
320 pub struct ItemType {
321 pub attrs: Vec<Attribute>,
322 pub vis: Visibility,
323 pub type_token: Token![type],
324 pub ident: Ident,
325 pub generics: Generics,
326 pub eq_token: Token![=],
327 pub ty: Box<Type>,
328 pub semi_token: Token![;],
329 }
330}
331
332ast_struct! {
333 /// A union definition: `union Foo<A, B> { x: A, y: B }`.
334 ///
f035d41b 335 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 336 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
337 pub struct ItemUnion {
338 pub attrs: Vec<Attribute>,
339 pub vis: Visibility,
340 pub union_token: Token![union],
341 pub ident: Ident,
342 pub generics: Generics,
343 pub fields: FieldsNamed,
344 }
345}
346
347ast_struct! {
348 /// A use declaration: `use std::collections::HashMap`.
349 ///
f035d41b 350 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 351 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
352 pub struct ItemUse {
353 pub attrs: Vec<Attribute>,
354 pub vis: Visibility,
355 pub use_token: Token![use],
356 pub leading_colon: Option<Token![::]>,
357 pub tree: UseTree,
358 pub semi_token: Token![;],
359 }
360}
361
f035d41b
XL
362impl Item {
363 #[cfg(feature = "parsing")]
364 pub(crate) fn replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute> {
365 match self {
366 Item::ExternCrate(ItemExternCrate { attrs, .. })
367 | Item::Use(ItemUse { attrs, .. })
368 | Item::Static(ItemStatic { attrs, .. })
369 | Item::Const(ItemConst { attrs, .. })
370 | Item::Fn(ItemFn { attrs, .. })
371 | Item::Mod(ItemMod { attrs, .. })
372 | Item::ForeignMod(ItemForeignMod { attrs, .. })
373 | Item::Type(ItemType { attrs, .. })
374 | Item::Struct(ItemStruct { attrs, .. })
375 | Item::Enum(ItemEnum { attrs, .. })
376 | Item::Union(ItemUnion { attrs, .. })
377 | Item::Trait(ItemTrait { attrs, .. })
378 | Item::TraitAlias(ItemTraitAlias { attrs, .. })
379 | Item::Impl(ItemImpl { attrs, .. })
380 | Item::Macro(ItemMacro { attrs, .. })
381 | Item::Macro2(ItemMacro2 { attrs, .. }) => mem::replace(attrs, new),
382 Item::Verbatim(_) => Vec::new(),
5869c6ff 383 Item::__TestExhaustive(_) => unreachable!(),
f035d41b
XL
384 }
385 }
386}
387
e74abb32
XL
388impl From<DeriveInput> for Item {
389 fn from(input: DeriveInput) -> Item {
390 match input.data {
391 Data::Struct(data) => Item::Struct(ItemStruct {
392 attrs: input.attrs,
393 vis: input.vis,
394 struct_token: data.struct_token,
395 ident: input.ident,
396 generics: input.generics,
397 fields: data.fields,
398 semi_token: data.semi_token,
399 }),
400 Data::Enum(data) => Item::Enum(ItemEnum {
401 attrs: input.attrs,
402 vis: input.vis,
403 enum_token: data.enum_token,
404 ident: input.ident,
405 generics: input.generics,
406 brace_token: data.brace_token,
407 variants: data.variants,
408 }),
409 Data::Union(data) => Item::Union(ItemUnion {
410 attrs: input.attrs,
411 vis: input.vis,
412 union_token: data.union_token,
413 ident: input.ident,
414 generics: input.generics,
415 fields: data.fields,
416 }),
417 }
418 }
419}
420
60c5eb7d
XL
421impl From<ItemStruct> for DeriveInput {
422 fn from(input: ItemStruct) -> DeriveInput {
423 DeriveInput {
424 attrs: input.attrs,
425 vis: input.vis,
426 ident: input.ident,
427 generics: input.generics,
428 data: Data::Struct(DataStruct {
429 struct_token: input.struct_token,
430 fields: input.fields,
431 semi_token: input.semi_token,
432 }),
433 }
434 }
435}
436
437impl From<ItemEnum> for DeriveInput {
438 fn from(input: ItemEnum) -> DeriveInput {
439 DeriveInput {
440 attrs: input.attrs,
441 vis: input.vis,
442 ident: input.ident,
443 generics: input.generics,
444 data: Data::Enum(DataEnum {
445 enum_token: input.enum_token,
446 brace_token: input.brace_token,
447 variants: input.variants,
448 }),
449 }
450 }
451}
452
453impl From<ItemUnion> for DeriveInput {
454 fn from(input: ItemUnion) -> DeriveInput {
455 DeriveInput {
456 attrs: input.attrs,
457 vis: input.vis,
458 ident: input.ident,
459 generics: input.generics,
460 data: Data::Union(DataUnion {
461 union_token: input.union_token,
462 fields: input.fields,
463 }),
464 }
465 }
466}
467
e74abb32
XL
468ast_enum_of_structs! {
469 /// A suffix of an import tree in a `use` item: `Type as Renamed` or `*`.
470 ///
f035d41b 471 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
472 ///
473 /// # Syntax tree enum
474 ///
475 /// This type is a [syntax tree enum].
476 ///
5869c6ff
XL
477 /// [syntax tree enum]: Expr#syntax-tree-enums
478 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
479 pub enum UseTree {
480 /// A path prefix of imports in a `use` item: `std::...`.
481 Path(UsePath),
482
483 /// An identifier imported by a `use` item: `HashMap`.
484 Name(UseName),
485
486 /// An renamed identifier imported by a `use` item: `HashMap as Map`.
487 Rename(UseRename),
488
489 /// A glob import in a `use` item: `*`.
490 Glob(UseGlob),
491
492 /// A braced group of imports in a `use` item: `{A, B, C}`.
493 Group(UseGroup),
494 }
495}
496
497ast_struct! {
498 /// A path prefix of imports in a `use` item: `std::...`.
499 ///
f035d41b 500 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 501 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
502 pub struct UsePath {
503 pub ident: Ident,
504 pub colon2_token: Token![::],
505 pub tree: Box<UseTree>,
506 }
507}
508
509ast_struct! {
510 /// An identifier imported by a `use` item: `HashMap`.
511 ///
f035d41b 512 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 513 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
514 pub struct UseName {
515 pub ident: Ident,
516 }
517}
518
519ast_struct! {
520 /// An renamed identifier imported by a `use` item: `HashMap as Map`.
521 ///
f035d41b 522 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 523 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
524 pub struct UseRename {
525 pub ident: Ident,
526 pub as_token: Token![as],
527 pub rename: Ident,
528 }
529}
530
531ast_struct! {
532 /// A glob import in a `use` item: `*`.
533 ///
f035d41b 534 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 535 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
536 pub struct UseGlob {
537 pub star_token: Token![*],
538 }
539}
540
541ast_struct! {
542 /// A braced group of imports in a `use` item: `{A, B, C}`.
543 ///
f035d41b 544 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 545 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
546 pub struct UseGroup {
547 pub brace_token: token::Brace,
548 pub items: Punctuated<UseTree, Token![,]>,
549 }
550}
551
552ast_enum_of_structs! {
553 /// An item within an `extern` block.
554 ///
f035d41b 555 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
556 ///
557 /// # Syntax tree enum
558 ///
559 /// This type is a [syntax tree enum].
560 ///
5869c6ff
XL
561 /// [syntax tree enum]: Expr#syntax-tree-enums
562 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
1b1a35ee 563 pub enum ForeignItem {
e74abb32
XL
564 /// A foreign function in an `extern` block.
565 Fn(ForeignItemFn),
566
567 /// A foreign static item in an `extern` block: `static ext: u8`.
568 Static(ForeignItemStatic),
569
570 /// A foreign type in an `extern` block: `type void`.
571 Type(ForeignItemType),
572
573 /// A macro invocation within an extern block.
574 Macro(ForeignItemMacro),
575
576 /// Tokens in an `extern` block not interpreted by Syn.
577 Verbatim(TokenStream),
578
5869c6ff
XL
579 // The following is the only supported idiom for exhaustive matching of
580 // this enum.
581 //
582 // match expr {
583 // ForeignItem::Fn(e) => {...}
584 // ForeignItem::Static(e) => {...}
585 // ...
586 // ForeignItem::Verbatim(e) => {...}
587 //
588 // #[cfg(test)]
589 // ForeignItem::__TestExhaustive(_) => unimplemented!(),
590 // #[cfg(not(test))]
591 // _ => { /* some sane fallback */ }
592 // }
593 //
594 // This way we fail your tests but don't break your library when adding
595 // a variant. You will be notified by a test failure when a variant is
596 // added, so that you can add code to handle it, but your library will
597 // continue to compile and work for downstream users in the interim.
598 //
599 // Once `deny(reachable)` is available in rustc, ForeignItem will be
600 // reimplemented as a non_exhaustive enum.
601 // https://github.com/rust-lang/rust/issues/44109#issuecomment-521781237
e74abb32 602 #[doc(hidden)]
5869c6ff 603 __TestExhaustive(crate::private),
e74abb32
XL
604 }
605}
606
607ast_struct! {
608 /// A foreign function in an `extern` block.
609 ///
f035d41b 610 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 611 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
612 pub struct ForeignItemFn {
613 pub attrs: Vec<Attribute>,
614 pub vis: Visibility,
615 pub sig: Signature,
616 pub semi_token: Token![;],
617 }
618}
619
620ast_struct! {
621 /// A foreign static item in an `extern` block: `static ext: u8`.
622 ///
f035d41b 623 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 624 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
625 pub struct ForeignItemStatic {
626 pub attrs: Vec<Attribute>,
627 pub vis: Visibility,
628 pub static_token: Token![static],
629 pub mutability: Option<Token![mut]>,
630 pub ident: Ident,
631 pub colon_token: Token![:],
632 pub ty: Box<Type>,
633 pub semi_token: Token![;],
634 }
635}
636
637ast_struct! {
638 /// A foreign type in an `extern` block: `type void`.
639 ///
f035d41b 640 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 641 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
642 pub struct ForeignItemType {
643 pub attrs: Vec<Attribute>,
644 pub vis: Visibility,
645 pub type_token: Token![type],
646 pub ident: Ident,
647 pub semi_token: Token![;],
648 }
649}
650
651ast_struct! {
652 /// A macro invocation within an extern block.
653 ///
f035d41b 654 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 655 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
656 pub struct ForeignItemMacro {
657 pub attrs: Vec<Attribute>,
658 pub mac: Macro,
659 pub semi_token: Option<Token![;]>,
660 }
661}
662
e74abb32
XL
663ast_enum_of_structs! {
664 /// An item declaration within the definition of a trait.
665 ///
f035d41b 666 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
667 ///
668 /// # Syntax tree enum
669 ///
670 /// This type is a [syntax tree enum].
671 ///
5869c6ff
XL
672 /// [syntax tree enum]: Expr#syntax-tree-enums
673 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
1b1a35ee 674 pub enum TraitItem {
e74abb32
XL
675 /// An associated constant within the definition of a trait.
676 Const(TraitItemConst),
677
678 /// A trait method within the definition of a trait.
679 Method(TraitItemMethod),
680
681 /// An associated type within the definition of a trait.
682 Type(TraitItemType),
683
684 /// A macro invocation within the definition of a trait.
685 Macro(TraitItemMacro),
686
687 /// Tokens within the definition of a trait not interpreted by Syn.
688 Verbatim(TokenStream),
689
5869c6ff
XL
690 // The following is the only supported idiom for exhaustive matching of
691 // this enum.
692 //
693 // match expr {
694 // TraitItem::Const(e) => {...}
695 // TraitItem::Method(e) => {...}
696 // ...
697 // TraitItem::Verbatim(e) => {...}
698 //
699 // #[cfg(test)]
700 // TraitItem::__TestExhaustive(_) => unimplemented!(),
701 // #[cfg(not(test))]
702 // _ => { /* some sane fallback */ }
703 // }
704 //
705 // This way we fail your tests but don't break your library when adding
706 // a variant. You will be notified by a test failure when a variant is
707 // added, so that you can add code to handle it, but your library will
708 // continue to compile and work for downstream users in the interim.
709 //
710 // Once `deny(reachable)` is available in rustc, TraitItem will be
711 // reimplemented as a non_exhaustive enum.
712 // https://github.com/rust-lang/rust/issues/44109#issuecomment-521781237
e74abb32 713 #[doc(hidden)]
5869c6ff 714 __TestExhaustive(crate::private),
e74abb32
XL
715 }
716}
717
718ast_struct! {
719 /// An associated constant within the definition of a trait.
720 ///
f035d41b 721 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 722 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
723 pub struct TraitItemConst {
724 pub attrs: Vec<Attribute>,
725 pub const_token: Token![const],
726 pub ident: Ident,
727 pub colon_token: Token![:],
728 pub ty: Type,
729 pub default: Option<(Token![=], Expr)>,
730 pub semi_token: Token![;],
731 }
732}
733
734ast_struct! {
735 /// A trait method within the definition of a trait.
736 ///
f035d41b 737 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 738 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
739 pub struct TraitItemMethod {
740 pub attrs: Vec<Attribute>,
741 pub sig: Signature,
742 pub default: Option<Block>,
743 pub semi_token: Option<Token![;]>,
744 }
745}
746
747ast_struct! {
748 /// An associated type within the definition of a trait.
749 ///
f035d41b 750 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 751 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
752 pub struct TraitItemType {
753 pub attrs: Vec<Attribute>,
754 pub type_token: Token![type],
755 pub ident: Ident,
756 pub generics: Generics,
757 pub colon_token: Option<Token![:]>,
758 pub bounds: Punctuated<TypeParamBound, Token![+]>,
759 pub default: Option<(Token![=], Type)>,
760 pub semi_token: Token![;],
761 }
762}
763
764ast_struct! {
765 /// A macro invocation within the definition of a trait.
766 ///
f035d41b 767 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 768 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
769 pub struct TraitItemMacro {
770 pub attrs: Vec<Attribute>,
771 pub mac: Macro,
772 pub semi_token: Option<Token![;]>,
773 }
774}
775
e74abb32
XL
776ast_enum_of_structs! {
777 /// An item within an impl block.
778 ///
f035d41b 779 /// *This type is available only if Syn is built with the `"full"` feature.*
e74abb32
XL
780 ///
781 /// # Syntax tree enum
782 ///
783 /// This type is a [syntax tree enum].
784 ///
5869c6ff
XL
785 /// [syntax tree enum]: Expr#syntax-tree-enums
786 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
1b1a35ee 787 pub enum ImplItem {
e74abb32
XL
788 /// An associated constant within an impl block.
789 Const(ImplItemConst),
790
791 /// A method within an impl block.
792 Method(ImplItemMethod),
793
794 /// An associated type within an impl block.
795 Type(ImplItemType),
796
797 /// A macro invocation within an impl block.
798 Macro(ImplItemMacro),
799
800 /// Tokens within an impl block not interpreted by Syn.
801 Verbatim(TokenStream),
802
5869c6ff
XL
803 // The following is the only supported idiom for exhaustive matching of
804 // this enum.
805 //
806 // match expr {
807 // ImplItem::Const(e) => {...}
808 // ImplItem::Method(e) => {...}
809 // ...
810 // ImplItem::Verbatim(e) => {...}
811 //
812 // #[cfg(test)]
813 // ImplItem::__TestExhaustive(_) => unimplemented!(),
814 // #[cfg(not(test))]
815 // _ => { /* some sane fallback */ }
816 // }
817 //
818 // This way we fail your tests but don't break your library when adding
819 // a variant. You will be notified by a test failure when a variant is
820 // added, so that you can add code to handle it, but your library will
821 // continue to compile and work for downstream users in the interim.
822 //
823 // Once `deny(reachable)` is available in rustc, ImplItem will be
824 // reimplemented as a non_exhaustive enum.
825 // https://github.com/rust-lang/rust/issues/44109#issuecomment-521781237
e74abb32 826 #[doc(hidden)]
5869c6ff 827 __TestExhaustive(crate::private),
e74abb32
XL
828 }
829}
830
831ast_struct! {
832 /// An associated constant within an impl block.
833 ///
f035d41b 834 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 835 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
836 pub struct ImplItemConst {
837 pub attrs: Vec<Attribute>,
838 pub vis: Visibility,
839 pub defaultness: Option<Token![default]>,
840 pub const_token: Token![const],
841 pub ident: Ident,
842 pub colon_token: Token![:],
843 pub ty: Type,
844 pub eq_token: Token![=],
845 pub expr: Expr,
846 pub semi_token: Token![;],
847 }
848}
849
850ast_struct! {
851 /// A method within an impl block.
852 ///
f035d41b 853 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 854 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
855 pub struct ImplItemMethod {
856 pub attrs: Vec<Attribute>,
857 pub vis: Visibility,
858 pub defaultness: Option<Token![default]>,
859 pub sig: Signature,
860 pub block: Block,
861 }
862}
863
864ast_struct! {
865 /// An associated type within an impl block.
866 ///
f035d41b 867 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 868 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
869 pub struct ImplItemType {
870 pub attrs: Vec<Attribute>,
871 pub vis: Visibility,
872 pub defaultness: Option<Token![default]>,
873 pub type_token: Token![type],
874 pub ident: Ident,
875 pub generics: Generics,
876 pub eq_token: Token![=],
877 pub ty: Type,
878 pub semi_token: Token![;],
879 }
880}
881
882ast_struct! {
883 /// A macro invocation within an impl block.
884 ///
f035d41b 885 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 886 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
887 pub struct ImplItemMacro {
888 pub attrs: Vec<Attribute>,
889 pub mac: Macro,
890 pub semi_token: Option<Token![;]>,
891 }
892}
893
e74abb32
XL
894ast_struct! {
895 /// A function signature in a trait or implementation: `unsafe fn
896 /// initialize(&self)`.
897 ///
f035d41b 898 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 899 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
900 pub struct Signature {
901 pub constness: Option<Token![const]>,
902 pub asyncness: Option<Token![async]>,
903 pub unsafety: Option<Token![unsafe]>,
904 pub abi: Option<Abi>,
905 pub fn_token: Token![fn],
906 pub ident: Ident,
907 pub generics: Generics,
908 pub paren_token: token::Paren,
909 pub inputs: Punctuated<FnArg, Token![,]>,
910 pub variadic: Option<Variadic>,
911 pub output: ReturnType,
912 }
913}
914
60c5eb7d
XL
915impl Signature {
916 /// A method's `self` receiver, such as `&self` or `self: Box<Self>`.
917 pub fn receiver(&self) -> Option<&FnArg> {
918 let arg = self.inputs.first()?;
919 match arg {
920 FnArg::Receiver(_) => Some(arg),
921 FnArg::Typed(PatType { pat, .. }) => {
922 if let Pat::Ident(PatIdent { ident, .. }) = &**pat {
923 if ident == "self" {
924 return Some(arg);
925 }
926 }
927 None
928 }
929 }
930 }
931}
932
e74abb32
XL
933ast_enum_of_structs! {
934 /// An argument in a function signature: the `n: usize` in `fn f(n: usize)`.
935 ///
f035d41b 936 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 937 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
938 pub enum FnArg {
939 /// The `self` argument of an associated method, whether taken by value
940 /// or by reference.
60c5eb7d
XL
941 ///
942 /// Note that `self` receivers with a specified type, such as `self:
943 /// Box<Self>`, are parsed as a `FnArg::Typed`.
e74abb32
XL
944 Receiver(Receiver),
945
946 /// A function argument accepted by pattern and type.
947 Typed(PatType),
948 }
949}
950
951ast_struct! {
952 /// The `self` argument of an associated method, whether taken by value
953 /// or by reference.
954 ///
60c5eb7d
XL
955 /// Note that `self` receivers with a specified type, such as `self:
956 /// Box<Self>`, are parsed as a `FnArg::Typed`.
957 ///
f035d41b 958 /// *This type is available only if Syn is built with the `"full"` feature.*
5869c6ff 959 #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))]
e74abb32
XL
960 pub struct Receiver {
961 pub attrs: Vec<Attribute>,
962 pub reference: Option<(Token![&], Option<Lifetime>)>,
963 pub mutability: Option<Token![mut]>,
964 pub self_token: Token![self],
965 }
966}
967
968impl Receiver {
969 pub fn lifetime(&self) -> Option<&Lifetime> {
970 self.reference.as_ref()?.1.as_ref()
971 }
972}
973
974#[cfg(feature = "parsing")]
975pub mod parsing {
976 use super::*;
e74abb32
XL
977 use crate::ext::IdentExt;
978 use crate::parse::discouraged::Speculative;
f035d41b
XL
979 use crate::parse::{Parse, ParseBuffer, ParseStream, Result};
980 use crate::token::Brace;
e74abb32
XL
981 use proc_macro2::{Delimiter, Group, Punct, Spacing, TokenTree};
982 use std::iter::{self, FromIterator};
983
984 crate::custom_keyword!(existential);
985
5869c6ff 986 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
987 impl Parse for Item {
988 fn parse(input: ParseStream) -> Result<Self> {
f035d41b 989 let begin = input.fork();
e74abb32
XL
990 let mut attrs = input.call(Attribute::parse_outer)?;
991 let ahead = input.fork();
992 let vis: Visibility = ahead.parse()?;
993
994 let lookahead = ahead.lookahead1();
f035d41b
XL
995 let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead) {
996 let vis: Visibility = input.parse()?;
29967ef6 997 let sig: Signature = input.parse()?;
f035d41b
XL
998 if input.peek(Token![;]) {
999 input.parse::<Token![;]>()?;
1000 Ok(Item::Verbatim(verbatim::between(begin, input)))
1001 } else {
1002 parse_rest_of_fn(input, Vec::new(), vis, sig).map(Item::Fn)
1003 }
1004 } else if lookahead.peek(Token![extern]) {
e74abb32
XL
1005 ahead.parse::<Token![extern]>()?;
1006 let lookahead = ahead.lookahead1();
1007 if lookahead.peek(Token![crate]) {
1008 input.parse().map(Item::ExternCrate)
e74abb32
XL
1009 } else if lookahead.peek(token::Brace) {
1010 input.parse().map(Item::ForeignMod)
1011 } else if lookahead.peek(LitStr) {
1012 ahead.parse::<LitStr>()?;
1013 let lookahead = ahead.lookahead1();
1014 if lookahead.peek(token::Brace) {
1015 input.parse().map(Item::ForeignMod)
e74abb32
XL
1016 } else {
1017 Err(lookahead.error())
1018 }
1019 } else {
1020 Err(lookahead.error())
1021 }
1022 } else if lookahead.peek(Token![use]) {
1023 input.parse().map(Item::Use)
1024 } else if lookahead.peek(Token![static]) {
f035d41b
XL
1025 let vis = input.parse()?;
1026 let static_token = input.parse()?;
1027 let mutability = input.parse()?;
1028 let ident = input.parse()?;
1029 let colon_token = input.parse()?;
1030 let ty = input.parse()?;
1031 if input.peek(Token![;]) {
1032 input.parse::<Token![;]>()?;
1033 Ok(Item::Verbatim(verbatim::between(begin, input)))
1034 } else {
1035 Ok(Item::Static(ItemStatic {
1036 attrs: Vec::new(),
1037 vis,
1038 static_token,
1039 mutability,
1040 ident,
1041 colon_token,
1042 ty,
1043 eq_token: input.parse()?,
1044 expr: input.parse()?,
1045 semi_token: input.parse()?,
1046 }))
1047 }
e74abb32
XL
1048 } else if lookahead.peek(Token![const]) {
1049 ahead.parse::<Token![const]>()?;
1050 let lookahead = ahead.lookahead1();
1051 if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
f035d41b
XL
1052 let vis = input.parse()?;
1053 let const_token = input.parse()?;
1054 let ident = {
1055 let lookahead = input.lookahead1();
1056 if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
1057 input.call(Ident::parse_any)?
1058 } else {
1059 return Err(lookahead.error());
1060 }
1061 };
1062 let colon_token = input.parse()?;
1063 let ty = input.parse()?;
1064 if input.peek(Token![;]) {
1065 input.parse::<Token![;]>()?;
1066 Ok(Item::Verbatim(verbatim::between(begin, input)))
1067 } else {
1068 Ok(Item::Const(ItemConst {
1069 attrs: Vec::new(),
1070 vis,
1071 const_token,
1072 ident,
1073 colon_token,
1074 ty,
1075 eq_token: input.parse()?,
1076 expr: input.parse()?,
1077 semi_token: input.parse()?,
1078 }))
1079 }
e74abb32
XL
1080 } else {
1081 Err(lookahead.error())
1082 }
1083 } else if lookahead.peek(Token![unsafe]) {
1084 ahead.parse::<Token![unsafe]>()?;
1085 let lookahead = ahead.lookahead1();
1086 if lookahead.peek(Token![trait])
1087 || lookahead.peek(Token![auto]) && ahead.peek2(Token![trait])
1088 {
1089 input.parse().map(Item::Trait)
1090 } else if lookahead.peek(Token![impl]) {
f035d41b
XL
1091 let allow_const_impl = true;
1092 if let Some(item) = parse_impl(input, allow_const_impl)? {
1093 Ok(Item::Impl(item))
1094 } else {
1095 Ok(Item::Verbatim(verbatim::between(begin, input)))
1096 }
5869c6ff
XL
1097 } else if lookahead.peek(Token![extern]) {
1098 input.parse::<Visibility>()?;
1099 input.parse::<Token![unsafe]>()?;
1100 input.parse::<ItemForeignMod>()?;
1101 Ok(Item::Verbatim(verbatim::between(begin, input)))
1102 } else if lookahead.peek(Token![mod]) {
1103 input.parse::<Visibility>()?;
1104 input.parse::<Token![unsafe]>()?;
1105 input.parse::<ItemMod>()?;
1106 Ok(Item::Verbatim(verbatim::between(begin, input)))
e74abb32
XL
1107 } else {
1108 Err(lookahead.error())
1109 }
e74abb32
XL
1110 } else if lookahead.peek(Token![mod]) {
1111 input.parse().map(Item::Mod)
1112 } else if lookahead.peek(Token![type]) {
f035d41b 1113 parse_item_type(begin, input)
e74abb32
XL
1114 } else if lookahead.peek(existential) {
1115 input.call(item_existential).map(Item::Verbatim)
1116 } else if lookahead.peek(Token![struct]) {
1117 input.parse().map(Item::Struct)
1118 } else if lookahead.peek(Token![enum]) {
1119 input.parse().map(Item::Enum)
1120 } else if lookahead.peek(Token![union]) && ahead.peek2(Ident) {
1121 input.parse().map(Item::Union)
1122 } else if lookahead.peek(Token![trait]) {
1123 input.call(parse_trait_or_trait_alias)
1124 } else if lookahead.peek(Token![auto]) && ahead.peek2(Token![trait]) {
1125 input.parse().map(Item::Trait)
1126 } else if lookahead.peek(Token![impl])
1127 || lookahead.peek(Token![default]) && !ahead.peek2(Token![!])
1128 {
f035d41b
XL
1129 let allow_const_impl = true;
1130 if let Some(item) = parse_impl(input, allow_const_impl)? {
1131 Ok(Item::Impl(item))
1132 } else {
1133 Ok(Item::Verbatim(verbatim::between(begin, input)))
1134 }
e74abb32
XL
1135 } else if lookahead.peek(Token![macro]) {
1136 input.parse().map(Item::Macro2)
1137 } else if vis.is_inherited()
1138 && (lookahead.peek(Ident)
1139 || lookahead.peek(Token![self])
1140 || lookahead.peek(Token![super])
e74abb32
XL
1141 || lookahead.peek(Token![crate])
1142 || lookahead.peek(Token![::]))
1143 {
1144 input.parse().map(Item::Macro)
1145 } else {
1146 Err(lookahead.error())
1147 }?;
1148
f035d41b
XL
1149 attrs.extend(item.replace_attrs(Vec::new()));
1150 item.replace_attrs(attrs);
1151 Ok(item)
1152 }
1153 }
1154
1155 struct FlexibleItemType {
1156 vis: Visibility,
1157 defaultness: Option<Token![default]>,
1158 type_token: Token![type],
1159 ident: Ident,
1160 generics: Generics,
1161 colon_token: Option<Token![:]>,
1162 bounds: Punctuated<TypeParamBound, Token![+]>,
1163 ty: Option<(Token![=], Type)>,
1164 semi_token: Token![;],
1165 }
1166
5869c6ff 1167 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
f035d41b
XL
1168 impl Parse for FlexibleItemType {
1169 fn parse(input: ParseStream) -> Result<Self> {
1170 let vis: Visibility = input.parse()?;
1171 let defaultness: Option<Token![default]> = input.parse()?;
1172 let type_token: Token![type] = input.parse()?;
1173 let ident: Ident = input.parse()?;
1174 let mut generics: Generics = input.parse()?;
1175 let colon_token: Option<Token![:]> = input.parse()?;
1176 let mut bounds = Punctuated::new();
1177 if colon_token.is_some() {
1178 loop {
1179 bounds.push_value(input.parse::<TypeParamBound>()?);
1180 if input.peek(Token![where]) || input.peek(Token![=]) || input.peek(Token![;]) {
1181 break;
1182 }
1183 bounds.push_punct(input.parse::<Token![+]>()?);
1184 if input.peek(Token![where]) || input.peek(Token![=]) || input.peek(Token![;]) {
1185 break;
1186 }
1187 }
e74abb32 1188 }
f035d41b
XL
1189 generics.where_clause = input.parse()?;
1190 let ty = if let Some(eq_token) = input.parse()? {
1191 Some((eq_token, input.parse::<Type>()?))
1192 } else {
1193 None
1194 };
1195 let semi_token: Token![;] = input.parse()?;
e74abb32 1196
f035d41b
XL
1197 Ok(FlexibleItemType {
1198 vis,
1199 defaultness,
1200 type_token,
1201 ident,
1202 generics,
1203 colon_token,
1204 bounds,
1205 ty,
1206 semi_token,
1207 })
e74abb32
XL
1208 }
1209 }
1210
5869c6ff 1211 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
1212 impl Parse for ItemMacro {
1213 fn parse(input: ParseStream) -> Result<Self> {
1214 let attrs = input.call(Attribute::parse_outer)?;
1215 let path = input.call(Path::parse_mod_style)?;
1216 let bang_token: Token![!] = input.parse()?;
1217 let ident: Option<Ident> = input.parse()?;
1218 let (delimiter, tokens) = input.call(mac::parse_delimiter)?;
1219 let semi_token: Option<Token![;]> = if !delimiter.is_brace() {
1220 Some(input.parse()?)
1221 } else {
1222 None
1223 };
1224 Ok(ItemMacro {
1225 attrs,
1226 ident,
1227 mac: Macro {
1228 path,
1229 bang_token,
1230 delimiter,
1231 tokens,
1232 },
1233 semi_token,
1234 })
1235 }
1236 }
1237
5869c6ff 1238 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
1239 impl Parse for ItemMacro2 {
1240 fn parse(input: ParseStream) -> Result<Self> {
1241 let attrs = input.call(Attribute::parse_outer)?;
1242 let vis: Visibility = input.parse()?;
1243 let macro_token: Token![macro] = input.parse()?;
1244 let ident: Ident = input.parse()?;
1245 let mut rules = TokenStream::new();
1246
1247 let mut lookahead = input.lookahead1();
1248 if lookahead.peek(token::Paren) {
1249 let paren_content;
1250 let paren_token = parenthesized!(paren_content in input);
1251 let args: TokenStream = paren_content.parse()?;
1252 let mut args = Group::new(Delimiter::Parenthesis, args);
1253 args.set_span(paren_token.span);
1254 rules.extend(iter::once(TokenTree::Group(args)));
1255 lookahead = input.lookahead1();
1256 }
1257
1258 if lookahead.peek(token::Brace) {
1259 let brace_content;
1260 let brace_token = braced!(brace_content in input);
1261 let body: TokenStream = brace_content.parse()?;
1262 let mut body = Group::new(Delimiter::Brace, body);
1263 body.set_span(brace_token.span);
1264 rules.extend(iter::once(TokenTree::Group(body)));
1265 } else {
1266 return Err(lookahead.error());
1267 }
1268
1269 Ok(ItemMacro2 {
1270 attrs,
1271 vis,
1272 macro_token,
1273 ident,
1274 rules,
1275 })
1276 }
1277 }
1278
5869c6ff 1279 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
1280 impl Parse for ItemExternCrate {
1281 fn parse(input: ParseStream) -> Result<Self> {
1282 Ok(ItemExternCrate {
1283 attrs: input.call(Attribute::parse_outer)?,
1284 vis: input.parse()?,
1285 extern_token: input.parse()?,
1286 crate_token: input.parse()?,
1287 ident: {
1288 if input.peek(Token![self]) {
1289 input.call(Ident::parse_any)?
1290 } else {
1291 input.parse()?
1292 }
1293 },
1294 rename: {
1295 if input.peek(Token![as]) {
1296 let as_token: Token![as] = input.parse()?;
1297 let rename: Ident = if input.peek(Token![_]) {
1298 Ident::from(input.parse::<Token![_]>()?)
1299 } else {
1300 input.parse()?
1301 };
1302 Some((as_token, rename))
1303 } else {
1304 None
1305 }
1306 },
1307 semi_token: input.parse()?,
1308 })
1309 }
1310 }
1311
5869c6ff 1312 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
1313 impl Parse for ItemUse {
1314 fn parse(input: ParseStream) -> Result<Self> {
1315 Ok(ItemUse {
1316 attrs: input.call(Attribute::parse_outer)?,
1317 vis: input.parse()?,
1318 use_token: input.parse()?,
1319 leading_colon: input.parse()?,
1320 tree: input.parse()?,
1321 semi_token: input.parse()?,
1322 })
1323 }
1324 }
1325
5869c6ff 1326 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
1327 impl Parse for UseTree {
1328 fn parse(input: ParseStream) -> Result<UseTree> {
1329 let lookahead = input.lookahead1();
1330 if lookahead.peek(Ident)
1331 || lookahead.peek(Token![self])
1332 || lookahead.peek(Token![super])
1333 || lookahead.peek(Token![crate])
e74abb32
XL
1334 {
1335 let ident = input.call(Ident::parse_any)?;
1336 if input.peek(Token![::]) {
1337 Ok(UseTree::Path(UsePath {
1338 ident,
1339 colon2_token: input.parse()?,
1340 tree: Box::new(input.parse()?),
1341 }))
1342 } else if input.peek(Token![as]) {
1343 Ok(UseTree::Rename(UseRename {
1344 ident,
1345 as_token: input.parse()?,
1346 rename: {
1347 if input.peek(Ident) {
1348 input.parse()?
1349 } else if input.peek(Token![_]) {
1350 Ident::from(input.parse::<Token![_]>()?)
1351 } else {
1352 return Err(input.error("expected identifier or underscore"));
1353 }
1354 },
1355 }))
1356 } else {
1357 Ok(UseTree::Name(UseName { ident }))
1358 }
1359 } else if lookahead.peek(Token![*]) {
1360 Ok(UseTree::Glob(UseGlob {
1361 star_token: input.parse()?,
1362 }))
1363 } else if lookahead.peek(token::Brace) {
1364 let content;
1365 Ok(UseTree::Group(UseGroup {
1366 brace_token: braced!(content in input),
1367 items: content.parse_terminated(UseTree::parse)?,
1368 }))
1369 } else {
1370 Err(lookahead.error())
1371 }
1372 }
1373 }
1374
5869c6ff 1375 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
1376 impl Parse for ItemStatic {
1377 fn parse(input: ParseStream) -> Result<Self> {
1378 Ok(ItemStatic {
1379 attrs: input.call(Attribute::parse_outer)?,
1380 vis: input.parse()?,
1381 static_token: input.parse()?,
1382 mutability: input.parse()?,
1383 ident: input.parse()?,
1384 colon_token: input.parse()?,
1385 ty: input.parse()?,
1386 eq_token: input.parse()?,
1387 expr: input.parse()?,
1388 semi_token: input.parse()?,
1389 })
1390 }
1391 }
1392
5869c6ff 1393 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
1394 impl Parse for ItemConst {
1395 fn parse(input: ParseStream) -> Result<Self> {
1396 Ok(ItemConst {
1397 attrs: input.call(Attribute::parse_outer)?,
1398 vis: input.parse()?,
1399 const_token: input.parse()?,
1400 ident: {
1401 let lookahead = input.lookahead1();
1402 if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
1403 input.call(Ident::parse_any)?
1404 } else {
1405 return Err(lookahead.error());
1406 }
1407 },
1408 colon_token: input.parse()?,
1409 ty: input.parse()?,
1410 eq_token: input.parse()?,
1411 expr: input.parse()?,
1412 semi_token: input.parse()?,
1413 })
1414 }
1415 }
1416
f035d41b
XL
1417 fn pop_variadic(args: &mut Punctuated<FnArg, Token![,]>) -> Option<Variadic> {
1418 let trailing_punct = args.trailing_punct();
e74abb32 1419
f035d41b
XL
1420 let last = match args.last_mut()? {
1421 FnArg::Typed(last) => last,
1422 _ => return None,
1423 };
1424
1425 let ty = match last.ty.as_ref() {
1426 Type::Verbatim(ty) => ty,
1427 _ => return None,
1428 };
1429
1430 let mut variadic = Variadic {
1431 attrs: Vec::new(),
1432 dots: parse2(ty.clone()).ok()?,
1433 };
1434
1435 if let Pat::Verbatim(pat) = last.pat.as_ref() {
1436 if pat.to_string() == "..." && !trailing_punct {
1437 variadic.attrs = mem::replace(&mut last.attrs, Vec::new());
1438 args.pop();
e74abb32 1439 }
f035d41b 1440 }
e74abb32 1441
f035d41b
XL
1442 Some(variadic)
1443 }
e74abb32 1444
f035d41b
XL
1445 fn variadic_to_tokens(dots: &Token![...]) -> TokenStream {
1446 TokenStream::from_iter(vec![
1447 TokenTree::Punct({
1448 let mut dot = Punct::new('.', Spacing::Joint);
1449 dot.set_span(dots.spans[0]);
1450 dot
1451 }),
1452 TokenTree::Punct({
1453 let mut dot = Punct::new('.', Spacing::Joint);
1454 dot.set_span(dots.spans[1]);
1455 dot
1456 }),
1457 TokenTree::Punct({
1458 let mut dot = Punct::new('.', Spacing::Alone);
1459 dot.set_span(dots.spans[2]);
1460 dot
1461 }),
1462 ])
1463 }
e74abb32 1464
f035d41b
XL
1465 fn peek_signature(input: ParseStream) -> bool {
1466 let fork = input.fork();
1467 fork.parse::<Option<Token![const]>>().is_ok()
1468 && fork.parse::<Option<Token![async]>>().is_ok()
1469 && fork.parse::<Option<Token![unsafe]>>().is_ok()
1470 && fork.parse::<Option<Abi>>().is_ok()
1471 && fork.peek(Token![fn])
1472 }
1473
5869c6ff 1474 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
29967ef6
XL
1475 impl Parse for Signature {
1476 fn parse(input: ParseStream) -> Result<Self> {
1477 let constness: Option<Token![const]> = input.parse()?;
1478 let asyncness: Option<Token![async]> = input.parse()?;
1479 let unsafety: Option<Token![unsafe]> = input.parse()?;
1480 let abi: Option<Abi> = input.parse()?;
1481 let fn_token: Token![fn] = input.parse()?;
1482 let ident: Ident = input.parse()?;
1483 let mut generics: Generics = input.parse()?;
f035d41b 1484
29967ef6
XL
1485 let content;
1486 let paren_token = parenthesized!(content in input);
1487 let mut inputs = parse_fn_args(&content)?;
1488 let variadic = pop_variadic(&mut inputs);
f035d41b 1489
29967ef6
XL
1490 let output: ReturnType = input.parse()?;
1491 generics.where_clause = input.parse()?;
f035d41b 1492
29967ef6
XL
1493 Ok(Signature {
1494 constness,
1495 asyncness,
1496 unsafety,
1497 abi,
1498 fn_token,
1499 ident,
1500 paren_token,
1501 inputs,
1502 output,
1503 variadic,
1504 generics,
1505 })
1506 }
f035d41b
XL
1507 }
1508
5869c6ff 1509 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
f035d41b
XL
1510 impl Parse for ItemFn {
1511 fn parse(input: ParseStream) -> Result<Self> {
1512 let outer_attrs = input.call(Attribute::parse_outer)?;
1513 let vis: Visibility = input.parse()?;
29967ef6 1514 let sig: Signature = input.parse()?;
f035d41b 1515 parse_rest_of_fn(input, outer_attrs, vis, sig)
e74abb32
XL
1516 }
1517 }
1518
f035d41b
XL
1519 fn parse_rest_of_fn(
1520 input: ParseStream,
1521 outer_attrs: Vec<Attribute>,
1522 vis: Visibility,
1523 sig: Signature,
1524 ) -> Result<ItemFn> {
1525 let content;
1526 let brace_token = braced!(content in input);
1527 let inner_attrs = content.call(Attribute::parse_inner)?;
1528 let stmts = content.call(Block::parse_within)?;
1529
1530 Ok(ItemFn {
1531 attrs: private::attrs(outer_attrs, inner_attrs),
1532 vis,
1533 sig,
1534 block: Box::new(Block { brace_token, stmts }),
1535 })
1536 }
1537
5869c6ff 1538 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
1539 impl Parse for FnArg {
1540 fn parse(input: ParseStream) -> Result<Self> {
1541 let attrs = input.call(Attribute::parse_outer)?;
1542
1543 let ahead = input.fork();
1544 if let Ok(mut receiver) = ahead.parse::<Receiver>() {
1545 if !ahead.peek(Token![:]) {
1546 input.advance_to(&ahead);
1547 receiver.attrs = attrs;
1548 return Ok(FnArg::Receiver(receiver));
1549 }
1550 }
1551
1552 let mut typed = input.call(fn_arg_typed)?;
1553 typed.attrs = attrs;
1554 Ok(FnArg::Typed(typed))
1555 }
1556 }
1557
5869c6ff 1558 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
1559 impl Parse for Receiver {
1560 fn parse(input: ParseStream) -> Result<Self> {
1561 Ok(Receiver {
1562 attrs: Vec::new(),
1563 reference: {
1564 if input.peek(Token![&]) {
1565 Some((input.parse()?, input.parse()?))
1566 } else {
1567 None
1568 }
1569 },
1570 mutability: input.parse()?,
1571 self_token: input.parse()?,
1572 })
1573 }
1574 }
1575
f035d41b
XL
1576 fn parse_fn_args(input: ParseStream) -> Result<Punctuated<FnArg, Token![,]>> {
1577 let mut args = Punctuated::new();
1578 let mut has_receiver = false;
1579
1580 while !input.is_empty() {
1581 let attrs = input.call(Attribute::parse_outer)?;
1582
1583 let arg = if let Some(dots) = input.parse::<Option<Token![...]>>()? {
1584 FnArg::Typed(PatType {
1585 attrs,
1586 pat: Box::new(Pat::Verbatim(variadic_to_tokens(&dots))),
1587 colon_token: Token![:](dots.spans[0]),
1588 ty: Box::new(Type::Verbatim(variadic_to_tokens(&dots))),
1589 })
1590 } else {
1591 let mut arg: FnArg = input.parse()?;
1592 match &mut arg {
1593 FnArg::Receiver(receiver) if has_receiver => {
1594 return Err(Error::new(
1595 receiver.self_token.span,
1596 "unexpected second method receiver",
1597 ));
1598 }
1599 FnArg::Receiver(receiver) if !args.is_empty() => {
1600 return Err(Error::new(
1601 receiver.self_token.span,
1602 "unexpected method receiver",
1603 ));
1604 }
1605 FnArg::Receiver(receiver) => {
1606 has_receiver = true;
1607 receiver.attrs = attrs;
1608 }
1609 FnArg::Typed(arg) => arg.attrs = attrs,
1610 }
1611 arg
1612 };
1613 args.push_value(arg);
1614
1615 if input.is_empty() {
1616 break;
1617 }
1618
1619 let comma: Token![,] = input.parse()?;
1620 args.push_punct(comma);
1621 }
1622
1623 Ok(args)
1624 }
1625
e74abb32 1626 fn fn_arg_typed(input: ParseStream) -> Result<PatType> {
60c5eb7d
XL
1627 // Hack to parse pre-2018 syntax in
1628 // test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs
1629 // because the rest of the test case is valuable.
1630 if input.peek(Ident) && input.peek2(Token![<]) {
1631 let span = input.fork().parse::<Ident>()?.span();
1632 return Ok(PatType {
1633 attrs: Vec::new(),
1634 pat: Box::new(Pat::Wild(PatWild {
1635 attrs: Vec::new(),
1636 underscore_token: Token![_](span),
1637 })),
1638 colon_token: Token![:](span),
1639 ty: input.parse()?,
1640 });
1641 }
1642
e74abb32
XL
1643 Ok(PatType {
1644 attrs: Vec::new(),
f035d41b 1645 pat: Box::new(pat::parsing::multi_pat(input)?),
e74abb32
XL
1646 colon_token: input.parse()?,
1647 ty: Box::new(match input.parse::<Option<Token![...]>>()? {
f035d41b 1648 Some(dot3) => Type::Verbatim(variadic_to_tokens(&dot3)),
e74abb32
XL
1649 None => input.parse()?,
1650 }),
1651 })
1652 }
1653
5869c6ff 1654 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
1655 impl Parse for ItemMod {
1656 fn parse(input: ParseStream) -> Result<Self> {
1657 let outer_attrs = input.call(Attribute::parse_outer)?;
1658 let vis: Visibility = input.parse()?;
1659 let mod_token: Token![mod] = input.parse()?;
1660 let ident: Ident = input.parse()?;
1661
1662 let lookahead = input.lookahead1();
1663 if lookahead.peek(Token![;]) {
1664 Ok(ItemMod {
1665 attrs: outer_attrs,
1666 vis,
1667 mod_token,
1668 ident,
1669 content: None,
1670 semi: Some(input.parse()?),
1671 })
1672 } else if lookahead.peek(token::Brace) {
1673 let content;
1674 let brace_token = braced!(content in input);
1675 let inner_attrs = content.call(Attribute::parse_inner)?;
1676
1677 let mut items = Vec::new();
1678 while !content.is_empty() {
1679 items.push(content.parse()?);
1680 }
1681
1682 Ok(ItemMod {
1683 attrs: private::attrs(outer_attrs, inner_attrs),
1684 vis,
1685 mod_token,
1686 ident,
1687 content: Some((brace_token, items)),
1688 semi: None,
1689 })
1690 } else {
1691 Err(lookahead.error())
1692 }
1693 }
1694 }
1695
5869c6ff 1696 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
1697 impl Parse for ItemForeignMod {
1698 fn parse(input: ParseStream) -> Result<Self> {
1699 let outer_attrs = input.call(Attribute::parse_outer)?;
1700 let abi: Abi = input.parse()?;
1701
1702 let content;
1703 let brace_token = braced!(content in input);
1704 let inner_attrs = content.call(Attribute::parse_inner)?;
1705 let mut items = Vec::new();
1706 while !content.is_empty() {
1707 items.push(content.parse()?);
1708 }
1709
1710 Ok(ItemForeignMod {
1711 attrs: private::attrs(outer_attrs, inner_attrs),
1712 abi,
1713 brace_token,
1714 items,
1715 })
1716 }
1717 }
1718
5869c6ff 1719 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
1720 impl Parse for ForeignItem {
1721 fn parse(input: ParseStream) -> Result<Self> {
f035d41b 1722 let begin = input.fork();
e74abb32
XL
1723 let mut attrs = input.call(Attribute::parse_outer)?;
1724 let ahead = input.fork();
1725 let vis: Visibility = ahead.parse()?;
1726
1727 let lookahead = ahead.lookahead1();
f035d41b
XL
1728 let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead) {
1729 let vis: Visibility = input.parse()?;
29967ef6 1730 let sig: Signature = input.parse()?;
f035d41b
XL
1731 if input.peek(token::Brace) {
1732 let content;
1733 braced!(content in input);
1734 content.call(Attribute::parse_inner)?;
1735 content.call(Block::parse_within)?;
1736
1737 Ok(ForeignItem::Verbatim(verbatim::between(begin, input)))
1738 } else {
1739 Ok(ForeignItem::Fn(ForeignItemFn {
1740 attrs: Vec::new(),
1741 vis,
1742 sig,
1743 semi_token: input.parse()?,
1744 }))
1745 }
e74abb32 1746 } else if lookahead.peek(Token![static]) {
f035d41b
XL
1747 let vis = input.parse()?;
1748 let static_token = input.parse()?;
1749 let mutability = input.parse()?;
1750 let ident = input.parse()?;
1751 let colon_token = input.parse()?;
1752 let ty = input.parse()?;
1753 if input.peek(Token![=]) {
1754 input.parse::<Token![=]>()?;
1755 input.parse::<Expr>()?;
1756 input.parse::<Token![;]>()?;
1757 Ok(ForeignItem::Verbatim(verbatim::between(begin, input)))
1758 } else {
1759 Ok(ForeignItem::Static(ForeignItemStatic {
1760 attrs: Vec::new(),
1761 vis,
1762 static_token,
1763 mutability,
1764 ident,
1765 colon_token,
1766 ty,
1767 semi_token: input.parse()?,
1768 }))
1769 }
e74abb32 1770 } else if lookahead.peek(Token![type]) {
f035d41b 1771 parse_foreign_item_type(begin, input)
e74abb32
XL
1772 } else if vis.is_inherited()
1773 && (lookahead.peek(Ident)
1774 || lookahead.peek(Token![self])
1775 || lookahead.peek(Token![super])
e74abb32
XL
1776 || lookahead.peek(Token![crate])
1777 || lookahead.peek(Token![::]))
1778 {
1779 input.parse().map(ForeignItem::Macro)
1780 } else {
1781 Err(lookahead.error())
1782 }?;
1783
f035d41b
XL
1784 let item_attrs = match &mut item {
1785 ForeignItem::Fn(item) => &mut item.attrs,
1786 ForeignItem::Static(item) => &mut item.attrs,
1787 ForeignItem::Type(item) => &mut item.attrs,
1788 ForeignItem::Macro(item) => &mut item.attrs,
1789 ForeignItem::Verbatim(_) => return Ok(item),
5869c6ff 1790 ForeignItem::__TestExhaustive(_) => unreachable!(),
f035d41b
XL
1791 };
1792 attrs.extend(item_attrs.drain(..));
1793 *item_attrs = attrs;
e74abb32
XL
1794
1795 Ok(item)
1796 }
1797 }
1798
5869c6ff 1799 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
1800 impl Parse for ForeignItemFn {
1801 fn parse(input: ParseStream) -> Result<Self> {
1802 let attrs = input.call(Attribute::parse_outer)?;
1803 let vis: Visibility = input.parse()?;
29967ef6 1804 let sig: Signature = input.parse()?;
e74abb32 1805 let semi_token: Token![;] = input.parse()?;
e74abb32
XL
1806 Ok(ForeignItemFn {
1807 attrs,
1808 vis,
f035d41b 1809 sig,
e74abb32
XL
1810 semi_token,
1811 })
1812 }
1813 }
1814
5869c6ff 1815 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
1816 impl Parse for ForeignItemStatic {
1817 fn parse(input: ParseStream) -> Result<Self> {
1818 Ok(ForeignItemStatic {
1819 attrs: input.call(Attribute::parse_outer)?,
1820 vis: input.parse()?,
1821 static_token: input.parse()?,
1822 mutability: input.parse()?,
1823 ident: input.parse()?,
1824 colon_token: input.parse()?,
1825 ty: input.parse()?,
1826 semi_token: input.parse()?,
1827 })
1828 }
1829 }
1830
5869c6ff 1831 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
1832 impl Parse for ForeignItemType {
1833 fn parse(input: ParseStream) -> Result<Self> {
1834 Ok(ForeignItemType {
1835 attrs: input.call(Attribute::parse_outer)?,
1836 vis: input.parse()?,
1837 type_token: input.parse()?,
1838 ident: input.parse()?,
1839 semi_token: input.parse()?,
1840 })
1841 }
1842 }
1843
f035d41b
XL
1844 fn parse_foreign_item_type(begin: ParseBuffer, input: ParseStream) -> Result<ForeignItem> {
1845 let FlexibleItemType {
1846 vis,
1847 defaultness,
1848 type_token,
1849 ident,
1850 generics,
1851 colon_token,
1852 bounds: _,
1853 ty,
1854 semi_token,
1855 } = input.parse()?;
1856
1857 if defaultness.is_some()
1858 || generics.lt_token.is_some()
1859 || generics.where_clause.is_some()
1860 || colon_token.is_some()
1861 || ty.is_some()
1862 {
1863 Ok(ForeignItem::Verbatim(verbatim::between(begin, input)))
1864 } else {
1865 Ok(ForeignItem::Type(ForeignItemType {
1866 attrs: Vec::new(),
1867 vis,
1868 type_token,
1869 ident,
1870 semi_token,
1871 }))
1872 }
1873 }
1874
5869c6ff 1875 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
1876 impl Parse for ForeignItemMacro {
1877 fn parse(input: ParseStream) -> Result<Self> {
1878 let attrs = input.call(Attribute::parse_outer)?;
1879 let mac: Macro = input.parse()?;
1880 let semi_token: Option<Token![;]> = if mac.delimiter.is_brace() {
1881 None
1882 } else {
1883 Some(input.parse()?)
1884 };
1885 Ok(ForeignItemMacro {
1886 attrs,
1887 mac,
1888 semi_token,
1889 })
1890 }
1891 }
1892
5869c6ff 1893 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
1894 impl Parse for ItemType {
1895 fn parse(input: ParseStream) -> Result<Self> {
1896 Ok(ItemType {
1897 attrs: input.call(Attribute::parse_outer)?,
1898 vis: input.parse()?,
1899 type_token: input.parse()?,
1900 ident: input.parse()?,
1901 generics: {
1902 let mut generics: Generics = input.parse()?;
1903 generics.where_clause = input.parse()?;
1904 generics
1905 },
1906 eq_token: input.parse()?,
1907 ty: input.parse()?,
1908 semi_token: input.parse()?,
1909 })
1910 }
1911 }
1912
f035d41b
XL
1913 fn parse_item_type(begin: ParseBuffer, input: ParseStream) -> Result<Item> {
1914 let FlexibleItemType {
1915 vis,
1916 defaultness,
1917 type_token,
1918 ident,
1919 generics,
1920 colon_token,
1921 bounds: _,
1922 ty,
1923 semi_token,
1924 } = input.parse()?;
1925
1926 if defaultness.is_some() || colon_token.is_some() || ty.is_none() {
1927 Ok(Item::Verbatim(verbatim::between(begin, input)))
1928 } else {
1929 let (eq_token, ty) = ty.unwrap();
1930 Ok(Item::Type(ItemType {
1931 attrs: Vec::new(),
1932 vis,
1933 type_token,
1934 ident,
1935 generics,
1936 eq_token,
1937 ty: Box::new(ty),
1938 semi_token,
1939 }))
1940 }
1941 }
1942
e74abb32
XL
1943 #[cfg(not(feature = "printing"))]
1944 fn item_existential(input: ParseStream) -> Result<TokenStream> {
1945 Err(input.error("existential type is not supported"))
1946 }
1947
1948 #[cfg(feature = "printing")]
1949 fn item_existential(input: ParseStream) -> Result<TokenStream> {
1950 use crate::attr::FilterAttrs;
1951 use quote::{ToTokens, TokenStreamExt};
1952
1953 let attrs = input.call(Attribute::parse_outer)?;
1954 let vis: Visibility = input.parse()?;
1955 let existential_token: existential = input.parse()?;
1956 let type_token: Token![type] = input.parse()?;
1957 let ident: Ident = input.parse()?;
1958
1959 let mut generics: Generics = input.parse()?;
1960 generics.where_clause = input.parse()?;
1961
1962 let colon_token: Token![:] = input.parse()?;
1963
1964 let mut bounds = Punctuated::new();
1965 while !input.peek(Token![;]) {
1966 if !bounds.is_empty() {
1967 bounds.push_punct(input.parse::<Token![+]>()?);
1968 }
1969 bounds.push_value(input.parse::<TypeParamBound>()?);
1970 }
1971
1972 let semi_token: Token![;] = input.parse()?;
1973
1974 let mut tokens = TokenStream::new();
1975 tokens.append_all(attrs.outer());
1976 vis.to_tokens(&mut tokens);
1977 existential_token.to_tokens(&mut tokens);
1978 type_token.to_tokens(&mut tokens);
1979 ident.to_tokens(&mut tokens);
1980 generics.to_tokens(&mut tokens);
1981 generics.where_clause.to_tokens(&mut tokens);
1982 if !bounds.is_empty() {
1983 colon_token.to_tokens(&mut tokens);
1984 bounds.to_tokens(&mut tokens);
1985 }
1986 semi_token.to_tokens(&mut tokens);
1987 Ok(tokens)
1988 }
1989
5869c6ff 1990 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
1991 impl Parse for ItemStruct {
1992 fn parse(input: ParseStream) -> Result<Self> {
1993 let attrs = input.call(Attribute::parse_outer)?;
1994 let vis = input.parse::<Visibility>()?;
1995 let struct_token = input.parse::<Token![struct]>()?;
1996 let ident = input.parse::<Ident>()?;
1997 let generics = input.parse::<Generics>()?;
1998 let (where_clause, fields, semi_token) = derive::parsing::data_struct(input)?;
1999 Ok(ItemStruct {
2000 attrs,
2001 vis,
2002 struct_token,
2003 ident,
2004 generics: Generics {
2005 where_clause,
2006 ..generics
2007 },
2008 fields,
2009 semi_token,
2010 })
2011 }
2012 }
2013
5869c6ff 2014 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
2015 impl Parse for ItemEnum {
2016 fn parse(input: ParseStream) -> Result<Self> {
2017 let attrs = input.call(Attribute::parse_outer)?;
2018 let vis = input.parse::<Visibility>()?;
2019 let enum_token = input.parse::<Token![enum]>()?;
2020 let ident = input.parse::<Ident>()?;
2021 let generics = input.parse::<Generics>()?;
2022 let (where_clause, brace_token, variants) = derive::parsing::data_enum(input)?;
2023 Ok(ItemEnum {
2024 attrs,
2025 vis,
2026 enum_token,
2027 ident,
2028 generics: Generics {
2029 where_clause,
2030 ..generics
2031 },
2032 brace_token,
2033 variants,
2034 })
2035 }
2036 }
2037
5869c6ff 2038 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
2039 impl Parse for ItemUnion {
2040 fn parse(input: ParseStream) -> Result<Self> {
2041 let attrs = input.call(Attribute::parse_outer)?;
2042 let vis = input.parse::<Visibility>()?;
2043 let union_token = input.parse::<Token![union]>()?;
2044 let ident = input.parse::<Ident>()?;
2045 let generics = input.parse::<Generics>()?;
2046 let (where_clause, fields) = derive::parsing::data_union(input)?;
2047 Ok(ItemUnion {
2048 attrs,
2049 vis,
2050 union_token,
2051 ident,
2052 generics: Generics {
2053 where_clause,
2054 ..generics
2055 },
2056 fields,
2057 })
2058 }
2059 }
2060
2061 fn parse_trait_or_trait_alias(input: ParseStream) -> Result<Item> {
2062 let (attrs, vis, trait_token, ident, generics) = parse_start_of_trait_alias(input)?;
2063 let lookahead = input.lookahead1();
2064 if lookahead.peek(token::Brace)
2065 || lookahead.peek(Token![:])
2066 || lookahead.peek(Token![where])
2067 {
2068 let unsafety = None;
2069 let auto_token = None;
2070 parse_rest_of_trait(
2071 input,
2072 attrs,
2073 vis,
2074 unsafety,
2075 auto_token,
2076 trait_token,
2077 ident,
2078 generics,
2079 )
2080 .map(Item::Trait)
2081 } else if lookahead.peek(Token![=]) {
2082 parse_rest_of_trait_alias(input, attrs, vis, trait_token, ident, generics)
2083 .map(Item::TraitAlias)
2084 } else {
2085 Err(lookahead.error())
2086 }
2087 }
2088
5869c6ff 2089 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
2090 impl Parse for ItemTrait {
2091 fn parse(input: ParseStream) -> Result<Self> {
f035d41b 2092 let outer_attrs = input.call(Attribute::parse_outer)?;
e74abb32
XL
2093 let vis: Visibility = input.parse()?;
2094 let unsafety: Option<Token![unsafe]> = input.parse()?;
2095 let auto_token: Option<Token![auto]> = input.parse()?;
2096 let trait_token: Token![trait] = input.parse()?;
2097 let ident: Ident = input.parse()?;
2098 let generics: Generics = input.parse()?;
2099 parse_rest_of_trait(
2100 input,
f035d41b 2101 outer_attrs,
e74abb32
XL
2102 vis,
2103 unsafety,
2104 auto_token,
2105 trait_token,
2106 ident,
2107 generics,
2108 )
2109 }
2110 }
2111
2112 fn parse_rest_of_trait(
2113 input: ParseStream,
f035d41b 2114 outer_attrs: Vec<Attribute>,
e74abb32
XL
2115 vis: Visibility,
2116 unsafety: Option<Token![unsafe]>,
2117 auto_token: Option<Token![auto]>,
2118 trait_token: Token![trait],
2119 ident: Ident,
2120 mut generics: Generics,
2121 ) -> Result<ItemTrait> {
2122 let colon_token: Option<Token![:]> = input.parse()?;
2123
2124 let mut supertraits = Punctuated::new();
2125 if colon_token.is_some() {
2126 loop {
e74abb32
XL
2127 if input.peek(Token![where]) || input.peek(token::Brace) {
2128 break;
2129 }
5869c6ff 2130 supertraits.push_value(input.parse()?);
e74abb32
XL
2131 if input.peek(Token![where]) || input.peek(token::Brace) {
2132 break;
2133 }
5869c6ff 2134 supertraits.push_punct(input.parse()?);
e74abb32
XL
2135 }
2136 }
2137
2138 generics.where_clause = input.parse()?;
2139
2140 let content;
2141 let brace_token = braced!(content in input);
f035d41b 2142 let inner_attrs = content.call(Attribute::parse_inner)?;
e74abb32
XL
2143 let mut items = Vec::new();
2144 while !content.is_empty() {
2145 items.push(content.parse()?);
2146 }
2147
2148 Ok(ItemTrait {
f035d41b 2149 attrs: private::attrs(outer_attrs, inner_attrs),
e74abb32
XL
2150 vis,
2151 unsafety,
2152 auto_token,
2153 trait_token,
2154 ident,
2155 generics,
2156 colon_token,
2157 supertraits,
2158 brace_token,
2159 items,
2160 })
2161 }
2162
5869c6ff 2163 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
2164 impl Parse for ItemTraitAlias {
2165 fn parse(input: ParseStream) -> Result<Self> {
2166 let (attrs, vis, trait_token, ident, generics) = parse_start_of_trait_alias(input)?;
2167 parse_rest_of_trait_alias(input, attrs, vis, trait_token, ident, generics)
2168 }
2169 }
2170
2171 fn parse_start_of_trait_alias(
2172 input: ParseStream,
2173 ) -> Result<(Vec<Attribute>, Visibility, Token![trait], Ident, Generics)> {
2174 let attrs = input.call(Attribute::parse_outer)?;
2175 let vis: Visibility = input.parse()?;
2176 let trait_token: Token![trait] = input.parse()?;
2177 let ident: Ident = input.parse()?;
2178 let generics: Generics = input.parse()?;
2179 Ok((attrs, vis, trait_token, ident, generics))
2180 }
2181
2182 fn parse_rest_of_trait_alias(
2183 input: ParseStream,
2184 attrs: Vec<Attribute>,
2185 vis: Visibility,
2186 trait_token: Token![trait],
2187 ident: Ident,
2188 mut generics: Generics,
2189 ) -> Result<ItemTraitAlias> {
2190 let eq_token: Token![=] = input.parse()?;
2191
2192 let mut bounds = Punctuated::new();
2193 loop {
2194 if input.peek(Token![where]) || input.peek(Token![;]) {
2195 break;
2196 }
2197 bounds.push_value(input.parse()?);
2198 if input.peek(Token![where]) || input.peek(Token![;]) {
2199 break;
2200 }
2201 bounds.push_punct(input.parse()?);
2202 }
2203
2204 generics.where_clause = input.parse()?;
2205 let semi_token: Token![;] = input.parse()?;
2206
2207 Ok(ItemTraitAlias {
2208 attrs,
2209 vis,
2210 trait_token,
2211 ident,
2212 generics,
2213 eq_token,
2214 bounds,
2215 semi_token,
2216 })
2217 }
2218
5869c6ff 2219 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
2220 impl Parse for TraitItem {
2221 fn parse(input: ParseStream) -> Result<Self> {
f035d41b 2222 let begin = input.fork();
e74abb32 2223 let mut attrs = input.call(Attribute::parse_outer)?;
f035d41b
XL
2224 let vis: Visibility = input.parse()?;
2225 let defaultness: Option<Token![default]> = input.parse()?;
e74abb32
XL
2226 let ahead = input.fork();
2227
2228 let lookahead = ahead.lookahead1();
f035d41b
XL
2229 let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead) {
2230 input.parse().map(TraitItem::Method)
2231 } else if lookahead.peek(Token![const]) {
e74abb32
XL
2232 ahead.parse::<Token![const]>()?;
2233 let lookahead = ahead.lookahead1();
f035d41b 2234 if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
e74abb32
XL
2235 input.parse().map(TraitItem::Const)
2236 } else if lookahead.peek(Token![async])
2237 || lookahead.peek(Token![unsafe])
2238 || lookahead.peek(Token![extern])
2239 || lookahead.peek(Token![fn])
2240 {
2241 input.parse().map(TraitItem::Method)
2242 } else {
2243 Err(lookahead.error())
2244 }
e74abb32 2245 } else if lookahead.peek(Token![type]) {
f035d41b 2246 parse_trait_item_type(begin.fork(), input)
e74abb32
XL
2247 } else if lookahead.peek(Ident)
2248 || lookahead.peek(Token![self])
2249 || lookahead.peek(Token![super])
e74abb32
XL
2250 || lookahead.peek(Token![crate])
2251 || lookahead.peek(Token![::])
2252 {
2253 input.parse().map(TraitItem::Macro)
2254 } else {
2255 Err(lookahead.error())
2256 }?;
2257
f035d41b
XL
2258 match (vis, defaultness) {
2259 (Visibility::Inherited, None) => {}
2260 _ => return Ok(TraitItem::Verbatim(verbatim::between(begin, input))),
e74abb32
XL
2261 }
2262
f035d41b
XL
2263 let item_attrs = match &mut item {
2264 TraitItem::Const(item) => &mut item.attrs,
2265 TraitItem::Method(item) => &mut item.attrs,
2266 TraitItem::Type(item) => &mut item.attrs,
2267 TraitItem::Macro(item) => &mut item.attrs,
5869c6ff 2268 TraitItem::Verbatim(_) | TraitItem::__TestExhaustive(_) => unreachable!(),
f035d41b
XL
2269 };
2270 attrs.extend(item_attrs.drain(..));
2271 *item_attrs = attrs;
e74abb32
XL
2272 Ok(item)
2273 }
2274 }
2275
5869c6ff 2276 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
2277 impl Parse for TraitItemConst {
2278 fn parse(input: ParseStream) -> Result<Self> {
2279 Ok(TraitItemConst {
2280 attrs: input.call(Attribute::parse_outer)?,
2281 const_token: input.parse()?,
f035d41b
XL
2282 ident: {
2283 let lookahead = input.lookahead1();
2284 if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
2285 input.call(Ident::parse_any)?
2286 } else {
2287 return Err(lookahead.error());
2288 }
2289 },
e74abb32
XL
2290 colon_token: input.parse()?,
2291 ty: input.parse()?,
2292 default: {
2293 if input.peek(Token![=]) {
2294 let eq_token: Token![=] = input.parse()?;
2295 let default: Expr = input.parse()?;
2296 Some((eq_token, default))
2297 } else {
2298 None
2299 }
2300 },
2301 semi_token: input.parse()?,
2302 })
2303 }
2304 }
2305
5869c6ff 2306 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
2307 impl Parse for TraitItemMethod {
2308 fn parse(input: ParseStream) -> Result<Self> {
2309 let outer_attrs = input.call(Attribute::parse_outer)?;
29967ef6 2310 let sig: Signature = input.parse()?;
e74abb32
XL
2311
2312 let lookahead = input.lookahead1();
2313 let (brace_token, inner_attrs, stmts, semi_token) = if lookahead.peek(token::Brace) {
2314 let content;
2315 let brace_token = braced!(content in input);
2316 let inner_attrs = content.call(Attribute::parse_inner)?;
2317 let stmts = content.call(Block::parse_within)?;
2318 (Some(brace_token), inner_attrs, stmts, None)
2319 } else if lookahead.peek(Token![;]) {
2320 let semi_token: Token![;] = input.parse()?;
2321 (None, Vec::new(), Vec::new(), Some(semi_token))
2322 } else {
2323 return Err(lookahead.error());
2324 };
2325
2326 Ok(TraitItemMethod {
2327 attrs: private::attrs(outer_attrs, inner_attrs),
f035d41b 2328 sig,
e74abb32
XL
2329 default: brace_token.map(|brace_token| Block { brace_token, stmts }),
2330 semi_token,
2331 })
2332 }
2333 }
2334
5869c6ff 2335 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
2336 impl Parse for TraitItemType {
2337 fn parse(input: ParseStream) -> Result<Self> {
2338 let attrs = input.call(Attribute::parse_outer)?;
2339 let type_token: Token![type] = input.parse()?;
2340 let ident: Ident = input.parse()?;
2341 let mut generics: Generics = input.parse()?;
2342 let colon_token: Option<Token![:]> = input.parse()?;
2343
2344 let mut bounds = Punctuated::new();
2345 if colon_token.is_some() {
2346 while !input.peek(Token![where]) && !input.peek(Token![=]) && !input.peek(Token![;])
2347 {
2348 if !bounds.is_empty() {
2349 bounds.push_punct(input.parse()?);
2350 }
2351 bounds.push_value(input.parse()?);
2352 }
2353 }
2354
2355 generics.where_clause = input.parse()?;
2356 let default = if input.peek(Token![=]) {
2357 let eq_token: Token![=] = input.parse()?;
2358 let default: Type = input.parse()?;
2359 Some((eq_token, default))
2360 } else {
2361 None
2362 };
2363 let semi_token: Token![;] = input.parse()?;
2364
2365 Ok(TraitItemType {
2366 attrs,
2367 type_token,
2368 ident,
2369 generics,
2370 colon_token,
2371 bounds,
2372 default,
2373 semi_token,
2374 })
2375 }
2376 }
2377
f035d41b
XL
2378 fn parse_trait_item_type(begin: ParseBuffer, input: ParseStream) -> Result<TraitItem> {
2379 let FlexibleItemType {
2380 vis,
2381 defaultness,
2382 type_token,
2383 ident,
2384 generics,
2385 colon_token,
2386 bounds,
2387 ty,
2388 semi_token,
2389 } = input.parse()?;
2390
2391 if defaultness.is_some() || vis.is_some() {
2392 Ok(TraitItem::Verbatim(verbatim::between(begin, input)))
2393 } else {
2394 Ok(TraitItem::Type(TraitItemType {
2395 attrs: Vec::new(),
2396 type_token,
2397 ident,
2398 generics,
2399 colon_token,
2400 bounds,
2401 default: ty,
2402 semi_token,
2403 }))
2404 }
2405 }
2406
5869c6ff 2407 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
2408 impl Parse for TraitItemMacro {
2409 fn parse(input: ParseStream) -> Result<Self> {
2410 let attrs = input.call(Attribute::parse_outer)?;
2411 let mac: Macro = input.parse()?;
2412 let semi_token: Option<Token![;]> = if mac.delimiter.is_brace() {
2413 None
2414 } else {
2415 Some(input.parse()?)
2416 };
2417 Ok(TraitItemMacro {
2418 attrs,
2419 mac,
2420 semi_token,
2421 })
2422 }
2423 }
2424
5869c6ff 2425 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
2426 impl Parse for ItemImpl {
2427 fn parse(input: ParseStream) -> Result<Self> {
f035d41b
XL
2428 let allow_const_impl = false;
2429 parse_impl(input, allow_const_impl).map(Option::unwrap)
2430 }
2431 }
2432
2433 fn parse_impl(input: ParseStream, allow_const_impl: bool) -> Result<Option<ItemImpl>> {
2434 let outer_attrs = input.call(Attribute::parse_outer)?;
2435 let defaultness: Option<Token![default]> = input.parse()?;
2436 let unsafety: Option<Token![unsafe]> = input.parse()?;
2437 let impl_token: Token![impl] = input.parse()?;
2438
2439 let has_generics = input.peek(Token![<])
2440 && (input.peek2(Token![>])
2441 || input.peek2(Token![#])
2442 || (input.peek2(Ident) || input.peek2(Lifetime))
2443 && (input.peek3(Token![:])
2444 || input.peek3(Token![,])
2445 || input.peek3(Token![>]))
2446 || input.peek2(Token![const]));
29967ef6 2447 let mut generics: Generics = if has_generics {
f035d41b
XL
2448 input.parse()?
2449 } else {
2450 Generics::default()
2451 };
e74abb32 2452
f035d41b
XL
2453 let is_const_impl = allow_const_impl
2454 && (input.peek(Token![const]) || input.peek(Token![?]) && input.peek2(Token![const]));
2455 if is_const_impl {
2456 input.parse::<Option<Token![?]>>()?;
2457 input.parse::<Token![const]>()?;
2458 }
e74abb32 2459
5869c6ff
XL
2460 let begin = input.fork();
2461 let polarity = if input.peek(Token![!]) && !input.peek2(token::Brace) {
2462 Some(input.parse::<Token![!]>()?)
2463 } else {
2464 None
2465 };
2466
2467 let mut first_ty: Type = input.parse()?;
2468 let self_ty: Type;
2469 let trait_;
2470
2471 let is_impl_for = input.peek(Token![for]);
2472 if is_impl_for {
2473 let for_token: Token![for] = input.parse()?;
2474 let mut first_ty_ref = &first_ty;
2475 while let Type::Group(ty) = first_ty_ref {
2476 first_ty_ref = &ty.elem;
3dfed10e 2477 }
5869c6ff
XL
2478 if let Type::Path(_) = first_ty_ref {
2479 while let Type::Group(ty) = first_ty {
2480 first_ty = *ty.elem;
2481 }
2482 if let Type::Path(TypePath { qself: None, path }) = first_ty {
2483 trait_ = Some((polarity, path, for_token));
2484 } else {
2485 unreachable!()
2486 }
2487 } else {
2488 trait_ = None;
2489 }
2490 self_ty = input.parse()?;
2491 } else {
2492 trait_ = None;
2493 self_ty = if polarity.is_none() {
2494 first_ty
2495 } else {
2496 Type::Verbatim(verbatim::between(begin, input))
2497 };
2498 }
e74abb32 2499
29967ef6 2500 generics.where_clause = input.parse()?;
f035d41b
XL
2501
2502 let content;
2503 let brace_token = braced!(content in input);
2504 let inner_attrs = content.call(Attribute::parse_inner)?;
2505
2506 let mut items = Vec::new();
2507 while !content.is_empty() {
2508 items.push(content.parse()?);
2509 }
e74abb32 2510
5869c6ff 2511 if is_const_impl || is_impl_for && trait_.is_none() {
f035d41b
XL
2512 Ok(None)
2513 } else {
2514 Ok(Some(ItemImpl {
e74abb32
XL
2515 attrs: private::attrs(outer_attrs, inner_attrs),
2516 defaultness,
2517 unsafety,
2518 impl_token,
29967ef6 2519 generics,
e74abb32
XL
2520 trait_,
2521 self_ty: Box::new(self_ty),
2522 brace_token,
2523 items,
f035d41b 2524 }))
e74abb32
XL
2525 }
2526 }
2527
5869c6ff 2528 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
2529 impl Parse for ImplItem {
2530 fn parse(input: ParseStream) -> Result<Self> {
f035d41b 2531 let begin = input.fork();
e74abb32
XL
2532 let mut attrs = input.call(Attribute::parse_outer)?;
2533 let ahead = input.fork();
2534 let vis: Visibility = ahead.parse()?;
2535
2536 let mut lookahead = ahead.lookahead1();
2537 let defaultness = if lookahead.peek(Token![default]) && !ahead.peek2(Token![!]) {
2538 let defaultness: Token![default] = ahead.parse()?;
2539 lookahead = ahead.lookahead1();
2540 Some(defaultness)
2541 } else {
2542 None
2543 };
2544
f035d41b
XL
2545 let mut item = if lookahead.peek(Token![fn]) || peek_signature(&ahead) {
2546 input.parse().map(ImplItem::Method)
2547 } else if lookahead.peek(Token![const]) {
2548 let const_token: Token![const] = ahead.parse()?;
e74abb32 2549 let lookahead = ahead.lookahead1();
f035d41b
XL
2550 if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
2551 input.advance_to(&ahead);
2552 let ident: Ident = input.call(Ident::parse_any)?;
2553 let colon_token: Token![:] = input.parse()?;
2554 let ty: Type = input.parse()?;
2555 if let Some(eq_token) = input.parse()? {
2556 return Ok(ImplItem::Const(ImplItemConst {
2557 attrs,
2558 vis,
2559 defaultness,
2560 const_token,
2561 ident,
2562 colon_token,
2563 ty,
2564 eq_token,
2565 expr: input.parse()?,
2566 semi_token: input.parse()?,
2567 }));
2568 } else {
2569 input.parse::<Token![;]>()?;
2570 return Ok(ImplItem::Verbatim(verbatim::between(begin, input)));
2571 }
e74abb32
XL
2572 } else {
2573 Err(lookahead.error())
2574 }
e74abb32 2575 } else if lookahead.peek(Token![type]) {
f035d41b 2576 parse_impl_item_type(begin, input)
e74abb32
XL
2577 } else if vis.is_inherited() && defaultness.is_none() && lookahead.peek(existential) {
2578 input.call(item_existential).map(ImplItem::Verbatim)
2579 } else if vis.is_inherited()
2580 && defaultness.is_none()
2581 && (lookahead.peek(Ident)
2582 || lookahead.peek(Token![self])
2583 || lookahead.peek(Token![super])
e74abb32
XL
2584 || lookahead.peek(Token![crate])
2585 || lookahead.peek(Token![::]))
2586 {
2587 input.parse().map(ImplItem::Macro)
2588 } else {
2589 Err(lookahead.error())
2590 }?;
2591
2592 {
2593 let item_attrs = match &mut item {
2594 ImplItem::Const(item) => &mut item.attrs,
2595 ImplItem::Method(item) => &mut item.attrs,
2596 ImplItem::Type(item) => &mut item.attrs,
2597 ImplItem::Macro(item) => &mut item.attrs,
2598 ImplItem::Verbatim(_) => return Ok(item),
5869c6ff 2599 ImplItem::__TestExhaustive(_) => unreachable!(),
e74abb32
XL
2600 };
2601 attrs.extend(item_attrs.drain(..));
2602 *item_attrs = attrs;
2603 }
2604
2605 Ok(item)
2606 }
2607 }
2608
5869c6ff 2609 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
2610 impl Parse for ImplItemConst {
2611 fn parse(input: ParseStream) -> Result<Self> {
2612 Ok(ImplItemConst {
2613 attrs: input.call(Attribute::parse_outer)?,
2614 vis: input.parse()?,
2615 defaultness: input.parse()?,
2616 const_token: input.parse()?,
f035d41b
XL
2617 ident: {
2618 let lookahead = input.lookahead1();
2619 if lookahead.peek(Ident) || lookahead.peek(Token![_]) {
2620 input.call(Ident::parse_any)?
2621 } else {
2622 return Err(lookahead.error());
2623 }
2624 },
e74abb32
XL
2625 colon_token: input.parse()?,
2626 ty: input.parse()?,
2627 eq_token: input.parse()?,
2628 expr: input.parse()?,
2629 semi_token: input.parse()?,
2630 })
2631 }
2632 }
2633
5869c6ff 2634 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
2635 impl Parse for ImplItemMethod {
2636 fn parse(input: ParseStream) -> Result<Self> {
f035d41b 2637 let mut attrs = input.call(Attribute::parse_outer)?;
e74abb32
XL
2638 let vis: Visibility = input.parse()?;
2639 let defaultness: Option<Token![default]> = input.parse()?;
29967ef6 2640 let sig: Signature = input.parse()?;
f035d41b
XL
2641
2642 let block = if let Some(semi) = input.parse::<Option<Token![;]>>()? {
2643 // Accept methods without a body in an impl block because
2644 // rustc's *parser* does not reject them (the compilation error
2645 // is emitted later than parsing) and it can be useful for macro
2646 // DSLs.
2647 let mut punct = Punct::new(';', Spacing::Alone);
2648 punct.set_span(semi.span);
2649 let tokens = TokenStream::from_iter(vec![TokenTree::Punct(punct)]);
2650 Block {
2651 brace_token: Brace::default(),
2652 stmts: vec![Stmt::Item(Item::Verbatim(tokens))],
2653 }
2654 } else {
2655 let content;
2656 let brace_token = braced!(content in input);
2657 attrs.extend(content.call(Attribute::parse_inner)?);
2658 Block {
2659 brace_token,
2660 stmts: content.call(Block::parse_within)?,
2661 }
2662 };
e74abb32
XL
2663
2664 Ok(ImplItemMethod {
f035d41b 2665 attrs,
e74abb32
XL
2666 vis,
2667 defaultness,
f035d41b
XL
2668 sig,
2669 block,
e74abb32
XL
2670 })
2671 }
2672 }
2673
5869c6ff 2674 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
2675 impl Parse for ImplItemType {
2676 fn parse(input: ParseStream) -> Result<Self> {
2677 Ok(ImplItemType {
2678 attrs: input.call(Attribute::parse_outer)?,
2679 vis: input.parse()?,
2680 defaultness: input.parse()?,
2681 type_token: input.parse()?,
2682 ident: input.parse()?,
2683 generics: {
2684 let mut generics: Generics = input.parse()?;
2685 generics.where_clause = input.parse()?;
2686 generics
2687 },
2688 eq_token: input.parse()?,
2689 ty: input.parse()?,
2690 semi_token: input.parse()?,
2691 })
2692 }
2693 }
2694
f035d41b
XL
2695 fn parse_impl_item_type(begin: ParseBuffer, input: ParseStream) -> Result<ImplItem> {
2696 let FlexibleItemType {
2697 vis,
2698 defaultness,
2699 type_token,
2700 ident,
2701 generics,
2702 colon_token,
2703 bounds: _,
2704 ty,
2705 semi_token,
2706 } = input.parse()?;
2707
2708 if colon_token.is_some() || ty.is_none() {
2709 Ok(ImplItem::Verbatim(verbatim::between(begin, input)))
2710 } else {
2711 let (eq_token, ty) = ty.unwrap();
2712 Ok(ImplItem::Type(ImplItemType {
2713 attrs: Vec::new(),
2714 vis,
2715 defaultness,
2716 type_token,
2717 ident,
2718 generics,
2719 eq_token,
2720 ty,
2721 semi_token,
2722 }))
2723 }
2724 }
2725
5869c6ff 2726 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
e74abb32
XL
2727 impl Parse for ImplItemMacro {
2728 fn parse(input: ParseStream) -> Result<Self> {
2729 let attrs = input.call(Attribute::parse_outer)?;
2730 let mac: Macro = input.parse()?;
2731 let semi_token: Option<Token![;]> = if mac.delimiter.is_brace() {
2732 None
2733 } else {
2734 Some(input.parse()?)
2735 };
2736 Ok(ImplItemMacro {
2737 attrs,
2738 mac,
2739 semi_token,
2740 })
2741 }
2742 }
2743
2744 impl Visibility {
2745 fn is_inherited(&self) -> bool {
2746 match *self {
2747 Visibility::Inherited => true,
2748 _ => false,
2749 }
2750 }
2751 }
2752
2753 impl MacroDelimiter {
2754 fn is_brace(&self) -> bool {
2755 match *self {
2756 MacroDelimiter::Brace(_) => true,
2757 MacroDelimiter::Paren(_) | MacroDelimiter::Bracket(_) => false,
2758 }
2759 }
2760 }
2761}
2762
2763#[cfg(feature = "printing")]
2764mod printing {
2765 use super::*;
e74abb32
XL
2766 use crate::attr::FilterAttrs;
2767 use crate::print::TokensOrDefault;
f035d41b 2768 use crate::punctuated::Pair;
29967ef6
XL
2769 use proc_macro2::TokenStream;
2770 use quote::{ToTokens, TokenStreamExt};
e74abb32 2771
5869c6ff 2772 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
2773 impl ToTokens for ItemExternCrate {
2774 fn to_tokens(&self, tokens: &mut TokenStream) {
2775 tokens.append_all(self.attrs.outer());
2776 self.vis.to_tokens(tokens);
2777 self.extern_token.to_tokens(tokens);
2778 self.crate_token.to_tokens(tokens);
2779 self.ident.to_tokens(tokens);
2780 if let Some((as_token, rename)) = &self.rename {
2781 as_token.to_tokens(tokens);
2782 rename.to_tokens(tokens);
2783 }
2784 self.semi_token.to_tokens(tokens);
2785 }
2786 }
2787
5869c6ff 2788 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
2789 impl ToTokens for ItemUse {
2790 fn to_tokens(&self, tokens: &mut TokenStream) {
2791 tokens.append_all(self.attrs.outer());
2792 self.vis.to_tokens(tokens);
2793 self.use_token.to_tokens(tokens);
2794 self.leading_colon.to_tokens(tokens);
2795 self.tree.to_tokens(tokens);
2796 self.semi_token.to_tokens(tokens);
2797 }
2798 }
2799
5869c6ff 2800 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
2801 impl ToTokens for ItemStatic {
2802 fn to_tokens(&self, tokens: &mut TokenStream) {
2803 tokens.append_all(self.attrs.outer());
2804 self.vis.to_tokens(tokens);
2805 self.static_token.to_tokens(tokens);
2806 self.mutability.to_tokens(tokens);
2807 self.ident.to_tokens(tokens);
2808 self.colon_token.to_tokens(tokens);
2809 self.ty.to_tokens(tokens);
2810 self.eq_token.to_tokens(tokens);
2811 self.expr.to_tokens(tokens);
2812 self.semi_token.to_tokens(tokens);
2813 }
2814 }
2815
5869c6ff 2816 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
2817 impl ToTokens for ItemConst {
2818 fn to_tokens(&self, tokens: &mut TokenStream) {
2819 tokens.append_all(self.attrs.outer());
2820 self.vis.to_tokens(tokens);
2821 self.const_token.to_tokens(tokens);
2822 self.ident.to_tokens(tokens);
2823 self.colon_token.to_tokens(tokens);
2824 self.ty.to_tokens(tokens);
2825 self.eq_token.to_tokens(tokens);
2826 self.expr.to_tokens(tokens);
2827 self.semi_token.to_tokens(tokens);
2828 }
2829 }
2830
5869c6ff 2831 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
2832 impl ToTokens for ItemFn {
2833 fn to_tokens(&self, tokens: &mut TokenStream) {
2834 tokens.append_all(self.attrs.outer());
2835 self.vis.to_tokens(tokens);
2836 self.sig.to_tokens(tokens);
2837 self.block.brace_token.surround(tokens, |tokens| {
2838 tokens.append_all(self.attrs.inner());
2839 tokens.append_all(&self.block.stmts);
2840 });
2841 }
2842 }
2843
5869c6ff 2844 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
2845 impl ToTokens for ItemMod {
2846 fn to_tokens(&self, tokens: &mut TokenStream) {
2847 tokens.append_all(self.attrs.outer());
2848 self.vis.to_tokens(tokens);
2849 self.mod_token.to_tokens(tokens);
2850 self.ident.to_tokens(tokens);
2851 if let Some((brace, items)) = &self.content {
2852 brace.surround(tokens, |tokens| {
2853 tokens.append_all(self.attrs.inner());
2854 tokens.append_all(items);
2855 });
2856 } else {
2857 TokensOrDefault(&self.semi).to_tokens(tokens);
2858 }
2859 }
2860 }
2861
5869c6ff 2862 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
2863 impl ToTokens for ItemForeignMod {
2864 fn to_tokens(&self, tokens: &mut TokenStream) {
2865 tokens.append_all(self.attrs.outer());
2866 self.abi.to_tokens(tokens);
2867 self.brace_token.surround(tokens, |tokens| {
2868 tokens.append_all(self.attrs.inner());
2869 tokens.append_all(&self.items);
2870 });
2871 }
2872 }
2873
5869c6ff 2874 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
2875 impl ToTokens for ItemType {
2876 fn to_tokens(&self, tokens: &mut TokenStream) {
2877 tokens.append_all(self.attrs.outer());
2878 self.vis.to_tokens(tokens);
2879 self.type_token.to_tokens(tokens);
2880 self.ident.to_tokens(tokens);
2881 self.generics.to_tokens(tokens);
2882 self.generics.where_clause.to_tokens(tokens);
2883 self.eq_token.to_tokens(tokens);
2884 self.ty.to_tokens(tokens);
2885 self.semi_token.to_tokens(tokens);
2886 }
2887 }
2888
5869c6ff 2889 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
2890 impl ToTokens for ItemEnum {
2891 fn to_tokens(&self, tokens: &mut TokenStream) {
2892 tokens.append_all(self.attrs.outer());
2893 self.vis.to_tokens(tokens);
2894 self.enum_token.to_tokens(tokens);
2895 self.ident.to_tokens(tokens);
2896 self.generics.to_tokens(tokens);
2897 self.generics.where_clause.to_tokens(tokens);
2898 self.brace_token.surround(tokens, |tokens| {
2899 self.variants.to_tokens(tokens);
2900 });
2901 }
2902 }
2903
5869c6ff 2904 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
2905 impl ToTokens for ItemStruct {
2906 fn to_tokens(&self, tokens: &mut TokenStream) {
2907 tokens.append_all(self.attrs.outer());
2908 self.vis.to_tokens(tokens);
2909 self.struct_token.to_tokens(tokens);
2910 self.ident.to_tokens(tokens);
2911 self.generics.to_tokens(tokens);
2912 match &self.fields {
2913 Fields::Named(fields) => {
2914 self.generics.where_clause.to_tokens(tokens);
2915 fields.to_tokens(tokens);
2916 }
2917 Fields::Unnamed(fields) => {
2918 fields.to_tokens(tokens);
2919 self.generics.where_clause.to_tokens(tokens);
2920 TokensOrDefault(&self.semi_token).to_tokens(tokens);
2921 }
2922 Fields::Unit => {
2923 self.generics.where_clause.to_tokens(tokens);
2924 TokensOrDefault(&self.semi_token).to_tokens(tokens);
2925 }
2926 }
2927 }
2928 }
2929
5869c6ff 2930 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
2931 impl ToTokens for ItemUnion {
2932 fn to_tokens(&self, tokens: &mut TokenStream) {
2933 tokens.append_all(self.attrs.outer());
2934 self.vis.to_tokens(tokens);
2935 self.union_token.to_tokens(tokens);
2936 self.ident.to_tokens(tokens);
2937 self.generics.to_tokens(tokens);
2938 self.generics.where_clause.to_tokens(tokens);
2939 self.fields.to_tokens(tokens);
2940 }
2941 }
2942
5869c6ff 2943 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
2944 impl ToTokens for ItemTrait {
2945 fn to_tokens(&self, tokens: &mut TokenStream) {
2946 tokens.append_all(self.attrs.outer());
2947 self.vis.to_tokens(tokens);
2948 self.unsafety.to_tokens(tokens);
2949 self.auto_token.to_tokens(tokens);
2950 self.trait_token.to_tokens(tokens);
2951 self.ident.to_tokens(tokens);
2952 self.generics.to_tokens(tokens);
2953 if !self.supertraits.is_empty() {
2954 TokensOrDefault(&self.colon_token).to_tokens(tokens);
2955 self.supertraits.to_tokens(tokens);
2956 }
2957 self.generics.where_clause.to_tokens(tokens);
2958 self.brace_token.surround(tokens, |tokens| {
5869c6ff 2959 tokens.append_all(self.attrs.inner());
e74abb32
XL
2960 tokens.append_all(&self.items);
2961 });
2962 }
2963 }
2964
5869c6ff 2965 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
2966 impl ToTokens for ItemTraitAlias {
2967 fn to_tokens(&self, tokens: &mut TokenStream) {
2968 tokens.append_all(self.attrs.outer());
2969 self.vis.to_tokens(tokens);
2970 self.trait_token.to_tokens(tokens);
2971 self.ident.to_tokens(tokens);
2972 self.generics.to_tokens(tokens);
2973 self.eq_token.to_tokens(tokens);
2974 self.bounds.to_tokens(tokens);
2975 self.generics.where_clause.to_tokens(tokens);
2976 self.semi_token.to_tokens(tokens);
2977 }
2978 }
2979
5869c6ff 2980 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
2981 impl ToTokens for ItemImpl {
2982 fn to_tokens(&self, tokens: &mut TokenStream) {
2983 tokens.append_all(self.attrs.outer());
2984 self.defaultness.to_tokens(tokens);
2985 self.unsafety.to_tokens(tokens);
2986 self.impl_token.to_tokens(tokens);
2987 self.generics.to_tokens(tokens);
2988 if let Some((polarity, path, for_token)) = &self.trait_ {
2989 polarity.to_tokens(tokens);
2990 path.to_tokens(tokens);
2991 for_token.to_tokens(tokens);
2992 }
2993 self.self_ty.to_tokens(tokens);
2994 self.generics.where_clause.to_tokens(tokens);
2995 self.brace_token.surround(tokens, |tokens| {
2996 tokens.append_all(self.attrs.inner());
2997 tokens.append_all(&self.items);
2998 });
2999 }
3000 }
3001
5869c6ff 3002 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3003 impl ToTokens for ItemMacro {
3004 fn to_tokens(&self, tokens: &mut TokenStream) {
3005 tokens.append_all(self.attrs.outer());
3006 self.mac.path.to_tokens(tokens);
3007 self.mac.bang_token.to_tokens(tokens);
3008 self.ident.to_tokens(tokens);
3009 match &self.mac.delimiter {
3010 MacroDelimiter::Paren(paren) => {
3011 paren.surround(tokens, |tokens| self.mac.tokens.to_tokens(tokens));
3012 }
3013 MacroDelimiter::Brace(brace) => {
3014 brace.surround(tokens, |tokens| self.mac.tokens.to_tokens(tokens));
3015 }
3016 MacroDelimiter::Bracket(bracket) => {
3017 bracket.surround(tokens, |tokens| self.mac.tokens.to_tokens(tokens));
3018 }
3019 }
3020 self.semi_token.to_tokens(tokens);
3021 }
3022 }
3023
5869c6ff 3024 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3025 impl ToTokens for ItemMacro2 {
3026 fn to_tokens(&self, tokens: &mut TokenStream) {
3027 tokens.append_all(self.attrs.outer());
3028 self.vis.to_tokens(tokens);
3029 self.macro_token.to_tokens(tokens);
3030 self.ident.to_tokens(tokens);
3031 self.rules.to_tokens(tokens);
3032 }
3033 }
3034
5869c6ff 3035 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3036 impl ToTokens for UsePath {
3037 fn to_tokens(&self, tokens: &mut TokenStream) {
3038 self.ident.to_tokens(tokens);
3039 self.colon2_token.to_tokens(tokens);
3040 self.tree.to_tokens(tokens);
3041 }
3042 }
3043
5869c6ff 3044 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3045 impl ToTokens for UseName {
3046 fn to_tokens(&self, tokens: &mut TokenStream) {
3047 self.ident.to_tokens(tokens);
3048 }
3049 }
3050
5869c6ff 3051 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3052 impl ToTokens for UseRename {
3053 fn to_tokens(&self, tokens: &mut TokenStream) {
3054 self.ident.to_tokens(tokens);
3055 self.as_token.to_tokens(tokens);
3056 self.rename.to_tokens(tokens);
3057 }
3058 }
3059
5869c6ff 3060 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3061 impl ToTokens for UseGlob {
3062 fn to_tokens(&self, tokens: &mut TokenStream) {
3063 self.star_token.to_tokens(tokens);
3064 }
3065 }
3066
5869c6ff 3067 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3068 impl ToTokens for UseGroup {
3069 fn to_tokens(&self, tokens: &mut TokenStream) {
3070 self.brace_token.surround(tokens, |tokens| {
3071 self.items.to_tokens(tokens);
3072 });
3073 }
3074 }
3075
5869c6ff 3076 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3077 impl ToTokens for TraitItemConst {
3078 fn to_tokens(&self, tokens: &mut TokenStream) {
3079 tokens.append_all(self.attrs.outer());
3080 self.const_token.to_tokens(tokens);
3081 self.ident.to_tokens(tokens);
3082 self.colon_token.to_tokens(tokens);
3083 self.ty.to_tokens(tokens);
3084 if let Some((eq_token, default)) = &self.default {
3085 eq_token.to_tokens(tokens);
3086 default.to_tokens(tokens);
3087 }
3088 self.semi_token.to_tokens(tokens);
3089 }
3090 }
3091
5869c6ff 3092 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3093 impl ToTokens for TraitItemMethod {
3094 fn to_tokens(&self, tokens: &mut TokenStream) {
3095 tokens.append_all(self.attrs.outer());
3096 self.sig.to_tokens(tokens);
3097 match &self.default {
3098 Some(block) => {
3099 block.brace_token.surround(tokens, |tokens| {
3100 tokens.append_all(self.attrs.inner());
3101 tokens.append_all(&block.stmts);
3102 });
3103 }
3104 None => {
3105 TokensOrDefault(&self.semi_token).to_tokens(tokens);
3106 }
3107 }
3108 }
3109 }
3110
5869c6ff 3111 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3112 impl ToTokens for TraitItemType {
3113 fn to_tokens(&self, tokens: &mut TokenStream) {
3114 tokens.append_all(self.attrs.outer());
3115 self.type_token.to_tokens(tokens);
3116 self.ident.to_tokens(tokens);
3117 self.generics.to_tokens(tokens);
3118 if !self.bounds.is_empty() {
3119 TokensOrDefault(&self.colon_token).to_tokens(tokens);
3120 self.bounds.to_tokens(tokens);
3121 }
3122 self.generics.where_clause.to_tokens(tokens);
3123 if let Some((eq_token, default)) = &self.default {
3124 eq_token.to_tokens(tokens);
3125 default.to_tokens(tokens);
3126 }
3127 self.semi_token.to_tokens(tokens);
3128 }
3129 }
3130
5869c6ff 3131 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3132 impl ToTokens for TraitItemMacro {
3133 fn to_tokens(&self, tokens: &mut TokenStream) {
3134 tokens.append_all(self.attrs.outer());
3135 self.mac.to_tokens(tokens);
3136 self.semi_token.to_tokens(tokens);
3137 }
3138 }
3139
5869c6ff 3140 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3141 impl ToTokens for ImplItemConst {
3142 fn to_tokens(&self, tokens: &mut TokenStream) {
3143 tokens.append_all(self.attrs.outer());
3144 self.vis.to_tokens(tokens);
3145 self.defaultness.to_tokens(tokens);
3146 self.const_token.to_tokens(tokens);
3147 self.ident.to_tokens(tokens);
3148 self.colon_token.to_tokens(tokens);
3149 self.ty.to_tokens(tokens);
3150 self.eq_token.to_tokens(tokens);
3151 self.expr.to_tokens(tokens);
3152 self.semi_token.to_tokens(tokens);
3153 }
3154 }
3155
5869c6ff 3156 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3157 impl ToTokens for ImplItemMethod {
3158 fn to_tokens(&self, tokens: &mut TokenStream) {
3159 tokens.append_all(self.attrs.outer());
3160 self.vis.to_tokens(tokens);
3161 self.defaultness.to_tokens(tokens);
3162 self.sig.to_tokens(tokens);
f035d41b
XL
3163 if self.block.stmts.len() == 1 {
3164 if let Stmt::Item(Item::Verbatim(verbatim)) = &self.block.stmts[0] {
3165 if verbatim.to_string() == ";" {
3166 verbatim.to_tokens(tokens);
3167 return;
3168 }
3169 }
3170 }
e74abb32
XL
3171 self.block.brace_token.surround(tokens, |tokens| {
3172 tokens.append_all(self.attrs.inner());
3173 tokens.append_all(&self.block.stmts);
3174 });
3175 }
3176 }
3177
5869c6ff 3178 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3179 impl ToTokens for ImplItemType {
3180 fn to_tokens(&self, tokens: &mut TokenStream) {
3181 tokens.append_all(self.attrs.outer());
3182 self.vis.to_tokens(tokens);
3183 self.defaultness.to_tokens(tokens);
3184 self.type_token.to_tokens(tokens);
3185 self.ident.to_tokens(tokens);
3186 self.generics.to_tokens(tokens);
3187 self.generics.where_clause.to_tokens(tokens);
3188 self.eq_token.to_tokens(tokens);
3189 self.ty.to_tokens(tokens);
3190 self.semi_token.to_tokens(tokens);
3191 }
3192 }
3193
5869c6ff 3194 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3195 impl ToTokens for ImplItemMacro {
3196 fn to_tokens(&self, tokens: &mut TokenStream) {
3197 tokens.append_all(self.attrs.outer());
3198 self.mac.to_tokens(tokens);
3199 self.semi_token.to_tokens(tokens);
3200 }
3201 }
3202
5869c6ff 3203 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3204 impl ToTokens for ForeignItemFn {
3205 fn to_tokens(&self, tokens: &mut TokenStream) {
3206 tokens.append_all(self.attrs.outer());
3207 self.vis.to_tokens(tokens);
3208 self.sig.to_tokens(tokens);
3209 self.semi_token.to_tokens(tokens);
3210 }
3211 }
3212
5869c6ff 3213 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3214 impl ToTokens for ForeignItemStatic {
3215 fn to_tokens(&self, tokens: &mut TokenStream) {
3216 tokens.append_all(self.attrs.outer());
3217 self.vis.to_tokens(tokens);
3218 self.static_token.to_tokens(tokens);
3219 self.mutability.to_tokens(tokens);
3220 self.ident.to_tokens(tokens);
3221 self.colon_token.to_tokens(tokens);
3222 self.ty.to_tokens(tokens);
3223 self.semi_token.to_tokens(tokens);
3224 }
3225 }
3226
5869c6ff 3227 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3228 impl ToTokens for ForeignItemType {
3229 fn to_tokens(&self, tokens: &mut TokenStream) {
3230 tokens.append_all(self.attrs.outer());
3231 self.vis.to_tokens(tokens);
3232 self.type_token.to_tokens(tokens);
3233 self.ident.to_tokens(tokens);
3234 self.semi_token.to_tokens(tokens);
3235 }
3236 }
3237
5869c6ff 3238 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3239 impl ToTokens for ForeignItemMacro {
3240 fn to_tokens(&self, tokens: &mut TokenStream) {
3241 tokens.append_all(self.attrs.outer());
3242 self.mac.to_tokens(tokens);
3243 self.semi_token.to_tokens(tokens);
3244 }
3245 }
3246
f035d41b
XL
3247 fn maybe_variadic_to_tokens(arg: &FnArg, tokens: &mut TokenStream) -> bool {
3248 let arg = match arg {
3249 FnArg::Typed(arg) => arg,
3250 FnArg::Receiver(receiver) => {
3251 receiver.to_tokens(tokens);
3252 return false;
3253 }
60c5eb7d
XL
3254 };
3255
f035d41b
XL
3256 match arg.ty.as_ref() {
3257 Type::Verbatim(ty) if ty.to_string() == "..." => {
3258 match arg.pat.as_ref() {
3259 Pat::Verbatim(pat) if pat.to_string() == "..." => {
3260 tokens.append_all(arg.attrs.outer());
3261 pat.to_tokens(tokens);
3262 }
3263 _ => arg.to_tokens(tokens),
3264 }
3265 true
3266 }
3267 _ => {
3268 arg.to_tokens(tokens);
3269 false
3270 }
3271 }
60c5eb7d
XL
3272 }
3273
5869c6ff 3274 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3275 impl ToTokens for Signature {
3276 fn to_tokens(&self, tokens: &mut TokenStream) {
3277 self.constness.to_tokens(tokens);
3278 self.asyncness.to_tokens(tokens);
3279 self.unsafety.to_tokens(tokens);
3280 self.abi.to_tokens(tokens);
3281 self.fn_token.to_tokens(tokens);
3282 self.ident.to_tokens(tokens);
3283 self.generics.to_tokens(tokens);
3284 self.paren_token.surround(tokens, |tokens| {
f035d41b
XL
3285 let mut last_is_variadic = false;
3286 for input in self.inputs.pairs() {
3287 match input {
3288 Pair::Punctuated(input, comma) => {
3289 maybe_variadic_to_tokens(input, tokens);
3290 comma.to_tokens(tokens);
3291 }
3292 Pair::End(input) => {
3293 last_is_variadic = maybe_variadic_to_tokens(input, tokens);
3294 }
3295 }
3296 }
3297 if self.variadic.is_some() && !last_is_variadic {
60c5eb7d
XL
3298 if !self.inputs.empty_or_trailing() {
3299 <Token![,]>::default().to_tokens(tokens);
3300 }
3301 self.variadic.to_tokens(tokens);
e74abb32 3302 }
e74abb32
XL
3303 });
3304 self.output.to_tokens(tokens);
3305 self.generics.where_clause.to_tokens(tokens);
3306 }
3307 }
3308
5869c6ff 3309 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
e74abb32
XL
3310 impl ToTokens for Receiver {
3311 fn to_tokens(&self, tokens: &mut TokenStream) {
3312 tokens.append_all(self.attrs.outer());
3313 if let Some((ampersand, lifetime)) = &self.reference {
3314 ampersand.to_tokens(tokens);
3315 lifetime.to_tokens(tokens);
3316 }
3317 self.mutability.to_tokens(tokens);
3318 self.self_token.to_tokens(tokens);
3319 }
3320 }
3321}