1 // Copyright 2017 Serde Developers
2 //
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
8 
9 use Ctxt;
10 use syn;
11 use syn::MetaItem::{List, NameValue, Word};
12 use syn::NestedMetaItem::{Literal, MetaItem};
13 use synom::IResult;
14 use std::collections::BTreeSet;
15 use std::str::FromStr;
16 
17 // This module handles parsing of `#[serde(...)]` attributes. The entrypoints
18 // are `attr::Container::from_ast`, `attr::Variant::from_ast`, and
19 // `attr::Field::from_ast`. Each returns an instance of the corresponding
20 // struct. Note that none of them return a Result. Unrecognized, malformed, or
21 // duplicated attributes result in a span_err but otherwise are ignored. The
22 // user will see errors simultaneously for all bad attributes in the crate
23 // rather than just the first.
24 
25 pub use case::RenameRule;
26 
27 struct Attr<'c, T> {
28     cx: &'c Ctxt,
29     name: &'static str,
30     value: Option<T>,
31 }
32 
33 impl<'c, T> Attr<'c, T> {
none(cx: &'c Ctxt, name: &'static str) -> Self34     fn none(cx: &'c Ctxt, name: &'static str) -> Self {
35         Attr {
36             cx: cx,
37             name: name,
38             value: None,
39         }
40     }
41 
set(&mut self, value: T)42     fn set(&mut self, value: T) {
43         if self.value.is_some() {
44             self.cx
45                 .error(format!("duplicate serde attribute `{}`", self.name));
46         } else {
47             self.value = Some(value);
48         }
49     }
50 
set_opt(&mut self, value: Option<T>)51     fn set_opt(&mut self, value: Option<T>) {
52         if let Some(value) = value {
53             self.set(value);
54         }
55     }
56 
set_if_none(&mut self, value: T)57     fn set_if_none(&mut self, value: T) {
58         if self.value.is_none() {
59             self.value = Some(value);
60         }
61     }
62 
get(self) -> Option<T>63     fn get(self) -> Option<T> {
64         self.value
65     }
66 }
67 
68 struct BoolAttr<'c>(Attr<'c, ()>);
69 
70 impl<'c> BoolAttr<'c> {
none(cx: &'c Ctxt, name: &'static str) -> Self71     fn none(cx: &'c Ctxt, name: &'static str) -> Self {
72         BoolAttr(Attr::none(cx, name))
73     }
74 
set_true(&mut self)75     fn set_true(&mut self) {
76         self.0.set(());
77     }
78 
get(&self) -> bool79     fn get(&self) -> bool {
80         self.0.value.is_some()
81     }
82 }
83 
84 #[derive(Debug)]
85 pub struct Name {
86     serialize: String,
87     deserialize: String,
88 }
89 
90 impl Name {
91     /// Return the container name for the container when serializing.
serialize_name(&self) -> String92     pub fn serialize_name(&self) -> String {
93         self.serialize.clone()
94     }
95 
96     /// Return the container name for the container when deserializing.
deserialize_name(&self) -> String97     pub fn deserialize_name(&self) -> String {
98         self.deserialize.clone()
99     }
100 }
101 
102 /// Represents container (e.g. struct) attribute information
103 #[derive(Debug)]
104 pub struct Container {
105     name: Name,
106     deny_unknown_fields: bool,
107     default: Default,
108     rename_all: RenameRule,
109     ser_bound: Option<Vec<syn::WherePredicate>>,
110     de_bound: Option<Vec<syn::WherePredicate>>,
111     tag: EnumTag,
112     from_type: Option<syn::Ty>,
113     into_type: Option<syn::Ty>,
114     remote: Option<syn::Path>,
115     identifier: Identifier,
116 }
117 
118 /// Styles of representing an enum.
119 #[derive(Debug)]
120 pub enum EnumTag {
121     /// The default.
122     ///
123     /// ```json
124     /// {"variant1": {"key1": "value1", "key2": "value2"}}
125     /// ```
126     External,
127 
128     /// `#[serde(tag = "type")]`
129     ///
130     /// ```json
131     /// {"type": "variant1", "key1": "value1", "key2": "value2"}
132     /// ```
133     Internal { tag: String },
134 
135     /// `#[serde(tag = "t", content = "c")]`
136     ///
137     /// ```json
138     /// {"t": "variant1", "c": {"key1": "value1", "key2": "value2"}}
139     /// ```
140     Adjacent { tag: String, content: String },
141 
142     /// `#[serde(untagged)]`
143     ///
144     /// ```json
145     /// {"key1": "value1", "key2": "value2"}
146     /// ```
147     None,
148 }
149 
150 /// Whether this enum represents the fields of a struct or the variants of an
151 /// enum.
152 #[derive(Copy, Clone, Debug)]
153 pub enum Identifier {
154     /// It does not.
155     No,
156 
157     /// This enum represents the fields of a struct. All of the variants must be
158     /// unit variants, except possibly one which is annotated with
159     /// `#[serde(other)]` and is a newtype variant.
160     Field,
161 
162     /// This enum represents the variants of an enum. All of the variants must
163     /// be unit variants.
164     Variant,
165 }
166 
167 impl Identifier {
is_some(self) -> bool168     pub fn is_some(self) -> bool {
169         match self {
170             Identifier::No => false,
171             Identifier::Field | Identifier::Variant => true,
172         }
173     }
174 }
175 
176 impl Container {
177     /// Extract out the `#[serde(...)]` attributes from an item.
from_ast(cx: &Ctxt, item: &syn::DeriveInput) -> Self178     pub fn from_ast(cx: &Ctxt, item: &syn::DeriveInput) -> Self {
179         let mut ser_name = Attr::none(cx, "rename");
180         let mut de_name = Attr::none(cx, "rename");
181         let mut deny_unknown_fields = BoolAttr::none(cx, "deny_unknown_fields");
182         let mut default = Attr::none(cx, "default");
183         let mut rename_all = Attr::none(cx, "rename_all");
184         let mut ser_bound = Attr::none(cx, "bound");
185         let mut de_bound = Attr::none(cx, "bound");
186         let mut untagged = BoolAttr::none(cx, "untagged");
187         let mut internal_tag = Attr::none(cx, "tag");
188         let mut content = Attr::none(cx, "content");
189         let mut from_type = Attr::none(cx, "from");
190         let mut into_type = Attr::none(cx, "into");
191         let mut remote = Attr::none(cx, "remote");
192         let mut field_identifier = BoolAttr::none(cx, "field_identifier");
193         let mut variant_identifier = BoolAttr::none(cx, "variant_identifier");
194 
195         for meta_items in item.attrs.iter().filter_map(get_serde_meta_items) {
196             for meta_item in meta_items {
197                 match meta_item {
198                     // Parse `#[serde(rename = "foo")]`
199                     MetaItem(NameValue(ref name, ref lit)) if name == "rename" => {
200                         if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
201                             ser_name.set(s.clone());
202                             de_name.set(s);
203                         }
204                     }
205 
206                     // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
207                     MetaItem(List(ref name, ref meta_items)) if name == "rename" => {
208                         if let Ok((ser, de)) = get_renames(cx, meta_items) {
209                             ser_name.set_opt(ser);
210                             de_name.set_opt(de);
211                         }
212                     }
213 
214                     // Parse `#[serde(rename_all = "foo")]`
215                     MetaItem(NameValue(ref name, ref lit)) if name == "rename_all" => {
216                         if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
217                             match RenameRule::from_str(&s) {
218                                 Ok(rename_rule) => rename_all.set(rename_rule),
219                                 Err(()) => cx.error(format!(
220                                     "unknown rename rule for #[serde(rename_all \
221                                      = {:?})]",
222                                     s
223                                 )),
224                             }
225                         }
226                     }
227 
228                     // Parse `#[serde(deny_unknown_fields)]`
229                     MetaItem(Word(ref name)) if name == "deny_unknown_fields" => {
230                         deny_unknown_fields.set_true();
231                     }
232 
233                     // Parse `#[serde(default)]`
234                     MetaItem(Word(ref name)) if name == "default" => match item.body {
235                         syn::Body::Struct(syn::VariantData::Struct(_)) => {
236                             default.set(Default::Default);
237                         }
238                         _ => cx.error(
239                             "#[serde(default)] can only be used on structs \
240                              with named fields",
241                         ),
242                     },
243 
244                     // Parse `#[serde(default = "...")]`
245                     MetaItem(NameValue(ref name, ref lit)) if name == "default" => {
246                         if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
247                             match item.body {
248                                 syn::Body::Struct(syn::VariantData::Struct(_)) => {
249                                     default.set(Default::Path(path));
250                                 }
251                                 _ => cx.error(
252                                     "#[serde(default = \"...\")] can only be used \
253                                      on structs with named fields",
254                                 ),
255                             }
256                         }
257                     }
258 
259                     // Parse `#[serde(bound = "D: Serialize")]`
260                     MetaItem(NameValue(ref name, ref lit)) if name == "bound" => {
261                         if let Ok(where_predicates) =
262                             parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit)
263                         {
264                             ser_bound.set(where_predicates.clone());
265                             de_bound.set(where_predicates);
266                         }
267                     }
268 
269                     // Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]`
270                     MetaItem(List(ref name, ref meta_items)) if name == "bound" => {
271                         if let Ok((ser, de)) = get_where_predicates(cx, meta_items) {
272                             ser_bound.set_opt(ser);
273                             de_bound.set_opt(de);
274                         }
275                     }
276 
277                     // Parse `#[serde(untagged)]`
278                     MetaItem(Word(ref name)) if name == "untagged" => match item.body {
279                         syn::Body::Enum(_) => {
280                             untagged.set_true();
281                         }
282                         syn::Body::Struct(_) => {
283                             cx.error("#[serde(untagged)] can only be used on enums")
284                         }
285                     },
286 
287                     // Parse `#[serde(tag = "type")]`
288                     MetaItem(NameValue(ref name, ref lit)) if name == "tag" => {
289                         if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
290                             match item.body {
291                                 syn::Body::Enum(_) => {
292                                     internal_tag.set(s);
293                                 }
294                                 syn::Body::Struct(_) => {
295                                     cx.error("#[serde(tag = \"...\")] can only be used on enums")
296                                 }
297                             }
298                         }
299                     }
300 
301                     // Parse `#[serde(content = "c")]`
302                     MetaItem(NameValue(ref name, ref lit)) if name == "content" => {
303                         if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
304                             match item.body {
305                                 syn::Body::Enum(_) => {
306                                     content.set(s);
307                                 }
308                                 syn::Body::Struct(_) => cx.error(
309                                     "#[serde(content = \"...\")] can only be used on \
310                                      enums",
311                                 ),
312                             }
313                         }
314                     }
315 
316                     // Parse `#[serde(from = "Type")]
317                     MetaItem(NameValue(ref name, ref lit)) if name == "from" => {
318                         if let Ok(from_ty) = parse_lit_into_ty(cx, name.as_ref(), lit) {
319                             from_type.set_opt(Some(from_ty));
320                         }
321                     }
322 
323                     // Parse `#[serde(into = "Type")]
324                     MetaItem(NameValue(ref name, ref lit)) if name == "into" => {
325                         if let Ok(into_ty) = parse_lit_into_ty(cx, name.as_ref(), lit) {
326                             into_type.set_opt(Some(into_ty));
327                         }
328                     }
329 
330                     // Parse `#[serde(remote = "...")]`
331                     MetaItem(NameValue(ref name, ref lit)) if name == "remote" => {
332                         if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
333                             remote.set(path);
334                         }
335                     }
336 
337                     // Parse `#[serde(field_identifier)]`
338                     MetaItem(Word(ref name)) if name == "field_identifier" => {
339                         field_identifier.set_true();
340                     }
341 
342                     // Parse `#[serde(variant_identifier)]`
343                     MetaItem(Word(ref name)) if name == "variant_identifier" => {
344                         variant_identifier.set_true();
345                     }
346 
347                     MetaItem(ref meta_item) => {
348                         cx.error(format!(
349                             "unknown serde container attribute `{}`",
350                             meta_item.name()
351                         ));
352                     }
353 
354                     Literal(_) => {
355                         cx.error("unexpected literal in serde container attribute");
356                     }
357                 }
358             }
359         }
360 
361         Container {
362             name: Name {
363                 serialize: ser_name.get().unwrap_or_else(|| item.ident.to_string()),
364                 deserialize: de_name.get().unwrap_or_else(|| item.ident.to_string()),
365             },
366             deny_unknown_fields: deny_unknown_fields.get(),
367             default: default.get().unwrap_or(Default::None),
368             rename_all: rename_all.get().unwrap_or(RenameRule::None),
369             ser_bound: ser_bound.get(),
370             de_bound: de_bound.get(),
371             tag: decide_tag(cx, item, untagged, internal_tag, content),
372             from_type: from_type.get(),
373             into_type: into_type.get(),
374             remote: remote.get(),
375             identifier: decide_identifier(cx, item, field_identifier, variant_identifier),
376         }
377     }
378 
name(&self) -> &Name379     pub fn name(&self) -> &Name {
380         &self.name
381     }
382 
rename_all(&self) -> &RenameRule383     pub fn rename_all(&self) -> &RenameRule {
384         &self.rename_all
385     }
386 
deny_unknown_fields(&self) -> bool387     pub fn deny_unknown_fields(&self) -> bool {
388         self.deny_unknown_fields
389     }
390 
default(&self) -> &Default391     pub fn default(&self) -> &Default {
392         &self.default
393     }
394 
ser_bound(&self) -> Option<&[syn::WherePredicate]>395     pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
396         self.ser_bound.as_ref().map(|vec| &vec[..])
397     }
398 
de_bound(&self) -> Option<&[syn::WherePredicate]>399     pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
400         self.de_bound.as_ref().map(|vec| &vec[..])
401     }
402 
tag(&self) -> &EnumTag403     pub fn tag(&self) -> &EnumTag {
404         &self.tag
405     }
406 
from_type(&self) -> Option<&syn::Ty>407     pub fn from_type(&self) -> Option<&syn::Ty> {
408         self.from_type.as_ref()
409     }
410 
into_type(&self) -> Option<&syn::Ty>411     pub fn into_type(&self) -> Option<&syn::Ty> {
412         self.into_type.as_ref()
413     }
414 
remote(&self) -> Option<&syn::Path>415     pub fn remote(&self) -> Option<&syn::Path> {
416         self.remote.as_ref()
417     }
418 
identifier(&self) -> Identifier419     pub fn identifier(&self) -> Identifier {
420         self.identifier
421     }
422 }
423 
decide_tag( cx: &Ctxt, item: &syn::DeriveInput, untagged: BoolAttr, internal_tag: Attr<String>, content: Attr<String>, ) -> EnumTag424 fn decide_tag(
425     cx: &Ctxt,
426     item: &syn::DeriveInput,
427     untagged: BoolAttr,
428     internal_tag: Attr<String>,
429     content: Attr<String>,
430 ) -> EnumTag {
431     match (untagged.get(), internal_tag.get(), content.get()) {
432         (false, None, None) => EnumTag::External,
433         (true, None, None) => EnumTag::None,
434         (false, Some(tag), None) => {
435             // Check that there are no tuple variants.
436             if let syn::Body::Enum(ref variants) = item.body {
437                 for variant in variants {
438                     match variant.data {
439                         syn::VariantData::Struct(_) | syn::VariantData::Unit => {}
440                         syn::VariantData::Tuple(ref fields) => {
441                             if fields.len() != 1 {
442                                 cx.error(
443                                     "#[serde(tag = \"...\")] cannot be used with tuple \
444                                      variants",
445                                 );
446                                 break;
447                             }
448                         }
449                     }
450                 }
451             }
452             EnumTag::Internal { tag: tag }
453         }
454         (true, Some(_), None) => {
455             cx.error("enum cannot be both untagged and internally tagged");
456             EnumTag::External // doesn't matter, will error
457         }
458         (false, None, Some(_)) => {
459             cx.error("#[serde(tag = \"...\", content = \"...\")] must be used together");
460             EnumTag::External
461         }
462         (true, None, Some(_)) => {
463             cx.error("untagged enum cannot have #[serde(content = \"...\")]");
464             EnumTag::External
465         }
466         (false, Some(tag), Some(content)) => EnumTag::Adjacent {
467             tag: tag,
468             content: content,
469         },
470         (true, Some(_), Some(_)) => {
471             cx.error("untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]");
472             EnumTag::External
473         }
474     }
475 }
476 
decide_identifier( cx: &Ctxt, item: &syn::DeriveInput, field_identifier: BoolAttr, variant_identifier: BoolAttr, ) -> Identifier477 fn decide_identifier(
478     cx: &Ctxt,
479     item: &syn::DeriveInput,
480     field_identifier: BoolAttr,
481     variant_identifier: BoolAttr,
482 ) -> Identifier {
483     match (&item.body, field_identifier.get(), variant_identifier.get()) {
484         (_, false, false) => Identifier::No,
485         (_, true, true) => {
486             cx.error("`field_identifier` and `variant_identifier` cannot both be set");
487             Identifier::No
488         }
489         (&syn::Body::Struct(_), true, false) => {
490             cx.error("`field_identifier` can only be used on an enum");
491             Identifier::No
492         }
493         (&syn::Body::Struct(_), false, true) => {
494             cx.error("`variant_identifier` can only be used on an enum");
495             Identifier::No
496         }
497         (&syn::Body::Enum(_), true, false) => Identifier::Field,
498         (&syn::Body::Enum(_), false, true) => Identifier::Variant,
499     }
500 }
501 
502 /// Represents variant attribute information
503 #[derive(Debug)]
504 pub struct Variant {
505     name: Name,
506     ser_renamed: bool,
507     de_renamed: bool,
508     rename_all: RenameRule,
509     skip_deserializing: bool,
510     skip_serializing: bool,
511     other: bool,
512     serialize_with: Option<syn::Path>,
513     deserialize_with: Option<syn::Path>,
514     borrow: Option<syn::MetaItem>,
515 }
516 
517 impl Variant {
from_ast(cx: &Ctxt, variant: &syn::Variant) -> Self518     pub fn from_ast(cx: &Ctxt, variant: &syn::Variant) -> Self {
519         let mut ser_name = Attr::none(cx, "rename");
520         let mut de_name = Attr::none(cx, "rename");
521         let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
522         let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
523         let mut rename_all = Attr::none(cx, "rename_all");
524         let mut other = BoolAttr::none(cx, "other");
525         let mut serialize_with = Attr::none(cx, "serialize_with");
526         let mut deserialize_with = Attr::none(cx, "deserialize_with");
527         let mut borrow = Attr::none(cx, "borrow");
528 
529         for meta_items in variant.attrs.iter().filter_map(get_serde_meta_items) {
530             for meta_item in meta_items {
531                 match meta_item {
532                     // Parse `#[serde(rename = "foo")]`
533                     MetaItem(NameValue(ref name, ref lit)) if name == "rename" => {
534                         if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
535                             ser_name.set(s.clone());
536                             de_name.set(s);
537                         }
538                     }
539 
540                     // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
541                     MetaItem(List(ref name, ref meta_items)) if name == "rename" => {
542                         if let Ok((ser, de)) = get_renames(cx, meta_items) {
543                             ser_name.set_opt(ser);
544                             de_name.set_opt(de);
545                         }
546                     }
547 
548                     // Parse `#[serde(rename_all = "foo")]`
549                     MetaItem(NameValue(ref name, ref lit)) if name == "rename_all" => {
550                         if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
551                             match RenameRule::from_str(&s) {
552                                 Ok(rename_rule) => rename_all.set(rename_rule),
553                                 Err(()) => cx.error(format!(
554                                     "unknown rename rule for #[serde(rename_all \
555                                      = {:?})]",
556                                     s
557                                 )),
558                             }
559                         }
560                     }
561 
562                     // Parse `#[serde(skip_deserializing)]`
563                     MetaItem(Word(ref name)) if name == "skip_deserializing" => {
564                         skip_deserializing.set_true();
565                     }
566 
567                     // Parse `#[serde(skip_serializing)]`
568                     MetaItem(Word(ref name)) if name == "skip_serializing" => {
569                         skip_serializing.set_true();
570                     }
571 
572                     // Parse `#[serde(other)]`
573                     MetaItem(Word(ref name)) if name == "other" => {
574                         other.set_true();
575                     }
576 
577                     // Parse `#[serde(with = "...")]`
578                     MetaItem(NameValue(ref name, ref lit)) if name == "with" => {
579                         if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
580                             let mut ser_path = path.clone();
581                             ser_path.segments.push("serialize".into());
582                             serialize_with.set(ser_path);
583                             let mut de_path = path;
584                             de_path.segments.push("deserialize".into());
585                             deserialize_with.set(de_path);
586                         }
587                     }
588 
589                     // Parse `#[serde(serialize_with = "...")]`
590                     MetaItem(NameValue(ref name, ref lit)) if name == "serialize_with" => {
591                         if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
592                             serialize_with.set(path);
593                         }
594                     }
595 
596                     // Parse `#[serde(deserialize_with = "...")]`
597                     MetaItem(NameValue(ref name, ref lit)) if name == "deserialize_with" => {
598                         if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
599                             deserialize_with.set(path);
600                         }
601                     }
602 
603                     // Defer `#[serde(borrow)]` and `#[serde(borrow = "'a + 'b")]`
604                     MetaItem(ref mi) if mi.name() == "borrow" => match variant.data {
605                         syn::VariantData::Tuple(ref fields) if fields.len() == 1 => {
606                             borrow.set(mi.clone());
607                         }
608                         _ => {
609                             cx.error("#[serde(borrow)] may only be used on newtype variants");
610                         }
611                     },
612 
613                     MetaItem(ref meta_item) => {
614                         cx.error(format!(
615                             "unknown serde variant attribute `{}`",
616                             meta_item.name()
617                         ));
618                     }
619 
620                     Literal(_) => {
621                         cx.error("unexpected literal in serde variant attribute");
622                     }
623                 }
624             }
625         }
626 
627         let ser_name = ser_name.get();
628         let ser_renamed = ser_name.is_some();
629         let de_name = de_name.get();
630         let de_renamed = de_name.is_some();
631         Variant {
632             name: Name {
633                 serialize: ser_name.unwrap_or_else(|| variant.ident.to_string()),
634                 deserialize: de_name.unwrap_or_else(|| variant.ident.to_string()),
635             },
636             ser_renamed: ser_renamed,
637             de_renamed: de_renamed,
638             rename_all: rename_all.get().unwrap_or(RenameRule::None),
639             skip_deserializing: skip_deserializing.get(),
640             skip_serializing: skip_serializing.get(),
641             other: other.get(),
642             serialize_with: serialize_with.get(),
643             deserialize_with: deserialize_with.get(),
644             borrow: borrow.get(),
645         }
646     }
647 
name(&self) -> &Name648     pub fn name(&self) -> &Name {
649         &self.name
650     }
651 
rename_by_rule(&mut self, rule: &RenameRule)652     pub fn rename_by_rule(&mut self, rule: &RenameRule) {
653         if !self.ser_renamed {
654             self.name.serialize = rule.apply_to_variant(&self.name.serialize);
655         }
656         if !self.de_renamed {
657             self.name.deserialize = rule.apply_to_variant(&self.name.deserialize);
658         }
659     }
660 
rename_all(&self) -> &RenameRule661     pub fn rename_all(&self) -> &RenameRule {
662         &self.rename_all
663     }
664 
skip_deserializing(&self) -> bool665     pub fn skip_deserializing(&self) -> bool {
666         self.skip_deserializing
667     }
668 
skip_serializing(&self) -> bool669     pub fn skip_serializing(&self) -> bool {
670         self.skip_serializing
671     }
672 
other(&self) -> bool673     pub fn other(&self) -> bool {
674         self.other
675     }
676 
serialize_with(&self) -> Option<&syn::Path>677     pub fn serialize_with(&self) -> Option<&syn::Path> {
678         self.serialize_with.as_ref()
679     }
680 
deserialize_with(&self) -> Option<&syn::Path>681     pub fn deserialize_with(&self) -> Option<&syn::Path> {
682         self.deserialize_with.as_ref()
683     }
684 }
685 
686 /// Represents field attribute information
687 #[derive(Debug)]
688 pub struct Field {
689     name: Name,
690     ser_renamed: bool,
691     de_renamed: bool,
692     skip_serializing: bool,
693     skip_deserializing: bool,
694     skip_serializing_if: Option<syn::Path>,
695     default: Default,
696     serialize_with: Option<syn::Path>,
697     deserialize_with: Option<syn::Path>,
698     ser_bound: Option<Vec<syn::WherePredicate>>,
699     de_bound: Option<Vec<syn::WherePredicate>>,
700     borrowed_lifetimes: BTreeSet<syn::Lifetime>,
701     getter: Option<syn::Path>,
702 }
703 
704 /// Represents the default to use for a field when deserializing.
705 #[derive(Debug, PartialEq)]
706 pub enum Default {
707     /// Field must always be specified because it does not have a default.
708     None,
709     /// The default is given by `std::default::Default::default()`.
710     Default,
711     /// The default is given by this function.
712     Path(syn::Path),
713 }
714 
715 impl Field {
716     /// Extract out the `#[serde(...)]` attributes from a struct field.
from_ast( cx: &Ctxt, index: usize, field: &syn::Field, attrs: Option<&Variant>, container_default: &Default, ) -> Self717     pub fn from_ast(
718         cx: &Ctxt,
719         index: usize,
720         field: &syn::Field,
721         attrs: Option<&Variant>,
722         container_default: &Default,
723     ) -> Self {
724         let mut ser_name = Attr::none(cx, "rename");
725         let mut de_name = Attr::none(cx, "rename");
726         let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
727         let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
728         let mut skip_serializing_if = Attr::none(cx, "skip_serializing_if");
729         let mut default = Attr::none(cx, "default");
730         let mut serialize_with = Attr::none(cx, "serialize_with");
731         let mut deserialize_with = Attr::none(cx, "deserialize_with");
732         let mut ser_bound = Attr::none(cx, "bound");
733         let mut de_bound = Attr::none(cx, "bound");
734         let mut borrowed_lifetimes = Attr::none(cx, "borrow");
735         let mut getter = Attr::none(cx, "getter");
736 
737         let ident = match field.ident {
738             Some(ref ident) => ident.to_string(),
739             None => index.to_string(),
740         };
741 
742         let variant_borrow = attrs
743             .map(|variant| &variant.borrow)
744             .unwrap_or(&None)
745             .as_ref()
746             .map(|borrow| vec![MetaItem(borrow.clone())]);
747 
748         for meta_items in field
749             .attrs
750             .iter()
751             .filter_map(get_serde_meta_items)
752             .chain(variant_borrow)
753         {
754             for meta_item in meta_items {
755                 match meta_item {
756                     // Parse `#[serde(rename = "foo")]`
757                     MetaItem(NameValue(ref name, ref lit)) if name == "rename" => {
758                         if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
759                             ser_name.set(s.clone());
760                             de_name.set(s);
761                         }
762                     }
763 
764                     // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
765                     MetaItem(List(ref name, ref meta_items)) if name == "rename" => {
766                         if let Ok((ser, de)) = get_renames(cx, meta_items) {
767                             ser_name.set_opt(ser);
768                             de_name.set_opt(de);
769                         }
770                     }
771 
772                     // Parse `#[serde(default)]`
773                     MetaItem(Word(ref name)) if name == "default" => {
774                         default.set(Default::Default);
775                     }
776 
777                     // Parse `#[serde(default = "...")]`
778                     MetaItem(NameValue(ref name, ref lit)) if name == "default" => {
779                         if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
780                             default.set(Default::Path(path));
781                         }
782                     }
783 
784                     // Parse `#[serde(skip_serializing)]`
785                     MetaItem(Word(ref name)) if name == "skip_serializing" => {
786                         skip_serializing.set_true();
787                     }
788 
789                     // Parse `#[serde(skip_deserializing)]`
790                     MetaItem(Word(ref name)) if name == "skip_deserializing" => {
791                         skip_deserializing.set_true();
792                     }
793 
794                     // Parse `#[serde(skip)]`
795                     MetaItem(Word(ref name)) if name == "skip" => {
796                         skip_serializing.set_true();
797                         skip_deserializing.set_true();
798                     }
799 
800                     // Parse `#[serde(skip_serializing_if = "...")]`
801                     MetaItem(NameValue(ref name, ref lit)) if name == "skip_serializing_if" => {
802                         if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
803                             skip_serializing_if.set(path);
804                         }
805                     }
806 
807                     // Parse `#[serde(serialize_with = "...")]`
808                     MetaItem(NameValue(ref name, ref lit)) if name == "serialize_with" => {
809                         if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
810                             serialize_with.set(path);
811                         }
812                     }
813 
814                     // Parse `#[serde(deserialize_with = "...")]`
815                     MetaItem(NameValue(ref name, ref lit)) if name == "deserialize_with" => {
816                         if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
817                             deserialize_with.set(path);
818                         }
819                     }
820 
821                     // Parse `#[serde(with = "...")]`
822                     MetaItem(NameValue(ref name, ref lit)) if name == "with" => {
823                         if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
824                             let mut ser_path = path.clone();
825                             ser_path.segments.push("serialize".into());
826                             serialize_with.set(ser_path);
827                             let mut de_path = path;
828                             de_path.segments.push("deserialize".into());
829                             deserialize_with.set(de_path);
830                         }
831                     }
832 
833                     // Parse `#[serde(bound = "D: Serialize")]`
834                     MetaItem(NameValue(ref name, ref lit)) if name == "bound" => {
835                         if let Ok(where_predicates) =
836                             parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit)
837                         {
838                             ser_bound.set(where_predicates.clone());
839                             de_bound.set(where_predicates);
840                         }
841                     }
842 
843                     // Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]`
844                     MetaItem(List(ref name, ref meta_items)) if name == "bound" => {
845                         if let Ok((ser, de)) = get_where_predicates(cx, meta_items) {
846                             ser_bound.set_opt(ser);
847                             de_bound.set_opt(de);
848                         }
849                     }
850 
851                     // Parse `#[serde(borrow)]`
852                     MetaItem(Word(ref name)) if name == "borrow" => {
853                         if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, &field.ty) {
854                             borrowed_lifetimes.set(borrowable);
855                         }
856                     }
857 
858                     // Parse `#[serde(borrow = "'a + 'b")]`
859                     MetaItem(NameValue(ref name, ref lit)) if name == "borrow" => {
860                         if let Ok(lifetimes) = parse_lit_into_lifetimes(cx, name.as_ref(), lit) {
861                             if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, &field.ty) {
862                                 for lifetime in &lifetimes {
863                                     if !borrowable.contains(lifetime) {
864                                         cx.error(format!(
865                                             "field `{}` does not have lifetime {}",
866                                             ident, lifetime.ident
867                                         ));
868                                     }
869                                 }
870                                 borrowed_lifetimes.set(lifetimes);
871                             }
872                         }
873                     }
874 
875                     // Parse `#[serde(getter = "...")]`
876                     MetaItem(NameValue(ref name, ref lit)) if name == "getter" => {
877                         if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
878                             getter.set(path);
879                         }
880                     }
881 
882                     MetaItem(ref meta_item) => {
883                         cx.error(format!(
884                             "unknown serde field attribute `{}`",
885                             meta_item.name()
886                         ));
887                     }
888 
889                     Literal(_) => {
890                         cx.error("unexpected literal in serde field attribute");
891                     }
892                 }
893             }
894         }
895 
896         // Is skip_deserializing, initialize the field to Default::default() unless a different
897         // default is specified by `#[serde(default = "...")]` on ourselves or our container (e.g.
898         // the struct we are in).
899         if container_default == &Default::None && skip_deserializing.0.value.is_some() {
900             default.set_if_none(Default::Default);
901         }
902 
903         let mut borrowed_lifetimes = borrowed_lifetimes.get().unwrap_or_default();
904         if !borrowed_lifetimes.is_empty() {
905             // Cow<str> and Cow<[u8]> never borrow by default:
906             //
907             //     impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T>
908             //
909             // A #[serde(borrow)] attribute enables borrowing that corresponds
910             // roughly to these impls:
911             //
912             //     impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, str>
913             //     impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, [u8]>
914             if is_cow(&field.ty, "str") {
915                 let path = syn::parse_path("_serde::private::de::borrow_cow_str").unwrap();
916                 deserialize_with.set_if_none(path);
917             } else if is_cow(&field.ty, "[u8]") {
918                 let path = syn::parse_path("_serde::private::de::borrow_cow_bytes").unwrap();
919                 deserialize_with.set_if_none(path);
920             }
921         } else if is_rptr(&field.ty, "str") || is_rptr(&field.ty, "[u8]") {
922             // Types &str and &[u8] are always implicitly borrowed. No need for
923             // a #[serde(borrow)].
924             borrowed_lifetimes = borrowable_lifetimes(cx, &ident, &field.ty).unwrap();
925         }
926 
927         let ser_name = ser_name.get();
928         let ser_renamed = ser_name.is_some();
929         let de_name = de_name.get();
930         let de_renamed = de_name.is_some();
931         Field {
932             name: Name {
933                 serialize: ser_name.unwrap_or_else(|| ident.clone()),
934                 deserialize: de_name.unwrap_or(ident),
935             },
936             ser_renamed: ser_renamed,
937             de_renamed: de_renamed,
938             skip_serializing: skip_serializing.get(),
939             skip_deserializing: skip_deserializing.get(),
940             skip_serializing_if: skip_serializing_if.get(),
941             default: default.get().unwrap_or(Default::None),
942             serialize_with: serialize_with.get(),
943             deserialize_with: deserialize_with.get(),
944             ser_bound: ser_bound.get(),
945             de_bound: de_bound.get(),
946             borrowed_lifetimes: borrowed_lifetimes,
947             getter: getter.get(),
948         }
949     }
950 
name(&self) -> &Name951     pub fn name(&self) -> &Name {
952         &self.name
953     }
954 
rename_by_rule(&mut self, rule: &RenameRule)955     pub fn rename_by_rule(&mut self, rule: &RenameRule) {
956         if !self.ser_renamed {
957             self.name.serialize = rule.apply_to_field(&self.name.serialize);
958         }
959         if !self.de_renamed {
960             self.name.deserialize = rule.apply_to_field(&self.name.deserialize);
961         }
962     }
963 
skip_serializing(&self) -> bool964     pub fn skip_serializing(&self) -> bool {
965         self.skip_serializing
966     }
967 
skip_deserializing(&self) -> bool968     pub fn skip_deserializing(&self) -> bool {
969         self.skip_deserializing
970     }
971 
skip_serializing_if(&self) -> Option<&syn::Path>972     pub fn skip_serializing_if(&self) -> Option<&syn::Path> {
973         self.skip_serializing_if.as_ref()
974     }
975 
default(&self) -> &Default976     pub fn default(&self) -> &Default {
977         &self.default
978     }
979 
serialize_with(&self) -> Option<&syn::Path>980     pub fn serialize_with(&self) -> Option<&syn::Path> {
981         self.serialize_with.as_ref()
982     }
983 
deserialize_with(&self) -> Option<&syn::Path>984     pub fn deserialize_with(&self) -> Option<&syn::Path> {
985         self.deserialize_with.as_ref()
986     }
987 
ser_bound(&self) -> Option<&[syn::WherePredicate]>988     pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
989         self.ser_bound.as_ref().map(|vec| &vec[..])
990     }
991 
de_bound(&self) -> Option<&[syn::WherePredicate]>992     pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
993         self.de_bound.as_ref().map(|vec| &vec[..])
994     }
995 
borrowed_lifetimes(&self) -> &BTreeSet<syn::Lifetime>996     pub fn borrowed_lifetimes(&self) -> &BTreeSet<syn::Lifetime> {
997         &self.borrowed_lifetimes
998     }
999 
getter(&self) -> Option<&syn::Path>1000     pub fn getter(&self) -> Option<&syn::Path> {
1001         self.getter.as_ref()
1002     }
1003 }
1004 
1005 type SerAndDe<T> = (Option<T>, Option<T>);
1006 
get_ser_and_de<T, F>( cx: &Ctxt, attr_name: &'static str, items: &[syn::NestedMetaItem], f: F, ) -> Result<SerAndDe<T>, ()> where F: Fn(&Ctxt, &str, &str, &syn::Lit) -> Result<T, ()>,1007 fn get_ser_and_de<T, F>(
1008     cx: &Ctxt,
1009     attr_name: &'static str,
1010     items: &[syn::NestedMetaItem],
1011     f: F,
1012 ) -> Result<SerAndDe<T>, ()>
1013 where
1014     F: Fn(&Ctxt, &str, &str, &syn::Lit) -> Result<T, ()>,
1015 {
1016     let mut ser_item = Attr::none(cx, attr_name);
1017     let mut de_item = Attr::none(cx, attr_name);
1018 
1019     for item in items {
1020         match *item {
1021             MetaItem(NameValue(ref name, ref lit)) if name == "serialize" => {
1022                 if let Ok(v) = f(cx, attr_name, name.as_ref(), lit) {
1023                     ser_item.set(v);
1024                 }
1025             }
1026 
1027             MetaItem(NameValue(ref name, ref lit)) if name == "deserialize" => {
1028                 if let Ok(v) = f(cx, attr_name, name.as_ref(), lit) {
1029                     de_item.set(v);
1030                 }
1031             }
1032 
1033             _ => {
1034                 cx.error(format!(
1035                     "malformed {0} attribute, expected `{0}(serialize = ..., \
1036                      deserialize = ...)`",
1037                     attr_name
1038                 ));
1039                 return Err(());
1040             }
1041         }
1042     }
1043 
1044     Ok((ser_item.get(), de_item.get()))
1045 }
1046 
get_renames(cx: &Ctxt, items: &[syn::NestedMetaItem]) -> Result<SerAndDe<String>, ()>1047 fn get_renames(cx: &Ctxt, items: &[syn::NestedMetaItem]) -> Result<SerAndDe<String>, ()> {
1048     get_ser_and_de(cx, "rename", items, get_string_from_lit)
1049 }
1050 
get_where_predicates( cx: &Ctxt, items: &[syn::NestedMetaItem], ) -> Result<SerAndDe<Vec<syn::WherePredicate>>, ()>1051 fn get_where_predicates(
1052     cx: &Ctxt,
1053     items: &[syn::NestedMetaItem],
1054 ) -> Result<SerAndDe<Vec<syn::WherePredicate>>, ()> {
1055     get_ser_and_de(cx, "bound", items, parse_lit_into_where)
1056 }
1057 
get_serde_meta_items(attr: &syn::Attribute) -> Option<Vec<syn::NestedMetaItem>>1058 pub fn get_serde_meta_items(attr: &syn::Attribute) -> Option<Vec<syn::NestedMetaItem>> {
1059     match attr.value {
1060         List(ref name, ref items) if name == "serde" => Some(items.iter().cloned().collect()),
1061         _ => None,
1062     }
1063 }
1064 
get_string_from_lit( cx: &Ctxt, attr_name: &str, meta_item_name: &str, lit: &syn::Lit, ) -> Result<String, ()>1065 fn get_string_from_lit(
1066     cx: &Ctxt,
1067     attr_name: &str,
1068     meta_item_name: &str,
1069     lit: &syn::Lit,
1070 ) -> Result<String, ()> {
1071     if let syn::Lit::Str(ref s, _) = *lit {
1072         Ok(s.clone())
1073     } else {
1074         cx.error(format!(
1075             "expected serde {} attribute to be a string: `{} = \"...\"`",
1076             attr_name, meta_item_name
1077         ));
1078         Err(())
1079     }
1080 }
1081 
parse_lit_into_path(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result<syn::Path, ()>1082 fn parse_lit_into_path(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result<syn::Path, ()> {
1083     let string = try!(get_string_from_lit(cx, attr_name, attr_name, lit));
1084     syn::parse_path(&string).map_err(|err| cx.error(err))
1085 }
1086 
parse_lit_into_where( cx: &Ctxt, attr_name: &str, meta_item_name: &str, lit: &syn::Lit, ) -> Result<Vec<syn::WherePredicate>, ()>1087 fn parse_lit_into_where(
1088     cx: &Ctxt,
1089     attr_name: &str,
1090     meta_item_name: &str,
1091     lit: &syn::Lit,
1092 ) -> Result<Vec<syn::WherePredicate>, ()> {
1093     let string = try!(get_string_from_lit(cx, attr_name, meta_item_name, lit));
1094     if string.is_empty() {
1095         return Ok(Vec::new());
1096     }
1097 
1098     let where_string = format!("where {}", string);
1099 
1100     syn::parse_where_clause(&where_string)
1101         .map(|wh| wh.predicates)
1102         .map_err(|err| cx.error(err))
1103 }
1104 
parse_lit_into_ty(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result<syn::Ty, ()>1105 fn parse_lit_into_ty(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result<syn::Ty, ()> {
1106     let string = try!(get_string_from_lit(cx, attr_name, attr_name, lit));
1107 
1108     syn::parse_type(&string).map_err(|_| {
1109         cx.error(format!(
1110             "failed to parse type: {} = {:?}",
1111             attr_name, string
1112         ))
1113     })
1114 }
1115 
1116 // Parses a string literal like "'a + 'b + 'c" containing a nonempty list of
1117 // lifetimes separated by `+`.
parse_lit_into_lifetimes( cx: &Ctxt, attr_name: &str, lit: &syn::Lit, ) -> Result<BTreeSet<syn::Lifetime>, ()>1118 fn parse_lit_into_lifetimes(
1119     cx: &Ctxt,
1120     attr_name: &str,
1121     lit: &syn::Lit,
1122 ) -> Result<BTreeSet<syn::Lifetime>, ()> {
1123     let string = try!(get_string_from_lit(cx, attr_name, attr_name, lit));
1124     if string.is_empty() {
1125         cx.error("at least one lifetime must be borrowed");
1126         return Err(());
1127     }
1128 
1129     named!(lifetimes -> Vec<syn::Lifetime>,
1130         separated_nonempty_list!(punct!("+"), syn::parse::lifetime)
1131     );
1132 
1133     if let IResult::Done(rest, o) = lifetimes(&string) {
1134         if rest.trim().is_empty() {
1135             let mut set = BTreeSet::new();
1136             for lifetime in o {
1137                 if !set.insert(lifetime.clone()) {
1138                     cx.error(format!("duplicate borrowed lifetime `{}`", lifetime.ident));
1139                 }
1140             }
1141             return Ok(set);
1142         }
1143     }
1144     Err(cx.error(format!("failed to parse borrowed lifetimes: {:?}", string)))
1145 }
1146 
1147 // Whether the type looks like it might be `std::borrow::Cow<T>` where elem="T".
1148 // This can have false negatives and false positives.
1149 //
1150 // False negative:
1151 //
1152 //     use std::borrow::Cow as Pig;
1153 //
1154 //     #[derive(Deserialize)]
1155 //     struct S<'a> {
1156 //         #[serde(borrow)]
1157 //         pig: Pig<'a, str>,
1158 //     }
1159 //
1160 // False positive:
1161 //
1162 //     type str = [i16];
1163 //
1164 //     #[derive(Deserialize)]
1165 //     struct S<'a> {
1166 //         #[serde(borrow)]
1167 //         cow: Cow<'a, str>,
1168 //     }
is_cow(ty: &syn::Ty, elem: &str) -> bool1169 fn is_cow(ty: &syn::Ty, elem: &str) -> bool {
1170     let path = match *ty {
1171         syn::Ty::Path(None, ref path) => path,
1172         _ => {
1173             return false;
1174         }
1175     };
1176     let seg = match path.segments.last() {
1177         Some(seg) => seg,
1178         None => {
1179             return false;
1180         }
1181     };
1182     let params = match seg.parameters {
1183         syn::PathParameters::AngleBracketed(ref params) => params,
1184         _ => {
1185             return false;
1186         }
1187     };
1188     seg.ident == "Cow" && params.lifetimes.len() == 1
1189         && params.types == vec![syn::parse_type(elem).unwrap()] && params.bindings.is_empty()
1190 }
1191 
1192 // Whether the type looks like it might be `&T` where elem="T". This can have
1193 // false negatives and false positives.
1194 //
1195 // False negative:
1196 //
1197 //     type Yarn = str;
1198 //
1199 //     #[derive(Deserialize)]
1200 //     struct S<'a> {
1201 //         r: &'a Yarn,
1202 //     }
1203 //
1204 // False positive:
1205 //
1206 //     type str = [i16];
1207 //
1208 //     #[derive(Deserialize)]
1209 //     struct S<'a> {
1210 //         r: &'a str,
1211 //     }
is_rptr(ty: &syn::Ty, elem: &str) -> bool1212 fn is_rptr(ty: &syn::Ty, elem: &str) -> bool {
1213     match *ty {
1214         syn::Ty::Rptr(Some(_), ref mut_ty) => {
1215             mut_ty.mutability == syn::Mutability::Immutable
1216                 && mut_ty.ty == syn::parse_type(elem).unwrap()
1217         }
1218         _ => false,
1219     }
1220 }
1221 
1222 // All lifetimes that this type could borrow from a Deserializer.
1223 //
1224 // For example a type `S<'a, 'b>` could borrow `'a` and `'b`. On the other hand
1225 // a type `for<'a> fn(&'a str)` could not borrow `'a` from the Deserializer.
1226 //
1227 // This is used when there is an explicit or implicit `#[serde(borrow)]`
1228 // attribute on the field so there must be at least one borrowable lifetime.
borrowable_lifetimes( cx: &Ctxt, name: &str, ty: &syn::Ty, ) -> Result<BTreeSet<syn::Lifetime>, ()>1229 fn borrowable_lifetimes(
1230     cx: &Ctxt,
1231     name: &str,
1232     ty: &syn::Ty,
1233 ) -> Result<BTreeSet<syn::Lifetime>, ()> {
1234     let mut lifetimes = BTreeSet::new();
1235     collect_lifetimes(ty, &mut lifetimes);
1236     if lifetimes.is_empty() {
1237         Err(cx.error(format!("field `{}` has no lifetimes to borrow", name)))
1238     } else {
1239         Ok(lifetimes)
1240     }
1241 }
1242 
collect_lifetimes(ty: &syn::Ty, out: &mut BTreeSet<syn::Lifetime>)1243 fn collect_lifetimes(ty: &syn::Ty, out: &mut BTreeSet<syn::Lifetime>) {
1244     match *ty {
1245         syn::Ty::Slice(ref elem) | syn::Ty::Array(ref elem, _) | syn::Ty::Paren(ref elem) => {
1246             collect_lifetimes(elem, out);
1247         }
1248         syn::Ty::Ptr(ref elem) => {
1249             collect_lifetimes(&elem.ty, out);
1250         }
1251         syn::Ty::Rptr(ref lifetime, ref elem) => {
1252             out.extend(lifetime.iter().cloned());
1253             collect_lifetimes(&elem.ty, out);
1254         }
1255         syn::Ty::Tup(ref elems) => for elem in elems {
1256             collect_lifetimes(elem, out);
1257         },
1258         syn::Ty::Path(ref qself, ref path) => {
1259             if let Some(ref qself) = *qself {
1260                 collect_lifetimes(&qself.ty, out);
1261             }
1262             for seg in &path.segments {
1263                 if let syn::PathParameters::AngleBracketed(ref params) = seg.parameters {
1264                     out.extend(params.lifetimes.iter().cloned());
1265                     for ty in &params.types {
1266                         collect_lifetimes(ty, out);
1267                     }
1268                     for binding in &params.bindings {
1269                         collect_lifetimes(&binding.ty, out);
1270                     }
1271                 }
1272             }
1273         }
1274         syn::Ty::BareFn(_)
1275         | syn::Ty::Never
1276         | syn::Ty::TraitObject(_)
1277         | syn::Ty::ImplTrait(_)
1278         | syn::Ty::Infer
1279         | syn::Ty::Mac(_) => {}
1280     }
1281 }
1282