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 ¶ms.types {
1266 collect_lifetimes(ty, out);
1267 }
1268 for binding in ¶ms.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