• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use internals::symbol::*;
2 use internals::{ungroup, Ctxt};
3 use proc_macro2::{Spacing, Span, TokenStream, TokenTree};
4 use quote::ToTokens;
5 use std::borrow::Cow;
6 use std::collections::BTreeSet;
7 use std::iter::FromIterator;
8 use syn;
9 use syn::meta::ParseNestedMeta;
10 use syn::parse::ParseStream;
11 use syn::punctuated::Punctuated;
12 use syn::{token, Ident, Lifetime};
13 
14 // This module handles parsing of `#[serde(...)]` attributes. The entrypoints
15 // are `attr::Container::from_ast`, `attr::Variant::from_ast`, and
16 // `attr::Field::from_ast`. Each returns an instance of the corresponding
17 // struct. Note that none of them return a Result. Unrecognized, malformed, or
18 // duplicated attributes result in a span_err but otherwise are ignored. The
19 // user will see errors simultaneously for all bad attributes in the crate
20 // rather than just the first.
21 
22 pub use internals::case::RenameRule;
23 
24 struct Attr<'c, T> {
25     cx: &'c Ctxt,
26     name: Symbol,
27     tokens: TokenStream,
28     value: Option<T>,
29 }
30 
31 impl<'c, T> Attr<'c, T> {
none(cx: &'c Ctxt, name: Symbol) -> Self32     fn none(cx: &'c Ctxt, name: Symbol) -> Self {
33         Attr {
34             cx,
35             name,
36             tokens: TokenStream::new(),
37             value: None,
38         }
39     }
40 
set<A: ToTokens>(&mut self, obj: A, value: T)41     fn set<A: ToTokens>(&mut self, obj: A, value: T) {
42         let tokens = obj.into_token_stream();
43 
44         if self.value.is_some() {
45             let msg = format!("duplicate serde attribute `{}`", self.name);
46             self.cx.error_spanned_by(tokens, msg);
47         } else {
48             self.tokens = tokens;
49             self.value = Some(value);
50         }
51     }
52 
set_opt<A: ToTokens>(&mut self, obj: A, value: Option<T>)53     fn set_opt<A: ToTokens>(&mut self, obj: A, value: Option<T>) {
54         if let Some(value) = value {
55             self.set(obj, value);
56         }
57     }
58 
set_if_none(&mut self, value: T)59     fn set_if_none(&mut self, value: T) {
60         if self.value.is_none() {
61             self.value = Some(value);
62         }
63     }
64 
get(self) -> Option<T>65     fn get(self) -> Option<T> {
66         self.value
67     }
68 
get_with_tokens(self) -> Option<(TokenStream, T)>69     fn get_with_tokens(self) -> Option<(TokenStream, T)> {
70         match self.value {
71             Some(v) => Some((self.tokens, v)),
72             None => None,
73         }
74     }
75 }
76 
77 struct BoolAttr<'c>(Attr<'c, ()>);
78 
79 impl<'c> BoolAttr<'c> {
none(cx: &'c Ctxt, name: Symbol) -> Self80     fn none(cx: &'c Ctxt, name: Symbol) -> Self {
81         BoolAttr(Attr::none(cx, name))
82     }
83 
set_true<A: ToTokens>(&mut self, obj: A)84     fn set_true<A: ToTokens>(&mut self, obj: A) {
85         self.0.set(obj, ());
86     }
87 
get(&self) -> bool88     fn get(&self) -> bool {
89         self.0.value.is_some()
90     }
91 }
92 
93 struct VecAttr<'c, T> {
94     cx: &'c Ctxt,
95     name: Symbol,
96     first_dup_tokens: TokenStream,
97     values: Vec<T>,
98 }
99 
100 impl<'c, T> VecAttr<'c, T> {
none(cx: &'c Ctxt, name: Symbol) -> Self101     fn none(cx: &'c Ctxt, name: Symbol) -> Self {
102         VecAttr {
103             cx,
104             name,
105             first_dup_tokens: TokenStream::new(),
106             values: Vec::new(),
107         }
108     }
109 
insert<A: ToTokens>(&mut self, obj: A, value: T)110     fn insert<A: ToTokens>(&mut self, obj: A, value: T) {
111         if self.values.len() == 1 {
112             self.first_dup_tokens = obj.into_token_stream();
113         }
114         self.values.push(value);
115     }
116 
at_most_one(mut self) -> Option<T>117     fn at_most_one(mut self) -> Option<T> {
118         if self.values.len() > 1 {
119             let dup_token = self.first_dup_tokens;
120             let msg = format!("duplicate serde attribute `{}`", self.name);
121             self.cx.error_spanned_by(dup_token, msg);
122             None
123         } else {
124             self.values.pop()
125         }
126     }
127 
get(self) -> Vec<T>128     fn get(self) -> Vec<T> {
129         self.values
130     }
131 }
132 
133 pub struct Name {
134     serialize: String,
135     serialize_renamed: bool,
136     deserialize: String,
137     deserialize_renamed: bool,
138     deserialize_aliases: Vec<String>,
139 }
140 
unraw(ident: &Ident) -> String141 fn unraw(ident: &Ident) -> String {
142     ident.to_string().trim_start_matches("r#").to_owned()
143 }
144 
145 impl Name {
from_attrs( source_name: String, ser_name: Attr<String>, de_name: Attr<String>, de_aliases: Option<VecAttr<String>>, ) -> Name146     fn from_attrs(
147         source_name: String,
148         ser_name: Attr<String>,
149         de_name: Attr<String>,
150         de_aliases: Option<VecAttr<String>>,
151     ) -> Name {
152         let deserialize_aliases = match de_aliases {
153             Some(de_aliases) => {
154                 let mut alias_list = BTreeSet::new();
155                 for alias_name in de_aliases.get() {
156                     alias_list.insert(alias_name);
157                 }
158                 alias_list.into_iter().collect()
159             }
160             None => Vec::new(),
161         };
162 
163         let ser_name = ser_name.get();
164         let ser_renamed = ser_name.is_some();
165         let de_name = de_name.get();
166         let de_renamed = de_name.is_some();
167         Name {
168             serialize: ser_name.unwrap_or_else(|| source_name.clone()),
169             serialize_renamed: ser_renamed,
170             deserialize: de_name.unwrap_or(source_name),
171             deserialize_renamed: de_renamed,
172             deserialize_aliases,
173         }
174     }
175 
176     /// Return the container name for the container when serializing.
serialize_name(&self) -> String177     pub fn serialize_name(&self) -> String {
178         self.serialize.clone()
179     }
180 
181     /// Return the container name for the container when deserializing.
deserialize_name(&self) -> String182     pub fn deserialize_name(&self) -> String {
183         self.deserialize.clone()
184     }
185 
deserialize_aliases(&self) -> Vec<String>186     fn deserialize_aliases(&self) -> Vec<String> {
187         let mut aliases = self.deserialize_aliases.clone();
188         let main_name = self.deserialize_name();
189         if !aliases.contains(&main_name) {
190             aliases.push(main_name);
191         }
192         aliases
193     }
194 }
195 
196 pub struct RenameAllRules {
197     serialize: RenameRule,
198     deserialize: RenameRule,
199 }
200 
201 /// Represents struct or enum attribute information.
202 pub struct Container {
203     name: Name,
204     transparent: bool,
205     deny_unknown_fields: bool,
206     default: Default,
207     rename_all_rules: RenameAllRules,
208     ser_bound: Option<Vec<syn::WherePredicate>>,
209     de_bound: Option<Vec<syn::WherePredicate>>,
210     tag: TagType,
211     type_from: Option<syn::Type>,
212     type_try_from: Option<syn::Type>,
213     type_into: Option<syn::Type>,
214     remote: Option<syn::Path>,
215     identifier: Identifier,
216     has_flatten: bool,
217     serde_path: Option<syn::Path>,
218     is_packed: bool,
219     /// Error message generated when type can't be deserialized
220     expecting: Option<String>,
221 }
222 
223 /// Styles of representing an enum.
224 pub enum TagType {
225     /// The default.
226     ///
227     /// ```json
228     /// {"variant1": {"key1": "value1", "key2": "value2"}}
229     /// ```
230     External,
231 
232     /// `#[serde(tag = "type")]`
233     ///
234     /// ```json
235     /// {"type": "variant1", "key1": "value1", "key2": "value2"}
236     /// ```
237     Internal { tag: String },
238 
239     /// `#[serde(tag = "t", content = "c")]`
240     ///
241     /// ```json
242     /// {"t": "variant1", "c": {"key1": "value1", "key2": "value2"}}
243     /// ```
244     Adjacent { tag: String, content: String },
245 
246     /// `#[serde(untagged)]`
247     ///
248     /// ```json
249     /// {"key1": "value1", "key2": "value2"}
250     /// ```
251     None,
252 }
253 
254 /// Whether this enum represents the fields of a struct or the variants of an
255 /// enum.
256 #[derive(Copy, Clone)]
257 pub enum Identifier {
258     /// It does not.
259     No,
260 
261     /// This enum represents the fields of a struct. All of the variants must be
262     /// unit variants, except possibly one which is annotated with
263     /// `#[serde(other)]` and is a newtype variant.
264     Field,
265 
266     /// This enum represents the variants of an enum. All of the variants must
267     /// be unit variants.
268     Variant,
269 }
270 
271 impl Identifier {
272     #[cfg(feature = "deserialize_in_place")]
is_some(self) -> bool273     pub fn is_some(self) -> bool {
274         match self {
275             Identifier::No => false,
276             Identifier::Field | Identifier::Variant => true,
277         }
278     }
279 }
280 
281 impl Container {
282     /// Extract out the `#[serde(...)]` attributes from an item.
from_ast(cx: &Ctxt, item: &syn::DeriveInput) -> Self283     pub fn from_ast(cx: &Ctxt, item: &syn::DeriveInput) -> Self {
284         let mut ser_name = Attr::none(cx, RENAME);
285         let mut de_name = Attr::none(cx, RENAME);
286         let mut transparent = BoolAttr::none(cx, TRANSPARENT);
287         let mut deny_unknown_fields = BoolAttr::none(cx, DENY_UNKNOWN_FIELDS);
288         let mut default = Attr::none(cx, DEFAULT);
289         let mut rename_all_ser_rule = Attr::none(cx, RENAME_ALL);
290         let mut rename_all_de_rule = Attr::none(cx, RENAME_ALL);
291         let mut ser_bound = Attr::none(cx, BOUND);
292         let mut de_bound = Attr::none(cx, BOUND);
293         let mut untagged = BoolAttr::none(cx, UNTAGGED);
294         let mut internal_tag = Attr::none(cx, TAG);
295         let mut content = Attr::none(cx, CONTENT);
296         let mut type_from = Attr::none(cx, FROM);
297         let mut type_try_from = Attr::none(cx, TRY_FROM);
298         let mut type_into = Attr::none(cx, INTO);
299         let mut remote = Attr::none(cx, REMOTE);
300         let mut field_identifier = BoolAttr::none(cx, FIELD_IDENTIFIER);
301         let mut variant_identifier = BoolAttr::none(cx, VARIANT_IDENTIFIER);
302         let mut serde_path = Attr::none(cx, CRATE);
303         let mut expecting = Attr::none(cx, EXPECTING);
304 
305         for attr in &item.attrs {
306             if attr.path() != SERDE {
307                 continue;
308             }
309 
310             if let Err(err) = attr.parse_nested_meta(|meta| {
311                 if meta.path == RENAME {
312                     // #[serde(rename = "foo")]
313                     // #[serde(rename(serialize = "foo", deserialize = "bar"))]
314                     let (ser, de) = get_renames(cx, RENAME, &meta)?;
315                     ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value));
316                     de_name.set_opt(&meta.path, de.as_ref().map(syn::LitStr::value));
317                 } else if meta.path == RENAME_ALL {
318                     // #[serde(rename_all = "foo")]
319                     // #[serde(rename_all(serialize = "foo", deserialize = "bar"))]
320                     let one_name = meta.input.peek(Token![=]);
321                     let (ser, de) = get_renames(cx, RENAME_ALL, &meta)?;
322                     if let Some(ser) = ser {
323                         match RenameRule::from_str(&ser.value()) {
324                             Ok(rename_rule) => rename_all_ser_rule.set(&meta.path, rename_rule),
325                             Err(err) => cx.error_spanned_by(ser, err),
326                         }
327                     }
328                     if let Some(de) = de {
329                         match RenameRule::from_str(&de.value()) {
330                             Ok(rename_rule) => rename_all_de_rule.set(&meta.path, rename_rule),
331                             Err(err) => {
332                                 if !one_name {
333                                     cx.error_spanned_by(de, err);
334                                 }
335                             }
336                         }
337                     }
338                 } else if meta.path == TRANSPARENT {
339                     // #[serde(transparent)]
340                     transparent.set_true(meta.path);
341                 } else if meta.path == DENY_UNKNOWN_FIELDS {
342                     // #[serde(deny_unknown_fields)]
343                     deny_unknown_fields.set_true(meta.path);
344                 } else if meta.path == DEFAULT {
345                     if meta.input.peek(Token![=]) {
346                         // #[serde(default = "...")]
347                         if let Some(path) = parse_lit_into_expr_path(cx, DEFAULT, &meta)? {
348                             match &item.data {
349                                 syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields {
350                                     syn::Fields::Named(_) => {
351                                         default.set(&meta.path, Default::Path(path));
352                                     }
353                                     syn::Fields::Unnamed(_) | syn::Fields::Unit => {
354                                         let msg = "#[serde(default = \"...\")] can only be used on structs with named fields";
355                                         cx.error_spanned_by(fields, msg);
356                                     }
357                                 },
358                                 syn::Data::Enum(syn::DataEnum { enum_token, .. }) => {
359                                     let msg = "#[serde(default = \"...\")] can only be used on structs with named fields";
360                                     cx.error_spanned_by(enum_token, msg);
361                                 }
362                                 syn::Data::Union(syn::DataUnion { union_token, .. }) => {
363                                     let msg = "#[serde(default = \"...\")] can only be used on structs with named fields";
364                                     cx.error_spanned_by(union_token, msg);
365                                 }
366                             }
367                         }
368                     } else {
369                         // #[serde(default)]
370                         match &item.data {
371                             syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields {
372                                 syn::Fields::Named(_) => {
373                                     default.set(meta.path, Default::Default);
374                                 }
375                                 syn::Fields::Unnamed(_) | syn::Fields::Unit => {
376                                     let msg = "#[serde(default)] can only be used on structs with named fields";
377                                     cx.error_spanned_by(fields, msg);
378                                 }
379                             },
380                             syn::Data::Enum(syn::DataEnum { enum_token, .. }) => {
381                                 let msg = "#[serde(default)] can only be used on structs with named fields";
382                                 cx.error_spanned_by(enum_token, msg);
383                             }
384                             syn::Data::Union(syn::DataUnion { union_token, .. }) => {
385                                 let msg = "#[serde(default)] can only be used on structs with named fields";
386                                 cx.error_spanned_by(union_token, msg);
387                             }
388                         }
389                     }
390                 } else if meta.path == BOUND {
391                     // #[serde(bound = "T: SomeBound")]
392                     // #[serde(bound(serialize = "...", deserialize = "..."))]
393                     let (ser, de) = get_where_predicates(cx, &meta)?;
394                     ser_bound.set_opt(&meta.path, ser);
395                     de_bound.set_opt(&meta.path, de);
396                 } else if meta.path == UNTAGGED {
397                     // #[serde(untagged)]
398                     match item.data {
399                         syn::Data::Enum(_) => {
400                             untagged.set_true(&meta.path);
401                         }
402                         syn::Data::Struct(syn::DataStruct { struct_token, .. }) => {
403                             let msg = "#[serde(untagged)] can only be used on enums";
404                             cx.error_spanned_by(struct_token, msg);
405                         }
406                         syn::Data::Union(syn::DataUnion { union_token, .. }) => {
407                             let msg = "#[serde(untagged)] can only be used on enums";
408                             cx.error_spanned_by(union_token, msg);
409                         }
410                     }
411                 } else if meta.path == TAG {
412                     // #[serde(tag = "type")]
413                     if let Some(s) = get_lit_str(cx, TAG, &meta)? {
414                         match &item.data {
415                             syn::Data::Enum(_) => {
416                                 internal_tag.set(&meta.path, s.value());
417                             }
418                             syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields {
419                                 syn::Fields::Named(_) => {
420                                     internal_tag.set(&meta.path, s.value());
421                                 }
422                                 syn::Fields::Unnamed(_) | syn::Fields::Unit => {
423                                     let msg = "#[serde(tag = \"...\")] can only be used on enums and structs with named fields";
424                                     cx.error_spanned_by(fields, msg);
425                                 }
426                             },
427                             syn::Data::Union(syn::DataUnion { union_token, .. }) => {
428                                 let msg = "#[serde(tag = \"...\")] can only be used on enums and structs with named fields";
429                                 cx.error_spanned_by(union_token, msg);
430                             }
431                         }
432                     }
433                 } else if meta.path == CONTENT {
434                     // #[serde(content = "c")]
435                     if let Some(s) = get_lit_str(cx, CONTENT, &meta)? {
436                         match &item.data {
437                             syn::Data::Enum(_) => {
438                                 content.set(&meta.path, s.value());
439                             }
440                             syn::Data::Struct(syn::DataStruct { struct_token, .. }) => {
441                                 let msg = "#[serde(content = \"...\")] can only be used on enums";
442                                 cx.error_spanned_by(struct_token, msg);
443                             }
444                             syn::Data::Union(syn::DataUnion { union_token, .. }) => {
445                                 let msg = "#[serde(content = \"...\")] can only be used on enums";
446                                 cx.error_spanned_by(union_token, msg);
447                             }
448                         }
449                     }
450                 } else if meta.path == FROM {
451                     // #[serde(from = "Type")]
452                     if let Some(from_ty) = parse_lit_into_ty(cx, FROM, &meta)? {
453                         type_from.set_opt(&meta.path, Some(from_ty));
454                     }
455                 } else if meta.path == TRY_FROM {
456                     // #[serde(try_from = "Type")]
457                     if let Some(try_from_ty) = parse_lit_into_ty(cx, TRY_FROM, &meta)? {
458                         type_try_from.set_opt(&meta.path, Some(try_from_ty));
459                     }
460                 } else if meta.path == INTO {
461                     // #[serde(into = "Type")]
462                     if let Some(into_ty) = parse_lit_into_ty(cx, INTO, &meta)? {
463                         type_into.set_opt(&meta.path, Some(into_ty));
464                     }
465                 } else if meta.path == REMOTE {
466                     // #[serde(remote = "...")]
467                     if let Some(path) = parse_lit_into_path(cx, REMOTE, &meta)? {
468                         if is_primitive_path(&path, "Self") {
469                             remote.set(&meta.path, item.ident.clone().into());
470                         } else {
471                             remote.set(&meta.path, path);
472                         }
473                     }
474                 } else if meta.path == FIELD_IDENTIFIER {
475                     // #[serde(field_identifier)]
476                     field_identifier.set_true(&meta.path);
477                 } else if meta.path == VARIANT_IDENTIFIER {
478                     // #[serde(variant_identifier)]
479                     variant_identifier.set_true(&meta.path);
480                 } else if meta.path == CRATE {
481                     // #[serde(crate = "foo")]
482                     if let Some(path) = parse_lit_into_path(cx, CRATE, &meta)? {
483                         serde_path.set(&meta.path, path);
484                     }
485                 } else if meta.path == EXPECTING {
486                     // #[serde(expecting = "a message")]
487                     if let Some(s) = get_lit_str(cx, EXPECTING, &meta)? {
488                         expecting.set(&meta.path, s.value());
489                     }
490                 } else {
491                     let path = meta.path.to_token_stream().to_string().replace(' ', "");
492                     return Err(
493                         meta.error(format_args!("unknown serde container attribute `{}`", path))
494                     );
495                 }
496                 Ok(())
497             }) {
498                 cx.syn_error(err);
499             }
500         }
501 
502         let mut is_packed = false;
503         for attr in &item.attrs {
504             if attr.path() == REPR {
505                 let _ = attr.parse_args_with(|input: ParseStream| {
506                     while let Some(token) = input.parse()? {
507                         if let TokenTree::Ident(ident) = token {
508                             is_packed |= ident == "packed";
509                         }
510                     }
511                     Ok(())
512                 });
513             }
514         }
515 
516         Container {
517             name: Name::from_attrs(unraw(&item.ident), ser_name, de_name, None),
518             transparent: transparent.get(),
519             deny_unknown_fields: deny_unknown_fields.get(),
520             default: default.get().unwrap_or(Default::None),
521             rename_all_rules: RenameAllRules {
522                 serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None),
523                 deserialize: rename_all_de_rule.get().unwrap_or(RenameRule::None),
524             },
525             ser_bound: ser_bound.get(),
526             de_bound: de_bound.get(),
527             tag: decide_tag(cx, item, untagged, internal_tag, content),
528             type_from: type_from.get(),
529             type_try_from: type_try_from.get(),
530             type_into: type_into.get(),
531             remote: remote.get(),
532             identifier: decide_identifier(cx, item, field_identifier, variant_identifier),
533             has_flatten: false,
534             serde_path: serde_path.get(),
535             is_packed,
536             expecting: expecting.get(),
537         }
538     }
539 
name(&self) -> &Name540     pub fn name(&self) -> &Name {
541         &self.name
542     }
543 
rename_all_rules(&self) -> &RenameAllRules544     pub fn rename_all_rules(&self) -> &RenameAllRules {
545         &self.rename_all_rules
546     }
547 
transparent(&self) -> bool548     pub fn transparent(&self) -> bool {
549         self.transparent
550     }
551 
deny_unknown_fields(&self) -> bool552     pub fn deny_unknown_fields(&self) -> bool {
553         self.deny_unknown_fields
554     }
555 
default(&self) -> &Default556     pub fn default(&self) -> &Default {
557         &self.default
558     }
559 
ser_bound(&self) -> Option<&[syn::WherePredicate]>560     pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
561         self.ser_bound.as_ref().map(|vec| &vec[..])
562     }
563 
de_bound(&self) -> Option<&[syn::WherePredicate]>564     pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
565         self.de_bound.as_ref().map(|vec| &vec[..])
566     }
567 
tag(&self) -> &TagType568     pub fn tag(&self) -> &TagType {
569         &self.tag
570     }
571 
type_from(&self) -> Option<&syn::Type>572     pub fn type_from(&self) -> Option<&syn::Type> {
573         self.type_from.as_ref()
574     }
575 
type_try_from(&self) -> Option<&syn::Type>576     pub fn type_try_from(&self) -> Option<&syn::Type> {
577         self.type_try_from.as_ref()
578     }
579 
type_into(&self) -> Option<&syn::Type>580     pub fn type_into(&self) -> Option<&syn::Type> {
581         self.type_into.as_ref()
582     }
583 
remote(&self) -> Option<&syn::Path>584     pub fn remote(&self) -> Option<&syn::Path> {
585         self.remote.as_ref()
586     }
587 
is_packed(&self) -> bool588     pub fn is_packed(&self) -> bool {
589         self.is_packed
590     }
591 
identifier(&self) -> Identifier592     pub fn identifier(&self) -> Identifier {
593         self.identifier
594     }
595 
has_flatten(&self) -> bool596     pub fn has_flatten(&self) -> bool {
597         self.has_flatten
598     }
599 
mark_has_flatten(&mut self)600     pub fn mark_has_flatten(&mut self) {
601         self.has_flatten = true;
602     }
603 
custom_serde_path(&self) -> Option<&syn::Path>604     pub fn custom_serde_path(&self) -> Option<&syn::Path> {
605         self.serde_path.as_ref()
606     }
607 
serde_path(&self) -> Cow<syn::Path>608     pub fn serde_path(&self) -> Cow<syn::Path> {
609         self.custom_serde_path()
610             .map_or_else(|| Cow::Owned(parse_quote!(_serde)), Cow::Borrowed)
611     }
612 
613     /// Error message generated when type can't be deserialized.
614     /// If `None`, default message will be used
expecting(&self) -> Option<&str>615     pub fn expecting(&self) -> Option<&str> {
616         self.expecting.as_ref().map(String::as_ref)
617     }
618 }
619 
decide_tag( cx: &Ctxt, item: &syn::DeriveInput, untagged: BoolAttr, internal_tag: Attr<String>, content: Attr<String>, ) -> TagType620 fn decide_tag(
621     cx: &Ctxt,
622     item: &syn::DeriveInput,
623     untagged: BoolAttr,
624     internal_tag: Attr<String>,
625     content: Attr<String>,
626 ) -> TagType {
627     match (
628         untagged.0.get_with_tokens(),
629         internal_tag.get_with_tokens(),
630         content.get_with_tokens(),
631     ) {
632         (None, None, None) => TagType::External,
633         (Some(_), None, None) => TagType::None,
634         (None, Some((_, tag)), None) => {
635             // Check that there are no tuple variants.
636             if let syn::Data::Enum(data) = &item.data {
637                 for variant in &data.variants {
638                     match &variant.fields {
639                         syn::Fields::Named(_) | syn::Fields::Unit => {}
640                         syn::Fields::Unnamed(fields) => {
641                             if fields.unnamed.len() != 1 {
642                                 let msg =
643                                     "#[serde(tag = \"...\")] cannot be used with tuple variants";
644                                 cx.error_spanned_by(variant, msg);
645                                 break;
646                             }
647                         }
648                     }
649                 }
650             }
651             TagType::Internal { tag }
652         }
653         (Some((untagged_tokens, _)), Some((tag_tokens, _)), None) => {
654             let msg = "enum cannot be both untagged and internally tagged";
655             cx.error_spanned_by(untagged_tokens, msg);
656             cx.error_spanned_by(tag_tokens, msg);
657             TagType::External // doesn't matter, will error
658         }
659         (None, None, Some((content_tokens, _))) => {
660             let msg = "#[serde(tag = \"...\", content = \"...\")] must be used together";
661             cx.error_spanned_by(content_tokens, msg);
662             TagType::External
663         }
664         (Some((untagged_tokens, _)), None, Some((content_tokens, _))) => {
665             let msg = "untagged enum cannot have #[serde(content = \"...\")]";
666             cx.error_spanned_by(untagged_tokens, msg);
667             cx.error_spanned_by(content_tokens, msg);
668             TagType::External
669         }
670         (None, Some((_, tag)), Some((_, content))) => TagType::Adjacent { tag, content },
671         (Some((untagged_tokens, _)), Some((tag_tokens, _)), Some((content_tokens, _))) => {
672             let msg = "untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]";
673             cx.error_spanned_by(untagged_tokens, msg);
674             cx.error_spanned_by(tag_tokens, msg);
675             cx.error_spanned_by(content_tokens, msg);
676             TagType::External
677         }
678     }
679 }
680 
decide_identifier( cx: &Ctxt, item: &syn::DeriveInput, field_identifier: BoolAttr, variant_identifier: BoolAttr, ) -> Identifier681 fn decide_identifier(
682     cx: &Ctxt,
683     item: &syn::DeriveInput,
684     field_identifier: BoolAttr,
685     variant_identifier: BoolAttr,
686 ) -> Identifier {
687     match (
688         &item.data,
689         field_identifier.0.get_with_tokens(),
690         variant_identifier.0.get_with_tokens(),
691     ) {
692         (_, None, None) => Identifier::No,
693         (_, Some((field_identifier_tokens, _)), Some((variant_identifier_tokens, _))) => {
694             let msg =
695                 "#[serde(field_identifier)] and #[serde(variant_identifier)] cannot both be set";
696             cx.error_spanned_by(field_identifier_tokens, msg);
697             cx.error_spanned_by(variant_identifier_tokens, msg);
698             Identifier::No
699         }
700         (syn::Data::Enum(_), Some(_), None) => Identifier::Field,
701         (syn::Data::Enum(_), None, Some(_)) => Identifier::Variant,
702         (syn::Data::Struct(syn::DataStruct { struct_token, .. }), Some(_), None) => {
703             let msg = "#[serde(field_identifier)] can only be used on an enum";
704             cx.error_spanned_by(struct_token, msg);
705             Identifier::No
706         }
707         (syn::Data::Union(syn::DataUnion { union_token, .. }), Some(_), None) => {
708             let msg = "#[serde(field_identifier)] can only be used on an enum";
709             cx.error_spanned_by(union_token, msg);
710             Identifier::No
711         }
712         (syn::Data::Struct(syn::DataStruct { struct_token, .. }), None, Some(_)) => {
713             let msg = "#[serde(variant_identifier)] can only be used on an enum";
714             cx.error_spanned_by(struct_token, msg);
715             Identifier::No
716         }
717         (syn::Data::Union(syn::DataUnion { union_token, .. }), None, Some(_)) => {
718             let msg = "#[serde(variant_identifier)] can only be used on an enum";
719             cx.error_spanned_by(union_token, msg);
720             Identifier::No
721         }
722     }
723 }
724 
725 /// Represents variant attribute information
726 pub struct Variant {
727     name: Name,
728     rename_all_rules: RenameAllRules,
729     ser_bound: Option<Vec<syn::WherePredicate>>,
730     de_bound: Option<Vec<syn::WherePredicate>>,
731     skip_deserializing: bool,
732     skip_serializing: bool,
733     other: bool,
734     serialize_with: Option<syn::ExprPath>,
735     deserialize_with: Option<syn::ExprPath>,
736     borrow: Option<BorrowAttribute>,
737 }
738 
739 struct BorrowAttribute {
740     path: syn::Path,
741     lifetimes: Option<BTreeSet<syn::Lifetime>>,
742 }
743 
744 impl Variant {
from_ast(cx: &Ctxt, variant: &syn::Variant) -> Self745     pub fn from_ast(cx: &Ctxt, variant: &syn::Variant) -> Self {
746         let mut ser_name = Attr::none(cx, RENAME);
747         let mut de_name = Attr::none(cx, RENAME);
748         let mut de_aliases = VecAttr::none(cx, RENAME);
749         let mut skip_deserializing = BoolAttr::none(cx, SKIP_DESERIALIZING);
750         let mut skip_serializing = BoolAttr::none(cx, SKIP_SERIALIZING);
751         let mut rename_all_ser_rule = Attr::none(cx, RENAME_ALL);
752         let mut rename_all_de_rule = Attr::none(cx, RENAME_ALL);
753         let mut ser_bound = Attr::none(cx, BOUND);
754         let mut de_bound = Attr::none(cx, BOUND);
755         let mut other = BoolAttr::none(cx, OTHER);
756         let mut serialize_with = Attr::none(cx, SERIALIZE_WITH);
757         let mut deserialize_with = Attr::none(cx, DESERIALIZE_WITH);
758         let mut borrow = Attr::none(cx, BORROW);
759 
760         for attr in &variant.attrs {
761             if attr.path() != SERDE {
762                 continue;
763             }
764 
765             if let Err(err) = attr.parse_nested_meta(|meta| {
766                 if meta.path == RENAME {
767                     // #[serde(rename = "foo")]
768                     // #[serde(rename(serialize = "foo", deserialize = "bar"))]
769                     let (ser, de) = get_multiple_renames(cx, &meta)?;
770                     ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value));
771                     for de_value in de {
772                         de_name.set_if_none(de_value.value());
773                         de_aliases.insert(&meta.path, de_value.value());
774                     }
775                 } else if meta.path == ALIAS {
776                     // #[serde(alias = "foo")]
777                     if let Some(s) = get_lit_str(cx, ALIAS, &meta)? {
778                         de_aliases.insert(&meta.path, s.value());
779                     }
780                 } else if meta.path == RENAME_ALL {
781                     // #[serde(rename_all = "foo")]
782                     // #[serde(rename_all(serialize = "foo", deserialize = "bar"))]
783                     let one_name = meta.input.peek(Token![=]);
784                     let (ser, de) = get_renames(cx, RENAME_ALL, &meta)?;
785                     if let Some(ser) = ser {
786                         match RenameRule::from_str(&ser.value()) {
787                             Ok(rename_rule) => rename_all_ser_rule.set(&meta.path, rename_rule),
788                             Err(err) => cx.error_spanned_by(ser, err),
789                         }
790                     }
791                     if let Some(de) = de {
792                         match RenameRule::from_str(&de.value()) {
793                             Ok(rename_rule) => rename_all_de_rule.set(&meta.path, rename_rule),
794                             Err(err) => {
795                                 if !one_name {
796                                     cx.error_spanned_by(de, err);
797                                 }
798                             }
799                         }
800                     }
801                 } else if meta.path == SKIP {
802                     // #[serde(skip)]
803                     skip_serializing.set_true(&meta.path);
804                     skip_deserializing.set_true(&meta.path);
805                 } else if meta.path == SKIP_DESERIALIZING {
806                     // #[serde(skip_deserializing)]
807                     skip_deserializing.set_true(&meta.path);
808                 } else if meta.path == SKIP_SERIALIZING {
809                     // #[serde(skip_serializing)]
810                     skip_serializing.set_true(&meta.path);
811                 } else if meta.path == OTHER {
812                     // #[serde(other)]
813                     other.set_true(&meta.path);
814                 } else if meta.path == BOUND {
815                     // #[serde(bound = "T: SomeBound")]
816                     // #[serde(bound(serialize = "...", deserialize = "..."))]
817                     let (ser, de) = get_where_predicates(cx, &meta)?;
818                     ser_bound.set_opt(&meta.path, ser);
819                     de_bound.set_opt(&meta.path, de);
820                 } else if meta.path == WITH {
821                     // #[serde(with = "...")]
822                     if let Some(path) = parse_lit_into_expr_path(cx, WITH, &meta)? {
823                         let mut ser_path = path.clone();
824                         ser_path
825                             .path
826                             .segments
827                             .push(Ident::new("serialize", Span::call_site()).into());
828                         serialize_with.set(&meta.path, ser_path);
829                         let mut de_path = path;
830                         de_path
831                             .path
832                             .segments
833                             .push(Ident::new("deserialize", Span::call_site()).into());
834                         deserialize_with.set(&meta.path, de_path);
835                     }
836                 } else if meta.path == SERIALIZE_WITH {
837                     // #[serde(serialize_with = "...")]
838                     if let Some(path) = parse_lit_into_expr_path(cx, SERIALIZE_WITH, &meta)? {
839                         serialize_with.set(&meta.path, path);
840                     }
841                 } else if meta.path == DESERIALIZE_WITH {
842                     // #[serde(deserialize_with = "...")]
843                     if let Some(path) = parse_lit_into_expr_path(cx, DESERIALIZE_WITH, &meta)? {
844                         deserialize_with.set(&meta.path, path);
845                     }
846                 } else if meta.path == BORROW {
847                     let borrow_attribute = if meta.input.peek(Token![=]) {
848                         // #[serde(borrow = "'a + 'b")]
849                         let lifetimes = parse_lit_into_lifetimes(cx, &meta)?;
850                         BorrowAttribute {
851                             path: meta.path.clone(),
852                             lifetimes: Some(lifetimes),
853                         }
854                     } else {
855                         // #[serde(borrow)]
856                         BorrowAttribute {
857                             path: meta.path.clone(),
858                             lifetimes: None,
859                         }
860                     };
861                     match &variant.fields {
862                         syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => {
863                             borrow.set(&meta.path, borrow_attribute);
864                         }
865                         _ => {
866                             let msg = "#[serde(borrow)] may only be used on newtype variants";
867                             cx.error_spanned_by(variant, msg);
868                         }
869                     }
870                 } else {
871                     let path = meta.path.to_token_stream().to_string().replace(' ', "");
872                     return Err(
873                         meta.error(format_args!("unknown serde variant attribute `{}`", path))
874                     );
875                 }
876                 Ok(())
877             }) {
878                 cx.syn_error(err);
879             }
880         }
881 
882         Variant {
883             name: Name::from_attrs(unraw(&variant.ident), ser_name, de_name, Some(de_aliases)),
884             rename_all_rules: RenameAllRules {
885                 serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None),
886                 deserialize: rename_all_de_rule.get().unwrap_or(RenameRule::None),
887             },
888             ser_bound: ser_bound.get(),
889             de_bound: de_bound.get(),
890             skip_deserializing: skip_deserializing.get(),
891             skip_serializing: skip_serializing.get(),
892             other: other.get(),
893             serialize_with: serialize_with.get(),
894             deserialize_with: deserialize_with.get(),
895             borrow: borrow.get(),
896         }
897     }
898 
name(&self) -> &Name899     pub fn name(&self) -> &Name {
900         &self.name
901     }
902 
aliases(&self) -> Vec<String>903     pub fn aliases(&self) -> Vec<String> {
904         self.name.deserialize_aliases()
905     }
906 
rename_by_rules(&mut self, rules: &RenameAllRules)907     pub fn rename_by_rules(&mut self, rules: &RenameAllRules) {
908         if !self.name.serialize_renamed {
909             self.name.serialize = rules.serialize.apply_to_variant(&self.name.serialize);
910         }
911         if !self.name.deserialize_renamed {
912             self.name.deserialize = rules.deserialize.apply_to_variant(&self.name.deserialize);
913         }
914     }
915 
rename_all_rules(&self) -> &RenameAllRules916     pub fn rename_all_rules(&self) -> &RenameAllRules {
917         &self.rename_all_rules
918     }
919 
ser_bound(&self) -> Option<&[syn::WherePredicate]>920     pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
921         self.ser_bound.as_ref().map(|vec| &vec[..])
922     }
923 
de_bound(&self) -> Option<&[syn::WherePredicate]>924     pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
925         self.de_bound.as_ref().map(|vec| &vec[..])
926     }
927 
skip_deserializing(&self) -> bool928     pub fn skip_deserializing(&self) -> bool {
929         self.skip_deserializing
930     }
931 
skip_serializing(&self) -> bool932     pub fn skip_serializing(&self) -> bool {
933         self.skip_serializing
934     }
935 
other(&self) -> bool936     pub fn other(&self) -> bool {
937         self.other
938     }
939 
serialize_with(&self) -> Option<&syn::ExprPath>940     pub fn serialize_with(&self) -> Option<&syn::ExprPath> {
941         self.serialize_with.as_ref()
942     }
943 
deserialize_with(&self) -> Option<&syn::ExprPath>944     pub fn deserialize_with(&self) -> Option<&syn::ExprPath> {
945         self.deserialize_with.as_ref()
946     }
947 }
948 
949 /// Represents field attribute information
950 pub struct Field {
951     name: Name,
952     skip_serializing: bool,
953     skip_deserializing: bool,
954     skip_serializing_if: Option<syn::ExprPath>,
955     default: Default,
956     serialize_with: Option<syn::ExprPath>,
957     deserialize_with: Option<syn::ExprPath>,
958     ser_bound: Option<Vec<syn::WherePredicate>>,
959     de_bound: Option<Vec<syn::WherePredicate>>,
960     borrowed_lifetimes: BTreeSet<syn::Lifetime>,
961     getter: Option<syn::ExprPath>,
962     flatten: bool,
963     transparent: bool,
964 }
965 
966 /// Represents the default to use for a field when deserializing.
967 pub enum Default {
968     /// Field must always be specified because it does not have a default.
969     None,
970     /// The default is given by `std::default::Default::default()`.
971     Default,
972     /// The default is given by this function.
973     Path(syn::ExprPath),
974 }
975 
976 impl Default {
is_none(&self) -> bool977     pub fn is_none(&self) -> bool {
978         match self {
979             Default::None => true,
980             Default::Default | Default::Path(_) => false,
981         }
982     }
983 }
984 
985 impl Field {
986     /// Extract out the `#[serde(...)]` attributes from a struct field.
from_ast( cx: &Ctxt, index: usize, field: &syn::Field, attrs: Option<&Variant>, container_default: &Default, ) -> Self987     pub fn from_ast(
988         cx: &Ctxt,
989         index: usize,
990         field: &syn::Field,
991         attrs: Option<&Variant>,
992         container_default: &Default,
993     ) -> Self {
994         let mut ser_name = Attr::none(cx, RENAME);
995         let mut de_name = Attr::none(cx, RENAME);
996         let mut de_aliases = VecAttr::none(cx, RENAME);
997         let mut skip_serializing = BoolAttr::none(cx, SKIP_SERIALIZING);
998         let mut skip_deserializing = BoolAttr::none(cx, SKIP_DESERIALIZING);
999         let mut skip_serializing_if = Attr::none(cx, SKIP_SERIALIZING_IF);
1000         let mut default = Attr::none(cx, DEFAULT);
1001         let mut serialize_with = Attr::none(cx, SERIALIZE_WITH);
1002         let mut deserialize_with = Attr::none(cx, DESERIALIZE_WITH);
1003         let mut ser_bound = Attr::none(cx, BOUND);
1004         let mut de_bound = Attr::none(cx, BOUND);
1005         let mut borrowed_lifetimes = Attr::none(cx, BORROW);
1006         let mut getter = Attr::none(cx, GETTER);
1007         let mut flatten = BoolAttr::none(cx, FLATTEN);
1008 
1009         let ident = match &field.ident {
1010             Some(ident) => unraw(ident),
1011             None => index.to_string(),
1012         };
1013 
1014         if let Some(borrow_attribute) = attrs.and_then(|variant| variant.borrow.as_ref()) {
1015             if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, field) {
1016                 if let Some(lifetimes) = &borrow_attribute.lifetimes {
1017                     for lifetime in lifetimes {
1018                         if !borrowable.contains(lifetime) {
1019                             let msg =
1020                                 format!("field `{}` does not have lifetime {}", ident, lifetime);
1021                             cx.error_spanned_by(field, msg);
1022                         }
1023                     }
1024                     borrowed_lifetimes.set(&borrow_attribute.path, lifetimes.clone());
1025                 } else {
1026                     borrowed_lifetimes.set(&borrow_attribute.path, borrowable);
1027                 }
1028             }
1029         }
1030 
1031         for attr in &field.attrs {
1032             if attr.path() != SERDE {
1033                 continue;
1034             }
1035 
1036             if let Err(err) = attr.parse_nested_meta(|meta| {
1037                 if meta.path == RENAME {
1038                     // #[serde(rename = "foo")]
1039                     // #[serde(rename(serialize = "foo", deserialize = "bar"))]
1040                     let (ser, de) = get_multiple_renames(cx, &meta)?;
1041                     ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value));
1042                     for de_value in de {
1043                         de_name.set_if_none(de_value.value());
1044                         de_aliases.insert(&meta.path, de_value.value());
1045                     }
1046                 } else if meta.path == ALIAS {
1047                     // #[serde(alias = "foo")]
1048                     if let Some(s) = get_lit_str(cx, ALIAS, &meta)? {
1049                         de_aliases.insert(&meta.path, s.value());
1050                     }
1051                 } else if meta.path == DEFAULT {
1052                     if meta.input.peek(Token![=]) {
1053                         // #[serde(default = "...")]
1054                         if let Some(path) = parse_lit_into_expr_path(cx, DEFAULT, &meta)? {
1055                             default.set(&meta.path, Default::Path(path));
1056                         }
1057                     } else {
1058                         // #[serde(default)]
1059                         default.set(&meta.path, Default::Default);
1060                     }
1061                 } else if meta.path == SKIP_SERIALIZING {
1062                     // #[serde(skip_serializing)]
1063                     skip_serializing.set_true(&meta.path);
1064                 } else if meta.path == SKIP_DESERIALIZING {
1065                     // #[serde(skip_deserializing)]
1066                     skip_deserializing.set_true(&meta.path);
1067                 } else if meta.path == SKIP {
1068                     // #[serde(skip)]
1069                     skip_serializing.set_true(&meta.path);
1070                     skip_deserializing.set_true(&meta.path);
1071                 } else if meta.path == SKIP_SERIALIZING_IF {
1072                     // #[serde(skip_serializing_if = "...")]
1073                     if let Some(path) = parse_lit_into_expr_path(cx, SKIP_SERIALIZING_IF, &meta)? {
1074                         skip_serializing_if.set(&meta.path, path);
1075                     }
1076                 } else if meta.path == SERIALIZE_WITH {
1077                     // #[serde(serialize_with = "...")]
1078                     if let Some(path) = parse_lit_into_expr_path(cx, SERIALIZE_WITH, &meta)? {
1079                         serialize_with.set(&meta.path, path);
1080                     }
1081                 } else if meta.path == DESERIALIZE_WITH {
1082                     // #[serde(deserialize_with = "...")]
1083                     if let Some(path) = parse_lit_into_expr_path(cx, DESERIALIZE_WITH, &meta)? {
1084                         deserialize_with.set(&meta.path, path);
1085                     }
1086                 } else if meta.path == WITH {
1087                     // #[serde(with = "...")]
1088                     if let Some(path) = parse_lit_into_expr_path(cx, WITH, &meta)? {
1089                         let mut ser_path = path.clone();
1090                         ser_path
1091                             .path
1092                             .segments
1093                             .push(Ident::new("serialize", Span::call_site()).into());
1094                         serialize_with.set(&meta.path, ser_path);
1095                         let mut de_path = path;
1096                         de_path
1097                             .path
1098                             .segments
1099                             .push(Ident::new("deserialize", Span::call_site()).into());
1100                         deserialize_with.set(&meta.path, de_path);
1101                     }
1102                 } else if meta.path == BOUND {
1103                     // #[serde(bound = "T: SomeBound")]
1104                     // #[serde(bound(serialize = "...", deserialize = "..."))]
1105                     let (ser, de) = get_where_predicates(cx, &meta)?;
1106                     ser_bound.set_opt(&meta.path, ser);
1107                     de_bound.set_opt(&meta.path, de);
1108                 } else if meta.path == BORROW {
1109                     if meta.input.peek(Token![=]) {
1110                         // #[serde(borrow = "'a + 'b")]
1111                         let lifetimes = parse_lit_into_lifetimes(cx, &meta)?;
1112                         if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, field) {
1113                             for lifetime in &lifetimes {
1114                                 if !borrowable.contains(lifetime) {
1115                                     let msg = format!(
1116                                         "field `{}` does not have lifetime {}",
1117                                         ident, lifetime,
1118                                     );
1119                                     cx.error_spanned_by(field, msg);
1120                                 }
1121                             }
1122                             borrowed_lifetimes.set(&meta.path, lifetimes);
1123                         }
1124                     } else {
1125                         // #[serde(borrow)]
1126                         if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, field) {
1127                             borrowed_lifetimes.set(&meta.path, borrowable);
1128                         }
1129                     }
1130                 } else if meta.path == GETTER {
1131                     // #[serde(getter = "...")]
1132                     if let Some(path) = parse_lit_into_expr_path(cx, GETTER, &meta)? {
1133                         getter.set(&meta.path, path);
1134                     }
1135                 } else if meta.path == FLATTEN {
1136                     // #[serde(flatten)]
1137                     flatten.set_true(&meta.path);
1138                 } else {
1139                     let path = meta.path.to_token_stream().to_string().replace(' ', "");
1140                     return Err(
1141                         meta.error(format_args!("unknown serde field attribute `{}`", path))
1142                     );
1143                 }
1144                 Ok(())
1145             }) {
1146                 cx.syn_error(err);
1147             }
1148         }
1149 
1150         // Is skip_deserializing, initialize the field to Default::default() unless a
1151         // different default is specified by `#[serde(default = "...")]` on
1152         // ourselves or our container (e.g. the struct we are in).
1153         if let Default::None = *container_default {
1154             if skip_deserializing.0.value.is_some() {
1155                 default.set_if_none(Default::Default);
1156             }
1157         }
1158 
1159         let mut borrowed_lifetimes = borrowed_lifetimes.get().unwrap_or_default();
1160         if !borrowed_lifetimes.is_empty() {
1161             // Cow<str> and Cow<[u8]> never borrow by default:
1162             //
1163             //     impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T>
1164             //
1165             // A #[serde(borrow)] attribute enables borrowing that corresponds
1166             // roughly to these impls:
1167             //
1168             //     impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, str>
1169             //     impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, [u8]>
1170             if is_cow(&field.ty, is_str) {
1171                 let mut path = syn::Path {
1172                     leading_colon: None,
1173                     segments: Punctuated::new(),
1174                 };
1175                 let span = Span::call_site();
1176                 path.segments.push(Ident::new("_serde", span).into());
1177                 path.segments.push(Ident::new("__private", span).into());
1178                 path.segments.push(Ident::new("de", span).into());
1179                 path.segments
1180                     .push(Ident::new("borrow_cow_str", span).into());
1181                 let expr = syn::ExprPath {
1182                     attrs: Vec::new(),
1183                     qself: None,
1184                     path,
1185                 };
1186                 deserialize_with.set_if_none(expr);
1187             } else if is_cow(&field.ty, is_slice_u8) {
1188                 let mut path = syn::Path {
1189                     leading_colon: None,
1190                     segments: Punctuated::new(),
1191                 };
1192                 let span = Span::call_site();
1193                 path.segments.push(Ident::new("_serde", span).into());
1194                 path.segments.push(Ident::new("__private", span).into());
1195                 path.segments.push(Ident::new("de", span).into());
1196                 path.segments
1197                     .push(Ident::new("borrow_cow_bytes", span).into());
1198                 let expr = syn::ExprPath {
1199                     attrs: Vec::new(),
1200                     qself: None,
1201                     path,
1202                 };
1203                 deserialize_with.set_if_none(expr);
1204             }
1205         } else if is_implicitly_borrowed(&field.ty) {
1206             // Types &str and &[u8] are always implicitly borrowed. No need for
1207             // a #[serde(borrow)].
1208             collect_lifetimes(&field.ty, &mut borrowed_lifetimes);
1209         }
1210 
1211         Field {
1212             name: Name::from_attrs(ident, ser_name, de_name, Some(de_aliases)),
1213             skip_serializing: skip_serializing.get(),
1214             skip_deserializing: skip_deserializing.get(),
1215             skip_serializing_if: skip_serializing_if.get(),
1216             default: default.get().unwrap_or(Default::None),
1217             serialize_with: serialize_with.get(),
1218             deserialize_with: deserialize_with.get(),
1219             ser_bound: ser_bound.get(),
1220             de_bound: de_bound.get(),
1221             borrowed_lifetimes,
1222             getter: getter.get(),
1223             flatten: flatten.get(),
1224             transparent: false,
1225         }
1226     }
1227 
name(&self) -> &Name1228     pub fn name(&self) -> &Name {
1229         &self.name
1230     }
1231 
aliases(&self) -> Vec<String>1232     pub fn aliases(&self) -> Vec<String> {
1233         self.name.deserialize_aliases()
1234     }
1235 
rename_by_rules(&mut self, rules: &RenameAllRules)1236     pub fn rename_by_rules(&mut self, rules: &RenameAllRules) {
1237         if !self.name.serialize_renamed {
1238             self.name.serialize = rules.serialize.apply_to_field(&self.name.serialize);
1239         }
1240         if !self.name.deserialize_renamed {
1241             self.name.deserialize = rules.deserialize.apply_to_field(&self.name.deserialize);
1242         }
1243     }
1244 
skip_serializing(&self) -> bool1245     pub fn skip_serializing(&self) -> bool {
1246         self.skip_serializing
1247     }
1248 
skip_deserializing(&self) -> bool1249     pub fn skip_deserializing(&self) -> bool {
1250         self.skip_deserializing
1251     }
1252 
skip_serializing_if(&self) -> Option<&syn::ExprPath>1253     pub fn skip_serializing_if(&self) -> Option<&syn::ExprPath> {
1254         self.skip_serializing_if.as_ref()
1255     }
1256 
default(&self) -> &Default1257     pub fn default(&self) -> &Default {
1258         &self.default
1259     }
1260 
serialize_with(&self) -> Option<&syn::ExprPath>1261     pub fn serialize_with(&self) -> Option<&syn::ExprPath> {
1262         self.serialize_with.as_ref()
1263     }
1264 
deserialize_with(&self) -> Option<&syn::ExprPath>1265     pub fn deserialize_with(&self) -> Option<&syn::ExprPath> {
1266         self.deserialize_with.as_ref()
1267     }
1268 
ser_bound(&self) -> Option<&[syn::WherePredicate]>1269     pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
1270         self.ser_bound.as_ref().map(|vec| &vec[..])
1271     }
1272 
de_bound(&self) -> Option<&[syn::WherePredicate]>1273     pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
1274         self.de_bound.as_ref().map(|vec| &vec[..])
1275     }
1276 
borrowed_lifetimes(&self) -> &BTreeSet<syn::Lifetime>1277     pub fn borrowed_lifetimes(&self) -> &BTreeSet<syn::Lifetime> {
1278         &self.borrowed_lifetimes
1279     }
1280 
getter(&self) -> Option<&syn::ExprPath>1281     pub fn getter(&self) -> Option<&syn::ExprPath> {
1282         self.getter.as_ref()
1283     }
1284 
flatten(&self) -> bool1285     pub fn flatten(&self) -> bool {
1286         self.flatten
1287     }
1288 
transparent(&self) -> bool1289     pub fn transparent(&self) -> bool {
1290         self.transparent
1291     }
1292 
mark_transparent(&mut self)1293     pub fn mark_transparent(&mut self) {
1294         self.transparent = true;
1295     }
1296 }
1297 
1298 type SerAndDe<T> = (Option<T>, Option<T>);
1299 
get_ser_and_de<'c, T, F, R>( cx: &'c Ctxt, attr_name: Symbol, meta: &ParseNestedMeta, f: F, ) -> syn::Result<(VecAttr<'c, T>, VecAttr<'c, T>)> where T: Clone, F: Fn(&Ctxt, Symbol, Symbol, &ParseNestedMeta) -> syn::Result<R>, R: Into<Option<T>>,1300 fn get_ser_and_de<'c, T, F, R>(
1301     cx: &'c Ctxt,
1302     attr_name: Symbol,
1303     meta: &ParseNestedMeta,
1304     f: F,
1305 ) -> syn::Result<(VecAttr<'c, T>, VecAttr<'c, T>)>
1306 where
1307     T: Clone,
1308     F: Fn(&Ctxt, Symbol, Symbol, &ParseNestedMeta) -> syn::Result<R>,
1309     R: Into<Option<T>>,
1310 {
1311     let mut ser_meta = VecAttr::none(cx, attr_name);
1312     let mut de_meta = VecAttr::none(cx, attr_name);
1313 
1314     let lookahead = meta.input.lookahead1();
1315     if lookahead.peek(Token![=]) {
1316         if let Some(both) = f(cx, attr_name, attr_name, meta)?.into() {
1317             ser_meta.insert(&meta.path, both.clone());
1318             de_meta.insert(&meta.path, both);
1319         }
1320     } else if lookahead.peek(token::Paren) {
1321         meta.parse_nested_meta(|meta| {
1322             if meta.path == SERIALIZE {
1323                 if let Some(v) = f(cx, attr_name, SERIALIZE, &meta)?.into() {
1324                     ser_meta.insert(&meta.path, v);
1325                 }
1326             } else if meta.path == DESERIALIZE {
1327                 if let Some(v) = f(cx, attr_name, DESERIALIZE, &meta)?.into() {
1328                     de_meta.insert(&meta.path, v);
1329                 }
1330             } else {
1331                 return Err(meta.error(format_args!(
1332                     "malformed {0} attribute, expected `{0}(serialize = ..., deserialize = ...)`",
1333                     attr_name,
1334                 )));
1335             }
1336             Ok(())
1337         })?;
1338     } else {
1339         return Err(lookahead.error());
1340     }
1341 
1342     Ok((ser_meta, de_meta))
1343 }
1344 
get_renames( cx: &Ctxt, attr_name: Symbol, meta: &ParseNestedMeta, ) -> syn::Result<SerAndDe<syn::LitStr>>1345 fn get_renames(
1346     cx: &Ctxt,
1347     attr_name: Symbol,
1348     meta: &ParseNestedMeta,
1349 ) -> syn::Result<SerAndDe<syn::LitStr>> {
1350     let (ser, de) = get_ser_and_de(cx, attr_name, meta, get_lit_str2)?;
1351     Ok((ser.at_most_one(), de.at_most_one()))
1352 }
1353 
get_multiple_renames( cx: &Ctxt, meta: &ParseNestedMeta, ) -> syn::Result<(Option<syn::LitStr>, Vec<syn::LitStr>)>1354 fn get_multiple_renames(
1355     cx: &Ctxt,
1356     meta: &ParseNestedMeta,
1357 ) -> syn::Result<(Option<syn::LitStr>, Vec<syn::LitStr>)> {
1358     let (ser, de) = get_ser_and_de(cx, RENAME, meta, get_lit_str2)?;
1359     Ok((ser.at_most_one(), de.get()))
1360 }
1361 
get_where_predicates( cx: &Ctxt, meta: &ParseNestedMeta, ) -> syn::Result<SerAndDe<Vec<syn::WherePredicate>>>1362 fn get_where_predicates(
1363     cx: &Ctxt,
1364     meta: &ParseNestedMeta,
1365 ) -> syn::Result<SerAndDe<Vec<syn::WherePredicate>>> {
1366     let (ser, de) = get_ser_and_de(cx, BOUND, meta, parse_lit_into_where)?;
1367     Ok((ser.at_most_one(), de.at_most_one()))
1368 }
1369 
get_lit_str( cx: &Ctxt, attr_name: Symbol, meta: &ParseNestedMeta, ) -> syn::Result<Option<syn::LitStr>>1370 fn get_lit_str(
1371     cx: &Ctxt,
1372     attr_name: Symbol,
1373     meta: &ParseNestedMeta,
1374 ) -> syn::Result<Option<syn::LitStr>> {
1375     get_lit_str2(cx, attr_name, attr_name, meta)
1376 }
1377 
get_lit_str2( cx: &Ctxt, attr_name: Symbol, meta_item_name: Symbol, meta: &ParseNestedMeta, ) -> syn::Result<Option<syn::LitStr>>1378 fn get_lit_str2(
1379     cx: &Ctxt,
1380     attr_name: Symbol,
1381     meta_item_name: Symbol,
1382     meta: &ParseNestedMeta,
1383 ) -> syn::Result<Option<syn::LitStr>> {
1384     let expr: syn::Expr = meta.value()?.parse()?;
1385     let mut value = &expr;
1386     while let syn::Expr::Group(e) = value {
1387         value = &e.expr;
1388     }
1389     if let syn::Expr::Lit(syn::ExprLit {
1390         lit: syn::Lit::Str(lit),
1391         ..
1392     }) = value
1393     {
1394         Ok(Some(lit.clone()))
1395     } else {
1396         cx.error_spanned_by(
1397             expr,
1398             format!(
1399                 "expected serde {} attribute to be a string: `{} = \"...\"`",
1400                 attr_name, meta_item_name
1401             ),
1402         );
1403         Ok(None)
1404     }
1405 }
1406 
parse_lit_into_path( cx: &Ctxt, attr_name: Symbol, meta: &ParseNestedMeta, ) -> syn::Result<Option<syn::Path>>1407 fn parse_lit_into_path(
1408     cx: &Ctxt,
1409     attr_name: Symbol,
1410     meta: &ParseNestedMeta,
1411 ) -> syn::Result<Option<syn::Path>> {
1412     let string = match get_lit_str(cx, attr_name, meta)? {
1413         Some(string) => string,
1414         None => return Ok(None),
1415     };
1416 
1417     Ok(match string.parse() {
1418         Ok(path) => Some(path),
1419         Err(_) => {
1420             cx.error_spanned_by(
1421                 &string,
1422                 format!("failed to parse path: {:?}", string.value()),
1423             );
1424             None
1425         }
1426     })
1427 }
1428 
parse_lit_into_expr_path( cx: &Ctxt, attr_name: Symbol, meta: &ParseNestedMeta, ) -> syn::Result<Option<syn::ExprPath>>1429 fn parse_lit_into_expr_path(
1430     cx: &Ctxt,
1431     attr_name: Symbol,
1432     meta: &ParseNestedMeta,
1433 ) -> syn::Result<Option<syn::ExprPath>> {
1434     let string = match get_lit_str(cx, attr_name, meta)? {
1435         Some(string) => string,
1436         None => return Ok(None),
1437     };
1438 
1439     Ok(match string.parse() {
1440         Ok(expr) => Some(expr),
1441         Err(_) => {
1442             cx.error_spanned_by(
1443                 &string,
1444                 format!("failed to parse path: {:?}", string.value()),
1445             );
1446             None
1447         }
1448     })
1449 }
1450 
parse_lit_into_where( cx: &Ctxt, attr_name: Symbol, meta_item_name: Symbol, meta: &ParseNestedMeta, ) -> syn::Result<Vec<syn::WherePredicate>>1451 fn parse_lit_into_where(
1452     cx: &Ctxt,
1453     attr_name: Symbol,
1454     meta_item_name: Symbol,
1455     meta: &ParseNestedMeta,
1456 ) -> syn::Result<Vec<syn::WherePredicate>> {
1457     let string = match get_lit_str2(cx, attr_name, meta_item_name, meta)? {
1458         Some(string) => string,
1459         None => return Ok(Vec::new()),
1460     };
1461 
1462     Ok(
1463         match string.parse_with(Punctuated::<syn::WherePredicate, Token![,]>::parse_terminated) {
1464             Ok(predicates) => Vec::from_iter(predicates),
1465             Err(err) => {
1466                 cx.error_spanned_by(string, err);
1467                 Vec::new()
1468             }
1469         },
1470     )
1471 }
1472 
parse_lit_into_ty( cx: &Ctxt, attr_name: Symbol, meta: &ParseNestedMeta, ) -> syn::Result<Option<syn::Type>>1473 fn parse_lit_into_ty(
1474     cx: &Ctxt,
1475     attr_name: Symbol,
1476     meta: &ParseNestedMeta,
1477 ) -> syn::Result<Option<syn::Type>> {
1478     let string = match get_lit_str(cx, attr_name, meta)? {
1479         Some(string) => string,
1480         None => return Ok(None),
1481     };
1482 
1483     Ok(match string.parse() {
1484         Ok(ty) => Some(ty),
1485         Err(_) => {
1486             cx.error_spanned_by(
1487                 &string,
1488                 format!("failed to parse type: {} = {:?}", attr_name, string.value()),
1489             );
1490             None
1491         }
1492     })
1493 }
1494 
1495 // Parses a string literal like "'a + 'b + 'c" containing a nonempty list of
1496 // lifetimes separated by `+`.
parse_lit_into_lifetimes( cx: &Ctxt, meta: &ParseNestedMeta, ) -> syn::Result<BTreeSet<syn::Lifetime>>1497 fn parse_lit_into_lifetimes(
1498     cx: &Ctxt,
1499     meta: &ParseNestedMeta,
1500 ) -> syn::Result<BTreeSet<syn::Lifetime>> {
1501     let string = match get_lit_str(cx, BORROW, meta)? {
1502         Some(string) => string,
1503         None => return Ok(BTreeSet::new()),
1504     };
1505 
1506     if let Ok(lifetimes) = string.parse_with(|input: ParseStream| {
1507         let mut set = BTreeSet::new();
1508         while !input.is_empty() {
1509             let lifetime: Lifetime = input.parse()?;
1510             if !set.insert(lifetime.clone()) {
1511                 cx.error_spanned_by(
1512                     &string,
1513                     format!("duplicate borrowed lifetime `{}`", lifetime),
1514                 );
1515             }
1516             if input.is_empty() {
1517                 break;
1518             }
1519             input.parse::<Token![+]>()?;
1520         }
1521         Ok(set)
1522     }) {
1523         if lifetimes.is_empty() {
1524             cx.error_spanned_by(string, "at least one lifetime must be borrowed");
1525         }
1526         return Ok(lifetimes);
1527     }
1528 
1529     cx.error_spanned_by(
1530         &string,
1531         format!("failed to parse borrowed lifetimes: {:?}", string.value()),
1532     );
1533     Ok(BTreeSet::new())
1534 }
1535 
is_implicitly_borrowed(ty: &syn::Type) -> bool1536 fn is_implicitly_borrowed(ty: &syn::Type) -> bool {
1537     is_implicitly_borrowed_reference(ty) || is_option(ty, is_implicitly_borrowed_reference)
1538 }
1539 
is_implicitly_borrowed_reference(ty: &syn::Type) -> bool1540 fn is_implicitly_borrowed_reference(ty: &syn::Type) -> bool {
1541     is_reference(ty, is_str) || is_reference(ty, is_slice_u8)
1542 }
1543 
1544 // Whether the type looks like it might be `std::borrow::Cow<T>` where elem="T".
1545 // This can have false negatives and false positives.
1546 //
1547 // False negative:
1548 //
1549 //     use std::borrow::Cow as Pig;
1550 //
1551 //     #[derive(Deserialize)]
1552 //     struct S<'a> {
1553 //         #[serde(borrow)]
1554 //         pig: Pig<'a, str>,
1555 //     }
1556 //
1557 // False positive:
1558 //
1559 //     type str = [i16];
1560 //
1561 //     #[derive(Deserialize)]
1562 //     struct S<'a> {
1563 //         #[serde(borrow)]
1564 //         cow: Cow<'a, str>,
1565 //     }
is_cow(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool1566 fn is_cow(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
1567     let path = match ungroup(ty) {
1568         syn::Type::Path(ty) => &ty.path,
1569         _ => {
1570             return false;
1571         }
1572     };
1573     let seg = match path.segments.last() {
1574         Some(seg) => seg,
1575         None => {
1576             return false;
1577         }
1578     };
1579     let args = match &seg.arguments {
1580         syn::PathArguments::AngleBracketed(bracketed) => &bracketed.args,
1581         _ => {
1582             return false;
1583         }
1584     };
1585     seg.ident == "Cow"
1586         && args.len() == 2
1587         && match (&args[0], &args[1]) {
1588             (syn::GenericArgument::Lifetime(_), syn::GenericArgument::Type(arg)) => elem(arg),
1589             _ => false,
1590         }
1591 }
1592 
is_option(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool1593 fn is_option(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
1594     let path = match ungroup(ty) {
1595         syn::Type::Path(ty) => &ty.path,
1596         _ => {
1597             return false;
1598         }
1599     };
1600     let seg = match path.segments.last() {
1601         Some(seg) => seg,
1602         None => {
1603             return false;
1604         }
1605     };
1606     let args = match &seg.arguments {
1607         syn::PathArguments::AngleBracketed(bracketed) => &bracketed.args,
1608         _ => {
1609             return false;
1610         }
1611     };
1612     seg.ident == "Option"
1613         && args.len() == 1
1614         && match &args[0] {
1615             syn::GenericArgument::Type(arg) => elem(arg),
1616             _ => false,
1617         }
1618 }
1619 
1620 // Whether the type looks like it might be `&T` where elem="T". This can have
1621 // false negatives and false positives.
1622 //
1623 // False negative:
1624 //
1625 //     type Yarn = str;
1626 //
1627 //     #[derive(Deserialize)]
1628 //     struct S<'a> {
1629 //         r: &'a Yarn,
1630 //     }
1631 //
1632 // False positive:
1633 //
1634 //     type str = [i16];
1635 //
1636 //     #[derive(Deserialize)]
1637 //     struct S<'a> {
1638 //         r: &'a str,
1639 //     }
is_reference(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool1640 fn is_reference(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
1641     match ungroup(ty) {
1642         syn::Type::Reference(ty) => ty.mutability.is_none() && elem(&ty.elem),
1643         _ => false,
1644     }
1645 }
1646 
is_str(ty: &syn::Type) -> bool1647 fn is_str(ty: &syn::Type) -> bool {
1648     is_primitive_type(ty, "str")
1649 }
1650 
is_slice_u8(ty: &syn::Type) -> bool1651 fn is_slice_u8(ty: &syn::Type) -> bool {
1652     match ungroup(ty) {
1653         syn::Type::Slice(ty) => is_primitive_type(&ty.elem, "u8"),
1654         _ => false,
1655     }
1656 }
1657 
is_primitive_type(ty: &syn::Type, primitive: &str) -> bool1658 fn is_primitive_type(ty: &syn::Type, primitive: &str) -> bool {
1659     match ungroup(ty) {
1660         syn::Type::Path(ty) => ty.qself.is_none() && is_primitive_path(&ty.path, primitive),
1661         _ => false,
1662     }
1663 }
1664 
is_primitive_path(path: &syn::Path, primitive: &str) -> bool1665 fn is_primitive_path(path: &syn::Path, primitive: &str) -> bool {
1666     path.leading_colon.is_none()
1667         && path.segments.len() == 1
1668         && path.segments[0].ident == primitive
1669         && path.segments[0].arguments.is_empty()
1670 }
1671 
1672 // All lifetimes that this type could borrow from a Deserializer.
1673 //
1674 // For example a type `S<'a, 'b>` could borrow `'a` and `'b`. On the other hand
1675 // a type `for<'a> fn(&'a str)` could not borrow `'a` from the Deserializer.
1676 //
1677 // This is used when there is an explicit or implicit `#[serde(borrow)]`
1678 // attribute on the field so there must be at least one borrowable lifetime.
borrowable_lifetimes( cx: &Ctxt, name: &str, field: &syn::Field, ) -> Result<BTreeSet<syn::Lifetime>, ()>1679 fn borrowable_lifetimes(
1680     cx: &Ctxt,
1681     name: &str,
1682     field: &syn::Field,
1683 ) -> Result<BTreeSet<syn::Lifetime>, ()> {
1684     let mut lifetimes = BTreeSet::new();
1685     collect_lifetimes(&field.ty, &mut lifetimes);
1686     if lifetimes.is_empty() {
1687         let msg = format!("field `{}` has no lifetimes to borrow", name);
1688         cx.error_spanned_by(field, msg);
1689         Err(())
1690     } else {
1691         Ok(lifetimes)
1692     }
1693 }
1694 
collect_lifetimes(ty: &syn::Type, out: &mut BTreeSet<syn::Lifetime>)1695 fn collect_lifetimes(ty: &syn::Type, out: &mut BTreeSet<syn::Lifetime>) {
1696     match ty {
1697         syn::Type::Slice(ty) => {
1698             collect_lifetimes(&ty.elem, out);
1699         }
1700         syn::Type::Array(ty) => {
1701             collect_lifetimes(&ty.elem, out);
1702         }
1703         syn::Type::Ptr(ty) => {
1704             collect_lifetimes(&ty.elem, out);
1705         }
1706         syn::Type::Reference(ty) => {
1707             out.extend(ty.lifetime.iter().cloned());
1708             collect_lifetimes(&ty.elem, out);
1709         }
1710         syn::Type::Tuple(ty) => {
1711             for elem in &ty.elems {
1712                 collect_lifetimes(elem, out);
1713             }
1714         }
1715         syn::Type::Path(ty) => {
1716             if let Some(qself) = &ty.qself {
1717                 collect_lifetimes(&qself.ty, out);
1718             }
1719             for seg in &ty.path.segments {
1720                 if let syn::PathArguments::AngleBracketed(bracketed) = &seg.arguments {
1721                     for arg in &bracketed.args {
1722                         match arg {
1723                             syn::GenericArgument::Lifetime(lifetime) => {
1724                                 out.insert(lifetime.clone());
1725                             }
1726                             syn::GenericArgument::Type(ty) => {
1727                                 collect_lifetimes(ty, out);
1728                             }
1729                             syn::GenericArgument::AssocType(binding) => {
1730                                 collect_lifetimes(&binding.ty, out);
1731                             }
1732                             _ => {}
1733                         }
1734                     }
1735                 }
1736             }
1737         }
1738         syn::Type::Paren(ty) => {
1739             collect_lifetimes(&ty.elem, out);
1740         }
1741         syn::Type::Group(ty) => {
1742             collect_lifetimes(&ty.elem, out);
1743         }
1744         syn::Type::Macro(ty) => {
1745             collect_lifetimes_from_tokens(ty.mac.tokens.clone(), out);
1746         }
1747         syn::Type::BareFn(_)
1748         | syn::Type::Never(_)
1749         | syn::Type::TraitObject(_)
1750         | syn::Type::ImplTrait(_)
1751         | syn::Type::Infer(_)
1752         | syn::Type::Verbatim(_) => {}
1753 
1754         #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1755         _ => {}
1756     }
1757 }
1758 
collect_lifetimes_from_tokens(tokens: TokenStream, out: &mut BTreeSet<syn::Lifetime>)1759 fn collect_lifetimes_from_tokens(tokens: TokenStream, out: &mut BTreeSet<syn::Lifetime>) {
1760     let mut iter = tokens.into_iter();
1761     while let Some(tt) = iter.next() {
1762         match &tt {
1763             TokenTree::Punct(op) if op.as_char() == '\'' && op.spacing() == Spacing::Joint => {
1764                 if let Some(TokenTree::Ident(ident)) = iter.next() {
1765                     out.insert(syn::Lifetime {
1766                         apostrophe: op.span(),
1767                         ident,
1768                     });
1769                 }
1770             }
1771             TokenTree::Group(group) => {
1772                 let tokens = group.stream();
1773                 collect_lifetimes_from_tokens(tokens, out);
1774             }
1775             _ => {}
1776         }
1777     }
1778 }
1779