]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/attr/builtin.rs
Rollup merge of #52019 - michaelwoerister:cross-lto-auto-plugin, r=alexcrichton
[rust.git] / src / libsyntax / attr / builtin.rs
1 // Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Parsing and validation of builtin attributes
12
13 use ast::{self, Attribute, MetaItem, Name, NestedMetaItemKind};
14 use errors::{Applicability, Handler};
15 use feature_gate::{Features, GatedCfg};
16 use parse::ParseSess;
17 use syntax_pos::{symbol::Symbol, Span};
18
19 use super::{list_contains_name, mark_used, MetaItemKind};
20
21 enum AttrError {
22     MultipleItem(Name),
23     UnknownMetaItem(Name, &'static [&'static str]),
24     MissingSince,
25     MissingFeature,
26     MultipleStabilityLevels,
27     UnsupportedLiteral
28 }
29
30 fn handle_errors(diag: &Handler, span: Span, error: AttrError) {
31     match error {
32         AttrError::MultipleItem(item) => span_err!(diag, span, E0538,
33                                                    "multiple '{}' items", item),
34         AttrError::UnknownMetaItem(item, expected) => {
35             let expected = expected
36                 .iter()
37                 .map(|name| format!("`{}`", name))
38                 .collect::<Vec<_>>();
39             struct_span_err!(diag, span, E0541, "unknown meta item '{}'", item)
40                 .span_label(span, format!("expected one of {}", expected.join(", ")))
41                 .emit();
42         }
43         AttrError::MissingSince => span_err!(diag, span, E0542, "missing 'since'"),
44         AttrError::MissingFeature => span_err!(diag, span, E0546, "missing 'feature'"),
45         AttrError::MultipleStabilityLevels => span_err!(diag, span, E0544,
46                                                         "multiple stability levels"),
47         AttrError::UnsupportedLiteral => span_err!(diag, span, E0565, "unsupported literal"),
48     }
49 }
50
51 #[derive(Copy, Clone, Hash, PartialEq, RustcEncodable, RustcDecodable)]
52 pub enum InlineAttr {
53     None,
54     Hint,
55     Always,
56     Never,
57 }
58
59 #[derive(Copy, Clone, PartialEq)]
60 pub enum UnwindAttr {
61     Allowed,
62     Aborts,
63 }
64
65 /// Determine what `#[unwind]` attribute is present in `attrs`, if any.
66 pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Option<UnwindAttr> {
67     let syntax_error = |attr: &Attribute| {
68         mark_used(attr);
69         diagnostic.map(|d| {
70             span_err!(d, attr.span, E0633, "malformed `#[unwind]` attribute");
71         });
72         None
73     };
74
75     attrs.iter().fold(None, |ia, attr| {
76         if attr.path != "unwind" {
77             return ia;
78         }
79         let meta = match attr.meta() {
80             Some(meta) => meta.node,
81             None => return ia,
82         };
83         match meta {
84             MetaItemKind::Word => {
85                 syntax_error(attr)
86             }
87             MetaItemKind::List(ref items) => {
88                 mark_used(attr);
89                 if items.len() != 1 {
90                     syntax_error(attr)
91                 } else if list_contains_name(&items[..], "allowed") {
92                     Some(UnwindAttr::Allowed)
93                 } else if list_contains_name(&items[..], "aborts") {
94                     Some(UnwindAttr::Aborts)
95                 } else {
96                     syntax_error(attr)
97                 }
98             }
99             _ => ia,
100         }
101     })
102 }
103
104 /// Represents the #[stable], #[unstable], #[rustc_{deprecated,const_unstable}] attributes.
105 #[derive(RustcEncodable, RustcDecodable, Clone, Debug, PartialEq, Eq, Hash)]
106 pub struct Stability {
107     pub level: StabilityLevel,
108     pub feature: Symbol,
109     pub rustc_depr: Option<RustcDeprecation>,
110     pub rustc_const_unstable: Option<RustcConstUnstable>,
111 }
112
113 /// The available stability levels.
114 #[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
115 pub enum StabilityLevel {
116     // Reason for the current stability level and the relevant rust-lang issue
117     Unstable { reason: Option<Symbol>, issue: u32 },
118     Stable { since: Symbol },
119 }
120
121 impl StabilityLevel {
122     pub fn is_unstable(&self) -> bool {
123         if let StabilityLevel::Unstable {..} = *self {
124             true
125         } else {
126             false
127         }
128     }
129     pub fn is_stable(&self) -> bool {
130         if let StabilityLevel::Stable {..} = *self {
131             true
132         } else {
133             false
134         }
135     }
136 }
137
138 #[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
139 pub struct RustcDeprecation {
140     pub since: Symbol,
141     pub reason: Symbol,
142 }
143
144 #[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
145 pub struct RustcConstUnstable {
146     pub feature: Symbol,
147 }
148
149 /// Check if `attrs` contains an attribute like `#![feature(feature_name)]`.
150 /// This will not perform any "sanity checks" on the form of the attributes.
151 pub fn contains_feature_attr(attrs: &[Attribute], feature_name: &str) -> bool {
152     attrs.iter().any(|item| {
153         item.check_name("feature") &&
154         item.meta_item_list().map(|list| {
155             list.iter().any(|mi| {
156                 mi.word().map(|w| w.name() == feature_name)
157                          .unwrap_or(false)
158             })
159         }).unwrap_or(false)
160     })
161 }
162
163 /// Find the first stability attribute. `None` if none exists.
164 pub fn find_stability(diagnostic: &Handler, attrs: &[Attribute],
165                       item_sp: Span) -> Option<Stability> {
166     find_stability_generic(diagnostic, attrs.iter(), item_sp)
167 }
168
169 fn find_stability_generic<'a, I>(diagnostic: &Handler,
170                                  attrs_iter: I,
171                                  item_sp: Span)
172                                  -> Option<Stability>
173     where I: Iterator<Item = &'a Attribute>
174 {
175     use self::StabilityLevel::*;
176
177     let mut stab: Option<Stability> = None;
178     let mut rustc_depr: Option<RustcDeprecation> = None;
179     let mut rustc_const_unstable: Option<RustcConstUnstable> = None;
180
181     'outer: for attr in attrs_iter {
182         if ![
183             "rustc_deprecated",
184             "rustc_const_unstable",
185             "unstable",
186             "stable",
187         ].iter().any(|&s| attr.path == s) {
188             continue // not a stability level
189         }
190
191         mark_used(attr);
192
193         let meta = attr.meta();
194         if let Some(MetaItem { node: MetaItemKind::List(ref metas), .. }) = meta {
195             let meta = meta.as_ref().unwrap();
196             let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
197                 if item.is_some() {
198                     handle_errors(diagnostic, meta.span, AttrError::MultipleItem(meta.name()));
199                     return false
200                 }
201                 if let Some(v) = meta.value_str() {
202                     *item = Some(v);
203                     true
204                 } else {
205                     span_err!(diagnostic, meta.span, E0539, "incorrect meta item");
206                     false
207                 }
208             };
209
210             macro_rules! get_meta {
211                 ($($name:ident),+) => {
212                     $(
213                         let mut $name = None;
214                     )+
215                     for meta in metas {
216                         if let Some(mi) = meta.meta_item() {
217                             match &*mi.name().as_str() {
218                                 $(
219                                     stringify!($name)
220                                         => if !get(mi, &mut $name) { continue 'outer },
221                                 )+
222                                 _ => {
223                                     let expected = &[ $( stringify!($name) ),+ ];
224                                     handle_errors(
225                                         diagnostic,
226                                         mi.span,
227                                         AttrError::UnknownMetaItem(mi.name(), expected));
228                                     continue 'outer
229                                 }
230                             }
231                         } else {
232                             handle_errors(diagnostic, meta.span, AttrError::UnsupportedLiteral);
233                             continue 'outer
234                         }
235                     }
236                 }
237             }
238
239             match &*meta.name().as_str() {
240                 "rustc_deprecated" => {
241                     if rustc_depr.is_some() {
242                         span_err!(diagnostic, item_sp, E0540,
243                                   "multiple rustc_deprecated attributes");
244                         continue 'outer
245                     }
246
247                     get_meta!(since, reason);
248
249                     match (since, reason) {
250                         (Some(since), Some(reason)) => {
251                             rustc_depr = Some(RustcDeprecation {
252                                 since,
253                                 reason,
254                             })
255                         }
256                         (None, _) => {
257                             handle_errors(diagnostic, attr.span(), AttrError::MissingSince);
258                             continue
259                         }
260                         _ => {
261                             span_err!(diagnostic, attr.span(), E0543, "missing 'reason'");
262                             continue
263                         }
264                     }
265                 }
266                 "rustc_const_unstable" => {
267                     if rustc_const_unstable.is_some() {
268                         span_err!(diagnostic, item_sp, E0553,
269                                   "multiple rustc_const_unstable attributes");
270                         continue 'outer
271                     }
272
273                     get_meta!(feature);
274                     if let Some(feature) = feature {
275                         rustc_const_unstable = Some(RustcConstUnstable {
276                             feature
277                         });
278                     } else {
279                         span_err!(diagnostic, attr.span(), E0629, "missing 'feature'");
280                         continue
281                     }
282                 }
283                 "unstable" => {
284                     if stab.is_some() {
285                         handle_errors(diagnostic, attr.span(), AttrError::MultipleStabilityLevels);
286                         break
287                     }
288
289                     let mut feature = None;
290                     let mut reason = None;
291                     let mut issue = None;
292                     for meta in metas {
293                         if let Some(mi) = meta.meta_item() {
294                             match &*mi.name().as_str() {
295                                 "feature" => if !get(mi, &mut feature) { continue 'outer },
296                                 "reason" => if !get(mi, &mut reason) { continue 'outer },
297                                 "issue" => if !get(mi, &mut issue) { continue 'outer },
298                                 _ => {
299                                     handle_errors(
300                                         diagnostic,
301                                         meta.span,
302                                         AttrError::UnknownMetaItem(
303                                             mi.name(),
304                                             &["feature", "reason", "issue"]
305                                         ),
306                                     );
307                                     continue 'outer
308                                 }
309                             }
310                         } else {
311                             handle_errors(diagnostic, meta.span, AttrError::UnsupportedLiteral);
312                             continue 'outer
313                         }
314                     }
315
316                     match (feature, reason, issue) {
317                         (Some(feature), reason, Some(issue)) => {
318                             stab = Some(Stability {
319                                 level: Unstable {
320                                     reason,
321                                     issue: {
322                                         if let Ok(issue) = issue.as_str().parse() {
323                                             issue
324                                         } else {
325                                             span_err!(diagnostic, attr.span(), E0545,
326                                                       "incorrect 'issue'");
327                                             continue
328                                         }
329                                     }
330                                 },
331                                 feature,
332                                 rustc_depr: None,
333                                 rustc_const_unstable: None,
334                             })
335                         }
336                         (None, _, _) => {
337                             handle_errors(diagnostic, attr.span(), AttrError::MissingFeature);
338                             continue
339                         }
340                         _ => {
341                             span_err!(diagnostic, attr.span(), E0547, "missing 'issue'");
342                             continue
343                         }
344                     }
345                 }
346                 "stable" => {
347                     if stab.is_some() {
348                         handle_errors(diagnostic, attr.span(), AttrError::MultipleStabilityLevels);
349                         break
350                     }
351
352                     let mut feature = None;
353                     let mut since = None;
354                     for meta in metas {
355                         if let NestedMetaItemKind::MetaItem(ref mi) = meta.node {
356                             match &*mi.name().as_str() {
357                                 "feature" => if !get(mi, &mut feature) { continue 'outer },
358                                 "since" => if !get(mi, &mut since) { continue 'outer },
359                                 _ => {
360                                     handle_errors(
361                                         diagnostic,
362                                         meta.span,
363                                         AttrError::UnknownMetaItem(mi.name(), &["since", "note"]),
364                                     );
365                                     continue 'outer
366                                 }
367                             }
368                         } else {
369                             handle_errors(diagnostic, meta.span, AttrError::UnsupportedLiteral);
370                             continue 'outer
371                         }
372                     }
373
374                     match (feature, since) {
375                         (Some(feature), Some(since)) => {
376                             stab = Some(Stability {
377                                 level: Stable {
378                                     since,
379                                 },
380                                 feature,
381                                 rustc_depr: None,
382                                 rustc_const_unstable: None,
383                             })
384                         }
385                         (None, _) => {
386                             handle_errors(diagnostic, attr.span(), AttrError::MissingFeature);
387                             continue
388                         }
389                         _ => {
390                             handle_errors(diagnostic, attr.span(), AttrError::MissingSince);
391                             continue
392                         }
393                     }
394                 }
395                 _ => unreachable!()
396             }
397         } else {
398             span_err!(diagnostic, attr.span(), E0548, "incorrect stability attribute type");
399             continue
400         }
401     }
402
403     // Merge the deprecation info into the stability info
404     if let Some(rustc_depr) = rustc_depr {
405         if let Some(ref mut stab) = stab {
406             stab.rustc_depr = Some(rustc_depr);
407         } else {
408             span_err!(diagnostic, item_sp, E0549,
409                       "rustc_deprecated attribute must be paired with \
410                        either stable or unstable attribute");
411         }
412     }
413
414     // Merge the const-unstable info into the stability info
415     if let Some(rustc_const_unstable) = rustc_const_unstable {
416         if let Some(ref mut stab) = stab {
417             stab.rustc_const_unstable = Some(rustc_const_unstable);
418         } else {
419             span_err!(diagnostic, item_sp, E0630,
420                       "rustc_const_unstable attribute must be paired with \
421                        either stable or unstable attribute");
422         }
423     }
424
425     stab
426 }
427
428 pub fn find_crate_name(attrs: &[Attribute]) -> Option<Symbol> {
429     super::first_attr_value_str_by_name(attrs, "crate_name")
430 }
431
432 /// Tests if a cfg-pattern matches the cfg set
433 pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Features>) -> bool {
434     eval_condition(cfg, sess, &mut |cfg| {
435         if let (Some(feats), Some(gated_cfg)) = (features, GatedCfg::gate(cfg)) {
436             gated_cfg.check_and_emit(sess, feats);
437         }
438         sess.config.contains(&(cfg.name(), cfg.value_str()))
439     })
440 }
441
442 /// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to
443 /// evaluate individual items.
444 pub fn eval_condition<F>(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F)
445                          -> bool
446     where F: FnMut(&ast::MetaItem) -> bool
447 {
448     match cfg.node {
449         ast::MetaItemKind::List(ref mis) => {
450             for mi in mis.iter() {
451                 if !mi.is_meta_item() {
452                     handle_errors(&sess.span_diagnostic, mi.span, AttrError::UnsupportedLiteral);
453                     return false;
454                 }
455             }
456
457             // The unwraps below may look dangerous, but we've already asserted
458             // that they won't fail with the loop above.
459             match &*cfg.name().as_str() {
460                 "any" => mis.iter().any(|mi| {
461                     eval_condition(mi.meta_item().unwrap(), sess, eval)
462                 }),
463                 "all" => mis.iter().all(|mi| {
464                     eval_condition(mi.meta_item().unwrap(), sess, eval)
465                 }),
466                 "not" => {
467                     if mis.len() != 1 {
468                         span_err!(sess.span_diagnostic, cfg.span, E0536, "expected 1 cfg-pattern");
469                         return false;
470                     }
471
472                     !eval_condition(mis[0].meta_item().unwrap(), sess, eval)
473                 },
474                 p => {
475                     span_err!(sess.span_diagnostic, cfg.span, E0537, "invalid predicate `{}`", p);
476                     false
477                 }
478             }
479         },
480         ast::MetaItemKind::Word | ast::MetaItemKind::NameValue(..) => {
481             eval(cfg)
482         }
483     }
484 }
485
486
487 #[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
488 pub struct Deprecation {
489     pub since: Option<Symbol>,
490     pub note: Option<Symbol>,
491 }
492
493 /// Find the deprecation attribute. `None` if none exists.
494 pub fn find_deprecation(diagnostic: &Handler, attrs: &[Attribute],
495                         item_sp: Span) -> Option<Deprecation> {
496     find_deprecation_generic(diagnostic, attrs.iter(), item_sp)
497 }
498
499 fn find_deprecation_generic<'a, I>(diagnostic: &Handler,
500                                    attrs_iter: I,
501                                    item_sp: Span)
502                                    -> Option<Deprecation>
503     where I: Iterator<Item = &'a Attribute>
504 {
505     let mut depr: Option<Deprecation> = None;
506
507     'outer: for attr in attrs_iter {
508         if attr.path != "deprecated" {
509             continue
510         }
511
512         mark_used(attr);
513
514         if depr.is_some() {
515             span_err!(diagnostic, item_sp, E0550, "multiple deprecated attributes");
516             break
517         }
518
519         depr = if let Some(metas) = attr.meta_item_list() {
520             let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
521                 if item.is_some() {
522                     handle_errors(diagnostic, meta.span, AttrError::MultipleItem(meta.name()));
523                     return false
524                 }
525                 if let Some(v) = meta.value_str() {
526                     *item = Some(v);
527                     true
528                 } else {
529                     span_err!(diagnostic, meta.span, E0551, "incorrect meta item");
530                     false
531                 }
532             };
533
534             let mut since = None;
535             let mut note = None;
536             for meta in metas {
537                 if let NestedMetaItemKind::MetaItem(ref mi) = meta.node {
538                     match &*mi.name().as_str() {
539                         "since" => if !get(mi, &mut since) { continue 'outer },
540                         "note" => if !get(mi, &mut note) { continue 'outer },
541                         _ => {
542                             handle_errors(
543                                 diagnostic,
544                                 meta.span,
545                                 AttrError::UnknownMetaItem(mi.name(), &["since", "note"]),
546                             );
547                             continue 'outer
548                         }
549                     }
550                 } else {
551                     handle_errors(diagnostic, meta.span, AttrError::UnsupportedLiteral);
552                     continue 'outer
553                 }
554             }
555
556             Some(Deprecation {since: since, note: note})
557         } else {
558             Some(Deprecation{since: None, note: None})
559         }
560     }
561
562     depr
563 }
564
565 #[derive(PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone)]
566 pub enum ReprAttr {
567     ReprInt(IntType),
568     ReprC,
569     ReprPacked(u32),
570     ReprSimd,
571     ReprTransparent,
572     ReprAlign(u32),
573 }
574
575 #[derive(Eq, Hash, PartialEq, Debug, RustcEncodable, RustcDecodable, Copy, Clone)]
576 pub enum IntType {
577     SignedInt(ast::IntTy),
578     UnsignedInt(ast::UintTy)
579 }
580
581 impl IntType {
582     #[inline]
583     pub fn is_signed(self) -> bool {
584         use self::IntType::*;
585
586         match self {
587             SignedInt(..) => true,
588             UnsignedInt(..) => false
589         }
590     }
591 }
592
593 /// Parse #[repr(...)] forms.
594 ///
595 /// Valid repr contents: any of the primitive integral type names (see
596 /// `int_type_of_word`, below) to specify enum discriminant type; `C`, to use
597 /// the same discriminant size that the corresponding C enum would or C
598 /// structure layout, `packed` to remove padding, and `transparent` to elegate representation
599 /// concerns to the only non-ZST field.
600 pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr> {
601     use self::ReprAttr::*;
602
603     let mut acc = Vec::new();
604     if attr.path == "repr" {
605         if let Some(items) = attr.meta_item_list() {
606             mark_used(attr);
607             for item in items {
608                 if !item.is_meta_item() {
609                     handle_errors(diagnostic, item.span, AttrError::UnsupportedLiteral);
610                     continue
611                 }
612
613                 let mut recognised = false;
614                 if let Some(mi) = item.word() {
615                     let word = &*mi.name().as_str();
616                     let hint = match word {
617                         "C" => Some(ReprC),
618                         "packed" => Some(ReprPacked(1)),
619                         "simd" => Some(ReprSimd),
620                         "transparent" => Some(ReprTransparent),
621                         _ => match int_type_of_word(word) {
622                             Some(ity) => Some(ReprInt(ity)),
623                             None => {
624                                 None
625                             }
626                         }
627                     };
628
629                     if let Some(h) = hint {
630                         recognised = true;
631                         acc.push(h);
632                     }
633                 } else if let Some((name, value)) = item.name_value_literal() {
634                     let parse_alignment = |node: &ast::LitKind| -> Result<u32, &'static str> {
635                         if let ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed) = node {
636                             if literal.is_power_of_two() {
637                                 // rustc::ty::layout::Align restricts align to <= 2^29
638                                 if *literal <= 1 << 29 {
639                                     Ok(*literal as u32)
640                                 } else {
641                                     Err("larger than 2^29")
642                                 }
643                             } else {
644                                 Err("not a power of two")
645                             }
646                         } else {
647                             Err("not an unsuffixed integer")
648                         }
649                     };
650
651                     let mut literal_error = None;
652                     if name == "align" {
653                         recognised = true;
654                         match parse_alignment(&value.node) {
655                             Ok(literal) => acc.push(ReprAlign(literal)),
656                             Err(message) => literal_error = Some(message)
657                         };
658                     }
659                     else if name == "packed" {
660                         recognised = true;
661                         match parse_alignment(&value.node) {
662                             Ok(literal) => acc.push(ReprPacked(literal)),
663                             Err(message) => literal_error = Some(message)
664                         };
665                     }
666                     if let Some(literal_error) = literal_error {
667                         span_err!(diagnostic, item.span, E0589,
668                                   "invalid `repr(align)` attribute: {}", literal_error);
669                     }
670                 } else {
671                     if let Some(meta_item) = item.meta_item() {
672                         if meta_item.name() == "align" {
673                             if let MetaItemKind::NameValue(ref value) = meta_item.node {
674                                 recognised = true;
675                                 let mut err = struct_span_err!(diagnostic, item.span, E0693,
676                                     "incorrect `repr(align)` attribute format");
677                                 match value.node {
678                                     ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
679                                         err.span_suggestion_with_applicability(
680                                             item.span,
681                                             "use parentheses instead",
682                                             format!("align({})", int),
683                                             Applicability::MachineApplicable
684                                         );
685                                     }
686                                     ast::LitKind::Str(s, _) => {
687                                         err.span_suggestion_with_applicability(
688                                             item.span,
689                                             "use parentheses instead",
690                                             format!("align({})", s),
691                                             Applicability::MachineApplicable
692                                         );
693                                     }
694                                     _ => {}
695                                 }
696                                 err.emit();
697                             }
698                         }
699                     }
700                 }
701                 if !recognised {
702                     // Not a word we recognize
703                     span_err!(diagnostic, item.span, E0552,
704                               "unrecognized representation hint");
705                 }
706             }
707         }
708     }
709     acc
710 }
711
712 fn int_type_of_word(s: &str) -> Option<IntType> {
713     use self::IntType::*;
714
715     match s {
716         "i8" => Some(SignedInt(ast::IntTy::I8)),
717         "u8" => Some(UnsignedInt(ast::UintTy::U8)),
718         "i16" => Some(SignedInt(ast::IntTy::I16)),
719         "u16" => Some(UnsignedInt(ast::UintTy::U16)),
720         "i32" => Some(SignedInt(ast::IntTy::I32)),
721         "u32" => Some(UnsignedInt(ast::UintTy::U32)),
722         "i64" => Some(SignedInt(ast::IntTy::I64)),
723         "u64" => Some(UnsignedInt(ast::UintTy::U64)),
724         "i128" => Some(SignedInt(ast::IntTy::I128)),
725         "u128" => Some(UnsignedInt(ast::UintTy::U128)),
726         "isize" => Some(SignedInt(ast::IntTy::Isize)),
727         "usize" => Some(UnsignedInt(ast::UintTy::Usize)),
728         _ => None
729     }
730 }