]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/ast.rs
Fix invalid associated type rendering in rustdoc
[rust.git] / src / libsyntax / ast.rs
1 // Copyright 2012-2014 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 // The Rust abstract syntax tree.
12
13 pub use self::TyParamBound::*;
14 pub use self::UnsafeSource::*;
15 pub use self::ViewPath_::*;
16 pub use self::PathParameters::*;
17 pub use symbol::{Ident, Symbol as Name};
18 pub use util::ThinVec;
19
20 use syntax_pos::{Span, DUMMY_SP};
21 use codemap::{respan, Spanned};
22 use abi::Abi;
23 use ext::hygiene::{Mark, SyntaxContext};
24 use print::pprust;
25 use ptr::P;
26 use rustc_data_structures::indexed_vec;
27 use symbol::{Symbol, keywords};
28 use tokenstream::{ThinTokenStream, TokenStream};
29
30 use serialize::{self, Encoder, Decoder};
31 use std::collections::HashSet;
32 use std::fmt;
33 use std::rc::Rc;
34 use std::u32;
35
36 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
37 pub struct Lifetime {
38     pub id: NodeId,
39     pub span: Span,
40     pub name: Name
41 }
42
43 impl fmt::Debug for Lifetime {
44     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
45         write!(f, "lifetime({}: {})", self.id, pprust::lifetime_to_string(self))
46     }
47 }
48
49 /// A lifetime definition, e.g. `'a: 'b+'c+'d`
50 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
51 pub struct LifetimeDef {
52     pub attrs: ThinVec<Attribute>,
53     pub lifetime: Lifetime,
54     pub bounds: Vec<Lifetime>
55 }
56
57 /// A "Path" is essentially Rust's notion of a name.
58 ///
59 /// It's represented as a sequence of identifiers,
60 /// along with a bunch of supporting information.
61 ///
62 /// E.g. `std::cmp::PartialEq`
63 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
64 pub struct Path {
65     pub span: Span,
66     /// The segments in the path: the things separated by `::`.
67     /// Global paths begin with `keywords::CrateRoot`.
68     pub segments: Vec<PathSegment>,
69 }
70
71 impl<'a> PartialEq<&'a str> for Path {
72     fn eq(&self, string: &&'a str) -> bool {
73         self.segments.len() == 1 && self.segments[0].identifier.name == *string
74     }
75 }
76
77 impl fmt::Debug for Path {
78     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
79         write!(f, "path({})", pprust::path_to_string(self))
80     }
81 }
82
83 impl fmt::Display for Path {
84     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
85         write!(f, "{}", pprust::path_to_string(self))
86     }
87 }
88
89 impl Path {
90     // convert a span and an identifier to the corresponding
91     // 1-segment path
92     pub fn from_ident(s: Span, identifier: Ident) -> Path {
93         Path {
94             span: s,
95             segments: vec![PathSegment::from_ident(identifier, s)],
96         }
97     }
98
99     pub fn default_to_global(mut self) -> Path {
100         let name = self.segments[0].identifier.name;
101         if !self.is_global() && name != "$crate" &&
102            name != keywords::SelfValue.name() && name != keywords::Super.name() {
103             self.segments.insert(0, PathSegment::crate_root());
104         }
105         self
106     }
107
108     pub fn is_global(&self) -> bool {
109         !self.segments.is_empty() && self.segments[0].identifier.name == keywords::CrateRoot.name()
110     }
111 }
112
113 /// A segment of a path: an identifier, an optional lifetime, and a set of types.
114 ///
115 /// E.g. `std`, `String` or `Box<T>`
116 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
117 pub struct PathSegment {
118     /// The identifier portion of this path segment.
119     pub identifier: Ident,
120     /// Span of the segment identifier.
121     pub span: Span,
122
123     /// Type/lifetime parameters attached to this path. They come in
124     /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
125     /// this is more than just simple syntactic sugar; the use of
126     /// parens affects the region binding rules, so we preserve the
127     /// distinction.
128     /// The `Option<P<..>>` wrapper is purely a size optimization;
129     /// `None` is used to represent both `Path` and `Path<>`.
130     pub parameters: Option<P<PathParameters>>,
131 }
132
133 impl PathSegment {
134     pub fn from_ident(ident: Ident, span: Span) -> Self {
135         PathSegment { identifier: ident, span: span, parameters: None }
136     }
137     pub fn crate_root() -> Self {
138         PathSegment {
139             identifier: keywords::CrateRoot.ident(),
140             span: DUMMY_SP,
141             parameters: None,
142         }
143     }
144 }
145
146 /// Parameters of a path segment.
147 ///
148 /// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`
149 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
150 pub enum PathParameters {
151     /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>`
152     AngleBracketed(AngleBracketedParameterData),
153     /// The `(A,B)` and `C` in `Foo(A,B) -> C`
154     Parenthesized(ParenthesizedParameterData),
155 }
156
157 /// A path like `Foo<'a, T>`
158 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Default)]
159 pub struct AngleBracketedParameterData {
160     /// The lifetime parameters for this path segment.
161     pub lifetimes: Vec<Lifetime>,
162     /// The type parameters for this path segment, if present.
163     pub types: Vec<P<Ty>>,
164     /// Bindings (equality constraints) on associated types, if present.
165     ///
166     /// E.g., `Foo<A=Bar>`.
167     pub bindings: Vec<TypeBinding>,
168 }
169
170 impl Into<Option<P<PathParameters>>> for AngleBracketedParameterData {
171     fn into(self) -> Option<P<PathParameters>> {
172         let empty = self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty();
173         if empty { None } else { Some(P(PathParameters::AngleBracketed(self))) }
174     }
175 }
176
177 /// A path like `Foo(A,B) -> C`
178 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
179 pub struct ParenthesizedParameterData {
180     /// Overall span
181     pub span: Span,
182
183     /// `(A,B)`
184     pub inputs: Vec<P<Ty>>,
185
186     /// `C`
187     pub output: Option<P<Ty>>,
188 }
189
190 #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
191 pub struct NodeId(u32);
192
193 impl NodeId {
194     pub fn new(x: usize) -> NodeId {
195         assert!(x < (u32::MAX as usize));
196         NodeId(x as u32)
197     }
198
199     pub fn from_u32(x: u32) -> NodeId {
200         NodeId(x)
201     }
202
203     pub fn as_usize(&self) -> usize {
204         self.0 as usize
205     }
206
207     pub fn as_u32(&self) -> u32 {
208         self.0
209     }
210
211     pub fn placeholder_from_mark(mark: Mark) -> Self {
212         NodeId(mark.as_u32())
213     }
214
215     pub fn placeholder_to_mark(self) -> Mark {
216         Mark::from_u32(self.0)
217     }
218 }
219
220 impl fmt::Display for NodeId {
221     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
222         fmt::Display::fmt(&self.0, f)
223     }
224 }
225
226 impl serialize::UseSpecializedEncodable for NodeId {
227     fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
228         s.emit_u32(self.0)
229     }
230 }
231
232 impl serialize::UseSpecializedDecodable for NodeId {
233     fn default_decode<D: Decoder>(d: &mut D) -> Result<NodeId, D::Error> {
234         d.read_u32().map(NodeId)
235     }
236 }
237
238 impl indexed_vec::Idx for NodeId {
239     fn new(idx: usize) -> Self {
240         NodeId::new(idx)
241     }
242
243     fn index(self) -> usize {
244         self.as_usize()
245     }
246 }
247
248 /// Node id used to represent the root of the crate.
249 pub const CRATE_NODE_ID: NodeId = NodeId(0);
250
251 /// When parsing and doing expansions, we initially give all AST nodes this AST
252 /// node value. Then later, in the renumber pass, we renumber them to have
253 /// small, positive ids.
254 pub const DUMMY_NODE_ID: NodeId = NodeId(!0);
255
256 /// The AST represents all type param bounds as types.
257 /// typeck::collect::compute_bounds matches these against
258 /// the "special" built-in traits (see middle::lang_items) and
259 /// detects Copy, Send and Sync.
260 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
261 pub enum TyParamBound {
262     TraitTyParamBound(PolyTraitRef, TraitBoundModifier),
263     RegionTyParamBound(Lifetime)
264 }
265
266 /// A modifier on a bound, currently this is only used for `?Sized`, where the
267 /// modifier is `Maybe`. Negative bounds should also be handled here.
268 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
269 pub enum TraitBoundModifier {
270     None,
271     Maybe,
272 }
273
274 pub type TyParamBounds = Vec<TyParamBound>;
275
276 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
277 pub struct TyParam {
278     pub attrs: ThinVec<Attribute>,
279     pub ident: Ident,
280     pub id: NodeId,
281     pub bounds: TyParamBounds,
282     pub default: Option<P<Ty>>,
283     pub span: Span,
284 }
285
286 /// Represents lifetimes and type parameters attached to a declaration
287 /// of a function, enum, trait, etc.
288 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
289 pub struct Generics {
290     pub lifetimes: Vec<LifetimeDef>,
291     pub ty_params: Vec<TyParam>,
292     pub where_clause: WhereClause,
293     pub span: Span,
294 }
295
296 impl Generics {
297     pub fn is_lt_parameterized(&self) -> bool {
298         !self.lifetimes.is_empty()
299     }
300     pub fn is_type_parameterized(&self) -> bool {
301         !self.ty_params.is_empty()
302     }
303     pub fn is_parameterized(&self) -> bool {
304         self.is_lt_parameterized() || self.is_type_parameterized()
305     }
306     pub fn span_for_name(&self, name: &str) -> Option<Span> {
307         for t in &self.ty_params {
308             if t.ident.name == name {
309                 return Some(t.span);
310             }
311         }
312         None
313     }
314 }
315
316 impl Default for Generics {
317     /// Creates an instance of `Generics`.
318     fn default() ->  Generics {
319         Generics {
320             lifetimes: Vec::new(),
321             ty_params: Vec::new(),
322             where_clause: WhereClause {
323                 id: DUMMY_NODE_ID,
324                 predicates: Vec::new(),
325             },
326             span: DUMMY_SP,
327         }
328     }
329 }
330
331 /// A `where` clause in a definition
332 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
333 pub struct WhereClause {
334     pub id: NodeId,
335     pub predicates: Vec<WherePredicate>,
336 }
337
338 /// A single predicate in a `where` clause
339 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
340 pub enum WherePredicate {
341     /// A type binding, e.g. `for<'c> Foo: Send+Clone+'c`
342     BoundPredicate(WhereBoundPredicate),
343     /// A lifetime predicate, e.g. `'a: 'b+'c`
344     RegionPredicate(WhereRegionPredicate),
345     /// An equality predicate (unsupported)
346     EqPredicate(WhereEqPredicate),
347 }
348
349 /// A type bound.
350 ///
351 /// E.g. `for<'c> Foo: Send+Clone+'c`
352 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
353 pub struct WhereBoundPredicate {
354     pub span: Span,
355     /// Any lifetimes from a `for` binding
356     pub bound_lifetimes: Vec<LifetimeDef>,
357     /// The type being bounded
358     pub bounded_ty: P<Ty>,
359     /// Trait and lifetime bounds (`Clone+Send+'static`)
360     pub bounds: TyParamBounds,
361 }
362
363 /// A lifetime predicate.
364 ///
365 /// E.g. `'a: 'b+'c`
366 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
367 pub struct WhereRegionPredicate {
368     pub span: Span,
369     pub lifetime: Lifetime,
370     pub bounds: Vec<Lifetime>,
371 }
372
373 /// An equality predicate (unsupported).
374 ///
375 /// E.g. `T=int`
376 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
377 pub struct WhereEqPredicate {
378     pub id: NodeId,
379     pub span: Span,
380     pub lhs_ty: P<Ty>,
381     pub rhs_ty: P<Ty>,
382 }
383
384 /// The set of MetaItems that define the compilation environment of the crate,
385 /// used to drive conditional compilation
386 pub type CrateConfig = HashSet<(Name, Option<Symbol>)>;
387
388 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
389 pub struct Crate {
390     pub module: Mod,
391     pub attrs: Vec<Attribute>,
392     pub span: Span,
393 }
394
395 /// A spanned compile-time attribute list item.
396 pub type NestedMetaItem = Spanned<NestedMetaItemKind>;
397
398 /// Possible values inside of compile-time attribute lists.
399 ///
400 /// E.g. the '..' in `#[name(..)]`.
401 #[derive(Clone, Eq, RustcEncodable, RustcDecodable, Hash, Debug, PartialEq)]
402 pub enum NestedMetaItemKind {
403     /// A full MetaItem, for recursive meta items.
404     MetaItem(MetaItem),
405     /// A literal.
406     ///
407     /// E.g. "foo", 64, true
408     Literal(Lit),
409 }
410
411 /// A spanned compile-time attribute item.
412 ///
413 /// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
414 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
415 pub struct MetaItem {
416     pub name: Name,
417     pub node: MetaItemKind,
418     pub span: Span,
419 }
420
421 /// A compile-time attribute item.
422 ///
423 /// E.g. `#[test]`, `#[derive(..)]` or `#[feature = "foo"]`
424 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
425 pub enum MetaItemKind {
426     /// Word meta item.
427     ///
428     /// E.g. `test` as in `#[test]`
429     Word,
430     /// List meta item.
431     ///
432     /// E.g. `derive(..)` as in `#[derive(..)]`
433     List(Vec<NestedMetaItem>),
434     /// Name value meta item.
435     ///
436     /// E.g. `feature = "foo"` as in `#[feature = "foo"]`
437     NameValue(Lit)
438 }
439
440 /// A Block (`{ .. }`).
441 ///
442 /// E.g. `{ .. }` as in `fn foo() { .. }`
443 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
444 pub struct Block {
445     /// Statements in a block
446     pub stmts: Vec<Stmt>,
447     pub id: NodeId,
448     /// Distinguishes between `unsafe { ... }` and `{ ... }`
449     pub rules: BlockCheckMode,
450     pub span: Span,
451 }
452
453 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
454 pub struct Pat {
455     pub id: NodeId,
456     pub node: PatKind,
457     pub span: Span,
458 }
459
460 impl fmt::Debug for Pat {
461     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
462         write!(f, "pat({}: {})", self.id, pprust::pat_to_string(self))
463     }
464 }
465
466 impl Pat {
467     pub fn walk<F>(&self, it: &mut F) -> bool
468         where F: FnMut(&Pat) -> bool
469     {
470         if !it(self) {
471             return false;
472         }
473
474         match self.node {
475             PatKind::Ident(_, _, Some(ref p)) => p.walk(it),
476             PatKind::Struct(_, ref fields, _) => {
477                 fields.iter().all(|field| field.node.pat.walk(it))
478             }
479             PatKind::TupleStruct(_, ref s, _) | PatKind::Tuple(ref s, _) => {
480                 s.iter().all(|p| p.walk(it))
481             }
482             PatKind::Box(ref s) | PatKind::Ref(ref s, _) => {
483                 s.walk(it)
484             }
485             PatKind::Slice(ref before, ref slice, ref after) => {
486                 before.iter().all(|p| p.walk(it)) &&
487                 slice.iter().all(|p| p.walk(it)) &&
488                 after.iter().all(|p| p.walk(it))
489             }
490             PatKind::Wild |
491             PatKind::Lit(_) |
492             PatKind::Range(..) |
493             PatKind::Ident(..) |
494             PatKind::Path(..) |
495             PatKind::Mac(_) => {
496                 true
497             }
498         }
499     }
500 }
501
502 /// A single field in a struct pattern
503 ///
504 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
505 /// are treated the same as` x: x, y: ref y, z: ref mut z`,
506 /// except is_shorthand is true
507 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
508 pub struct FieldPat {
509     /// The identifier for the field
510     pub ident: Ident,
511     /// The pattern the field is destructured to
512     pub pat: P<Pat>,
513     pub is_shorthand: bool,
514     pub attrs: ThinVec<Attribute>,
515 }
516
517 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
518 pub enum BindingMode {
519     ByRef(Mutability),
520     ByValue(Mutability),
521 }
522
523 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
524 pub enum RangeEnd {
525     Included,
526     Excluded,
527 }
528
529 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
530 pub enum PatKind {
531     /// Represents a wildcard pattern (`_`)
532     Wild,
533
534     /// A `PatKind::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
535     /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
536     /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
537     /// during name resolution.
538     Ident(BindingMode, SpannedIdent, Option<P<Pat>>),
539
540     /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
541     /// The `bool` is `true` in the presence of a `..`.
542     Struct(Path, Vec<Spanned<FieldPat>>, bool),
543
544     /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
545     /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
546     /// 0 <= position <= subpats.len()
547     TupleStruct(Path, Vec<P<Pat>>, Option<usize>),
548
549     /// A possibly qualified path pattern.
550     /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
551     /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
552     /// only legally refer to associated constants.
553     Path(Option<QSelf>, Path),
554
555     /// A tuple pattern `(a, b)`.
556     /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
557     /// 0 <= position <= subpats.len()
558     Tuple(Vec<P<Pat>>, Option<usize>),
559     /// A `box` pattern
560     Box(P<Pat>),
561     /// A reference pattern, e.g. `&mut (a, b)`
562     Ref(P<Pat>, Mutability),
563     /// A literal
564     Lit(P<Expr>),
565     /// A range pattern, e.g. `1...2` or `1..2`
566     Range(P<Expr>, P<Expr>, RangeEnd),
567     /// `[a, b, ..i, y, z]` is represented as:
568     ///     `PatKind::Slice(box [a, b], Some(i), box [y, z])`
569     Slice(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
570     /// A macro pattern; pre-expansion
571     Mac(Mac),
572 }
573
574 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
575 pub enum Mutability {
576     Mutable,
577     Immutable,
578 }
579
580 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
581 pub enum BinOpKind {
582     /// The `+` operator (addition)
583     Add,
584     /// The `-` operator (subtraction)
585     Sub,
586     /// The `*` operator (multiplication)
587     Mul,
588     /// The `/` operator (division)
589     Div,
590     /// The `%` operator (modulus)
591     Rem,
592     /// The `&&` operator (logical and)
593     And,
594     /// The `||` operator (logical or)
595     Or,
596     /// The `^` operator (bitwise xor)
597     BitXor,
598     /// The `&` operator (bitwise and)
599     BitAnd,
600     /// The `|` operator (bitwise or)
601     BitOr,
602     /// The `<<` operator (shift left)
603     Shl,
604     /// The `>>` operator (shift right)
605     Shr,
606     /// The `==` operator (equality)
607     Eq,
608     /// The `<` operator (less than)
609     Lt,
610     /// The `<=` operator (less than or equal to)
611     Le,
612     /// The `!=` operator (not equal to)
613     Ne,
614     /// The `>=` operator (greater than or equal to)
615     Ge,
616     /// The `>` operator (greater than)
617     Gt,
618 }
619
620 impl BinOpKind {
621     pub fn to_string(&self) -> &'static str {
622         use self::BinOpKind::*;
623         match *self {
624             Add => "+",
625             Sub => "-",
626             Mul => "*",
627             Div => "/",
628             Rem => "%",
629             And => "&&",
630             Or => "||",
631             BitXor => "^",
632             BitAnd => "&",
633             BitOr => "|",
634             Shl => "<<",
635             Shr => ">>",
636             Eq => "==",
637             Lt => "<",
638             Le => "<=",
639             Ne => "!=",
640             Ge => ">=",
641             Gt => ">",
642         }
643     }
644     pub fn lazy(&self) -> bool {
645         match *self {
646             BinOpKind::And | BinOpKind::Or => true,
647             _ => false
648         }
649     }
650
651     pub fn is_shift(&self) -> bool {
652         match *self {
653             BinOpKind::Shl | BinOpKind::Shr => true,
654             _ => false
655         }
656     }
657     pub fn is_comparison(&self) -> bool {
658         use self::BinOpKind::*;
659         match *self {
660             Eq | Lt | Le | Ne | Gt | Ge =>
661             true,
662             And | Or | Add | Sub | Mul | Div | Rem |
663             BitXor | BitAnd | BitOr | Shl | Shr =>
664             false,
665         }
666     }
667     /// Returns `true` if the binary operator takes its arguments by value
668     pub fn is_by_value(&self) -> bool {
669         !self.is_comparison()
670     }
671 }
672
673 pub type BinOp = Spanned<BinOpKind>;
674
675 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
676 pub enum UnOp {
677     /// The `*` operator for dereferencing
678     Deref,
679     /// The `!` operator for logical inversion
680     Not,
681     /// The `-` operator for negation
682     Neg,
683 }
684
685 impl UnOp {
686     /// Returns `true` if the unary operator takes its argument by value
687     pub fn is_by_value(u: UnOp) -> bool {
688         match u {
689             UnOp::Neg | UnOp::Not => true,
690             _ => false,
691         }
692     }
693
694     pub fn to_string(op: UnOp) -> &'static str {
695         match op {
696             UnOp::Deref => "*",
697             UnOp::Not => "!",
698             UnOp::Neg => "-",
699         }
700     }
701 }
702
703 /// A statement
704 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
705 pub struct Stmt {
706     pub id: NodeId,
707     pub node: StmtKind,
708     pub span: Span,
709 }
710
711 impl Stmt {
712     pub fn add_trailing_semicolon(mut self) -> Self {
713         self.node = match self.node {
714             StmtKind::Expr(expr) => StmtKind::Semi(expr),
715             StmtKind::Mac(mac) => StmtKind::Mac(mac.map(|(mac, _style, attrs)| {
716                 (mac, MacStmtStyle::Semicolon, attrs)
717             })),
718             node @ _ => node,
719         };
720         self
721     }
722 }
723
724 impl fmt::Debug for Stmt {
725     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
726         write!(f, "stmt({}: {})", self.id.to_string(), pprust::stmt_to_string(self))
727     }
728 }
729
730
731 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
732 pub enum StmtKind {
733     /// A local (let) binding.
734     Local(P<Local>),
735
736     /// An item definition.
737     Item(P<Item>),
738
739     /// Expr without trailing semi-colon.
740     Expr(P<Expr>),
741
742     Semi(P<Expr>),
743
744     Mac(P<(Mac, MacStmtStyle, ThinVec<Attribute>)>),
745 }
746
747 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
748 pub enum MacStmtStyle {
749     /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
750     /// `foo!(...);`, `foo![...];`
751     Semicolon,
752     /// The macro statement had braces; e.g. foo! { ... }
753     Braces,
754     /// The macro statement had parentheses or brackets and no semicolon; e.g.
755     /// `foo!(...)`. All of these will end up being converted into macro
756     /// expressions.
757     NoBraces,
758 }
759
760 // FIXME (pending discussion of #1697, #2178...): local should really be
761 // a refinement on pat.
762 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
763 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
764 pub struct Local {
765     pub pat: P<Pat>,
766     pub ty: Option<P<Ty>>,
767     /// Initializer expression to set the value, if any
768     pub init: Option<P<Expr>>,
769     pub id: NodeId,
770     pub span: Span,
771     pub attrs: ThinVec<Attribute>,
772 }
773
774 /// An arm of a 'match'.
775 ///
776 /// E.g. `0...10 => { println!("match!") }` as in
777 ///
778 /// ```rust,ignore
779 /// match n {
780 ///     0...10 => { println!("match!") },
781 ///     // ..
782 /// }
783 /// ```
784 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
785 pub struct Arm {
786     pub attrs: Vec<Attribute>,
787     pub pats: Vec<P<Pat>>,
788     pub guard: Option<P<Expr>>,
789     pub body: P<Expr>,
790 }
791
792 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
793 pub struct Field {
794     pub ident: SpannedIdent,
795     pub expr: P<Expr>,
796     pub span: Span,
797     pub is_shorthand: bool,
798     pub attrs: ThinVec<Attribute>,
799 }
800
801 pub type SpannedIdent = Spanned<Ident>;
802
803 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
804 pub enum BlockCheckMode {
805     Default,
806     Unsafe(UnsafeSource),
807 }
808
809 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
810 pub enum UnsafeSource {
811     CompilerGenerated,
812     UserProvided,
813 }
814
815 /// An expression
816 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash,)]
817 pub struct Expr {
818     pub id: NodeId,
819     pub node: ExprKind,
820     pub span: Span,
821     pub attrs: ThinVec<Attribute>
822 }
823
824 impl fmt::Debug for Expr {
825     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
826         write!(f, "expr({}: {})", self.id, pprust::expr_to_string(self))
827     }
828 }
829
830 /// Limit types of a range (inclusive or exclusive)
831 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
832 pub enum RangeLimits {
833     /// Inclusive at the beginning, exclusive at the end
834     HalfOpen,
835     /// Inclusive at the beginning and end
836     Closed,
837 }
838
839 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
840 pub enum ExprKind {
841     /// A `box x` expression.
842     Box(P<Expr>),
843     /// First expr is the place; second expr is the value.
844     InPlace(P<Expr>, P<Expr>),
845     /// An array (`[a, b, c, d]`)
846     Array(Vec<P<Expr>>),
847     /// A function call
848     ///
849     /// The first field resolves to the function itself,
850     /// and the second field is the list of arguments
851     Call(P<Expr>, Vec<P<Expr>>),
852     /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
853     ///
854     /// The `SpannedIdent` is the identifier for the method name.
855     /// The vector of `Ty`s are the ascripted type parameters for the method
856     /// (within the angle brackets).
857     ///
858     /// The first element of the vector of `Expr`s is the expression that evaluates
859     /// to the object on which the method is being called on (the receiver),
860     /// and the remaining elements are the rest of the arguments.
861     ///
862     /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
863     /// `ExprKind::MethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
864     MethodCall(SpannedIdent, Vec<P<Ty>>, Vec<P<Expr>>),
865     /// A tuple (`(a, b, c ,d)`)
866     Tup(Vec<P<Expr>>),
867     /// A binary operation (For example: `a + b`, `a * b`)
868     Binary(BinOp, P<Expr>, P<Expr>),
869     /// A unary operation (For example: `!x`, `*x`)
870     Unary(UnOp, P<Expr>),
871     /// A literal (For example: `1`, `"foo"`)
872     Lit(P<Lit>),
873     /// A cast (`foo as f64`)
874     Cast(P<Expr>, P<Ty>),
875     Type(P<Expr>, P<Ty>),
876     /// An `if` block, with an optional else block
877     ///
878     /// `if expr { block } else { expr }`
879     If(P<Expr>, P<Block>, Option<P<Expr>>),
880     /// An `if let` expression with an optional else block
881     ///
882     /// `if let pat = expr { block } else { expr }`
883     ///
884     /// This is desugared to a `match` expression.
885     IfLet(P<Pat>, P<Expr>, P<Block>, Option<P<Expr>>),
886     /// A while loop, with an optional label
887     ///
888     /// `'label: while expr { block }`
889     While(P<Expr>, P<Block>, Option<SpannedIdent>),
890     /// A while-let loop, with an optional label
891     ///
892     /// `'label: while let pat = expr { block }`
893     ///
894     /// This is desugared to a combination of `loop` and `match` expressions.
895     WhileLet(P<Pat>, P<Expr>, P<Block>, Option<SpannedIdent>),
896     /// A for loop, with an optional label
897     ///
898     /// `'label: for pat in expr { block }`
899     ///
900     /// This is desugared to a combination of `loop` and `match` expressions.
901     ForLoop(P<Pat>, P<Expr>, P<Block>, Option<SpannedIdent>),
902     /// Conditionless loop (can be exited with break, continue, or return)
903     ///
904     /// `'label: loop { block }`
905     Loop(P<Block>, Option<SpannedIdent>),
906     /// A `match` block.
907     Match(P<Expr>, Vec<Arm>),
908     /// A closure (for example, `move |a, b, c| a + b + c`)
909     ///
910     /// The final span is the span of the argument block `|...|`
911     Closure(CaptureBy, P<FnDecl>, P<Expr>, Span),
912     /// A block (`{ ... }`)
913     Block(P<Block>),
914     /// A catch block (`catch { ... }`)
915     Catch(P<Block>),
916
917     /// An assignment (`a = foo()`)
918     Assign(P<Expr>, P<Expr>),
919     /// An assignment with an operator
920     ///
921     /// For example, `a += 1`.
922     AssignOp(BinOp, P<Expr>, P<Expr>),
923     /// Access of a named struct field (`obj.foo`)
924     Field(P<Expr>, SpannedIdent),
925     /// Access of an unnamed field of a struct or tuple-struct
926     ///
927     /// For example, `foo.0`.
928     TupField(P<Expr>, Spanned<usize>),
929     /// An indexing operation (`foo[2]`)
930     Index(P<Expr>, P<Expr>),
931     /// A range (`1..2`, `1..`, `..2`, `1...2`, `1...`, `...2`)
932     Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
933
934     /// Variable reference, possibly containing `::` and/or type
935     /// parameters, e.g. foo::bar::<baz>.
936     ///
937     /// Optionally "qualified",
938     /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
939     Path(Option<QSelf>, Path),
940
941     /// A referencing operation (`&a` or `&mut a`)
942     AddrOf(Mutability, P<Expr>),
943     /// A `break`, with an optional label to break, and an optional expression
944     Break(Option<SpannedIdent>, Option<P<Expr>>),
945     /// A `continue`, with an optional label
946     Continue(Option<SpannedIdent>),
947     /// A `return`, with an optional value to be returned
948     Ret(Option<P<Expr>>),
949
950     /// Output of the `asm!()` macro
951     InlineAsm(P<InlineAsm>),
952
953     /// A macro invocation; pre-expansion
954     Mac(Mac),
955
956     /// A struct literal expression.
957     ///
958     /// For example, `Foo {x: 1, y: 2}`, or
959     /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
960     Struct(Path, Vec<Field>, Option<P<Expr>>),
961
962     /// An array literal constructed from one repeated element.
963     ///
964     /// For example, `[1; 5]`. The first expression is the element
965     /// to be repeated; the second is the number of times to repeat it.
966     Repeat(P<Expr>, P<Expr>),
967
968     /// No-op: used solely so we can pretty-print faithfully
969     Paren(P<Expr>),
970
971     /// `expr?`
972     Try(P<Expr>),
973 }
974
975 /// The explicit Self type in a "qualified path". The actual
976 /// path, including the trait and the associated item, is stored
977 /// separately. `position` represents the index of the associated
978 /// item qualified with this Self type.
979 ///
980 /// ```rust,ignore
981 /// <Vec<T> as a::b::Trait>::AssociatedItem
982 ///  ^~~~~     ~~~~~~~~~~~~~~^
983 ///  ty        position = 3
984 ///
985 /// <Vec<T>>::AssociatedItem
986 ///  ^~~~~    ^
987 ///  ty       position = 0
988 /// ```
989 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
990 pub struct QSelf {
991     pub ty: P<Ty>,
992     pub position: usize
993 }
994
995 /// A capture clause
996 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
997 pub enum CaptureBy {
998     Value,
999     Ref,
1000 }
1001
1002 pub type Mac = Spanned<Mac_>;
1003
1004 /// Represents a macro invocation. The Path indicates which macro
1005 /// is being invoked, and the vector of token-trees contains the source
1006 /// of the macro invocation.
1007 ///
1008 /// NB: the additional ident for a macro_rules-style macro is actually
1009 /// stored in the enclosing item. Oog.
1010 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1011 pub struct Mac_ {
1012     pub path: Path,
1013     pub tts: ThinTokenStream,
1014 }
1015
1016 impl Mac_ {
1017     pub fn stream(&self) -> TokenStream {
1018         self.tts.clone().into()
1019     }
1020 }
1021
1022 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1023 pub enum StrStyle {
1024     /// A regular string, like `"foo"`
1025     Cooked,
1026     /// A raw string, like `r##"foo"##`
1027     ///
1028     /// The uint is the number of `#` symbols used
1029     Raw(usize)
1030 }
1031
1032 /// A literal
1033 pub type Lit = Spanned<LitKind>;
1034
1035 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1036 pub enum LitIntType {
1037     Signed(IntTy),
1038     Unsigned(UintTy),
1039     Unsuffixed,
1040 }
1041
1042 /// Literal kind.
1043 ///
1044 /// E.g. `"foo"`, `42`, `12.34` or `bool`
1045 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1046 pub enum LitKind {
1047     /// A string literal (`"foo"`)
1048     Str(Symbol, StrStyle),
1049     /// A byte string (`b"foo"`)
1050     ByteStr(Rc<Vec<u8>>),
1051     /// A byte char (`b'f'`)
1052     Byte(u8),
1053     /// A character literal (`'a'`)
1054     Char(char),
1055     /// An integer literal (`1`)
1056     Int(u128, LitIntType),
1057     /// A float literal (`1f64` or `1E10f64`)
1058     Float(Symbol, FloatTy),
1059     /// A float literal without a suffix (`1.0 or 1.0E10`)
1060     FloatUnsuffixed(Symbol),
1061     /// A boolean literal
1062     Bool(bool),
1063 }
1064
1065 impl LitKind {
1066     /// Returns true if this literal is a string and false otherwise.
1067     pub fn is_str(&self) -> bool {
1068         match *self {
1069             LitKind::Str(..) => true,
1070             _ => false,
1071         }
1072     }
1073
1074     /// Returns true if this literal has no suffix. Note: this will return true
1075     /// for literals with prefixes such as raw strings and byte strings.
1076     pub fn is_unsuffixed(&self) -> bool {
1077         match *self {
1078             // unsuffixed variants
1079             LitKind::Str(..) => true,
1080             LitKind::ByteStr(..) => true,
1081             LitKind::Byte(..) => true,
1082             LitKind::Char(..) => true,
1083             LitKind::Int(_, LitIntType::Unsuffixed) => true,
1084             LitKind::FloatUnsuffixed(..) => true,
1085             LitKind::Bool(..) => true,
1086             // suffixed variants
1087             LitKind::Int(_, LitIntType::Signed(..)) => false,
1088             LitKind::Int(_, LitIntType::Unsigned(..)) => false,
1089             LitKind::Float(..) => false,
1090         }
1091     }
1092
1093     /// Returns true if this literal has a suffix.
1094     pub fn is_suffixed(&self) -> bool {
1095         !self.is_unsuffixed()
1096     }
1097 }
1098
1099 // NB: If you change this, you'll probably want to change the corresponding
1100 // type structure in middle/ty.rs as well.
1101 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1102 pub struct MutTy {
1103     pub ty: P<Ty>,
1104     pub mutbl: Mutability,
1105 }
1106
1107 /// Represents a method's signature in a trait declaration,
1108 /// or in an implementation.
1109 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1110 pub struct MethodSig {
1111     pub unsafety: Unsafety,
1112     pub constness: Spanned<Constness>,
1113     pub abi: Abi,
1114     pub decl: P<FnDecl>,
1115     pub generics: Generics,
1116 }
1117
1118 /// Represents an item declaration within a trait declaration,
1119 /// possibly including a default implementation. A trait item is
1120 /// either required (meaning it doesn't have an implementation, just a
1121 /// signature) or provided (meaning it has a default implementation).
1122 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1123 pub struct TraitItem {
1124     pub id: NodeId,
1125     pub ident: Ident,
1126     pub attrs: Vec<Attribute>,
1127     pub node: TraitItemKind,
1128     pub span: Span,
1129 }
1130
1131 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1132 pub enum TraitItemKind {
1133     Const(P<Ty>, Option<P<Expr>>),
1134     Method(MethodSig, Option<P<Block>>),
1135     Type(TyParamBounds, Option<P<Ty>>),
1136     Macro(Mac),
1137 }
1138
1139 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1140 pub struct ImplItem {
1141     pub id: NodeId,
1142     pub ident: Ident,
1143     pub vis: Visibility,
1144     pub defaultness: Defaultness,
1145     pub attrs: Vec<Attribute>,
1146     pub node: ImplItemKind,
1147     pub span: Span,
1148 }
1149
1150 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1151 pub enum ImplItemKind {
1152     Const(P<Ty>, P<Expr>),
1153     Method(MethodSig, P<Block>),
1154     Type(P<Ty>),
1155     Macro(Mac),
1156 }
1157
1158 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1159 pub enum IntTy {
1160     Is,
1161     I8,
1162     I16,
1163     I32,
1164     I64,
1165     I128,
1166 }
1167
1168 impl fmt::Debug for IntTy {
1169     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1170         fmt::Display::fmt(self, f)
1171     }
1172 }
1173
1174 impl fmt::Display for IntTy {
1175     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1176         write!(f, "{}", self.ty_to_string())
1177     }
1178 }
1179
1180 impl IntTy {
1181     pub fn ty_to_string(&self) -> &'static str {
1182         match *self {
1183             IntTy::Is => "isize",
1184             IntTy::I8 => "i8",
1185             IntTy::I16 => "i16",
1186             IntTy::I32 => "i32",
1187             IntTy::I64 => "i64",
1188             IntTy::I128 => "i128",
1189         }
1190     }
1191
1192     pub fn val_to_string(&self, val: i128) -> String {
1193         // cast to a u128 so we can correctly print INT128_MIN. All integral types
1194         // are parsed as u128, so we wouldn't want to print an extra negative
1195         // sign.
1196         format!("{}{}", val as u128, self.ty_to_string())
1197     }
1198
1199     pub fn bit_width(&self) -> Option<usize> {
1200         Some(match *self {
1201             IntTy::Is => return None,
1202             IntTy::I8 => 8,
1203             IntTy::I16 => 16,
1204             IntTy::I32 => 32,
1205             IntTy::I64 => 64,
1206             IntTy::I128 => 128,
1207         })
1208     }
1209 }
1210
1211 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1212 pub enum UintTy {
1213     Us,
1214     U8,
1215     U16,
1216     U32,
1217     U64,
1218     U128,
1219 }
1220
1221 impl UintTy {
1222     pub fn ty_to_string(&self) -> &'static str {
1223         match *self {
1224             UintTy::Us => "usize",
1225             UintTy::U8 => "u8",
1226             UintTy::U16 => "u16",
1227             UintTy::U32 => "u32",
1228             UintTy::U64 => "u64",
1229             UintTy::U128 => "u128",
1230         }
1231     }
1232
1233     pub fn val_to_string(&self, val: u128) -> String {
1234         format!("{}{}", val, self.ty_to_string())
1235     }
1236
1237     pub fn bit_width(&self) -> Option<usize> {
1238         Some(match *self {
1239             UintTy::Us => return None,
1240             UintTy::U8 => 8,
1241             UintTy::U16 => 16,
1242             UintTy::U32 => 32,
1243             UintTy::U64 => 64,
1244             UintTy::U128 => 128,
1245         })
1246     }
1247 }
1248
1249 impl fmt::Debug for UintTy {
1250     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1251         fmt::Display::fmt(self, f)
1252     }
1253 }
1254
1255 impl fmt::Display for UintTy {
1256     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1257         write!(f, "{}", self.ty_to_string())
1258     }
1259 }
1260
1261 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
1262 pub enum FloatTy {
1263     F32,
1264     F64,
1265 }
1266
1267 impl fmt::Debug for FloatTy {
1268     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1269         fmt::Display::fmt(self, f)
1270     }
1271 }
1272
1273 impl fmt::Display for FloatTy {
1274     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1275         write!(f, "{}", self.ty_to_string())
1276     }
1277 }
1278
1279 impl FloatTy {
1280     pub fn ty_to_string(&self) -> &'static str {
1281         match *self {
1282             FloatTy::F32 => "f32",
1283             FloatTy::F64 => "f64",
1284         }
1285     }
1286
1287     pub fn bit_width(&self) -> usize {
1288         match *self {
1289             FloatTy::F32 => 32,
1290             FloatTy::F64 => 64,
1291         }
1292     }
1293 }
1294
1295 // Bind a type to an associated type: `A=Foo`.
1296 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1297 pub struct TypeBinding {
1298     pub id: NodeId,
1299     pub ident: Ident,
1300     pub ty: P<Ty>,
1301     pub span: Span,
1302 }
1303
1304 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1305 pub struct Ty {
1306     pub id: NodeId,
1307     pub node: TyKind,
1308     pub span: Span,
1309 }
1310
1311 impl fmt::Debug for Ty {
1312     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1313         write!(f, "type({})", pprust::ty_to_string(self))
1314     }
1315 }
1316
1317 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1318 pub struct BareFnTy {
1319     pub unsafety: Unsafety,
1320     pub abi: Abi,
1321     pub lifetimes: Vec<LifetimeDef>,
1322     pub decl: P<FnDecl>
1323 }
1324
1325 /// The different kinds of types recognized by the compiler
1326 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1327 pub enum TyKind {
1328     /// A variable-length slice (`[T]`)
1329     Slice(P<Ty>),
1330     /// A fixed length array (`[T; n]`)
1331     Array(P<Ty>, P<Expr>),
1332     /// A raw pointer (`*const T` or `*mut T`)
1333     Ptr(MutTy),
1334     /// A reference (`&'a T` or `&'a mut T`)
1335     Rptr(Option<Lifetime>, MutTy),
1336     /// A bare function (e.g. `fn(usize) -> bool`)
1337     BareFn(P<BareFnTy>),
1338     /// The never type (`!`)
1339     Never,
1340     /// A tuple (`(A, B, C, D,...)`)
1341     Tup(Vec<P<Ty>> ),
1342     /// A path (`module::module::...::Type`), optionally
1343     /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`.
1344     ///
1345     /// Type parameters are stored in the Path itself
1346     Path(Option<QSelf>, Path),
1347     /// A trait object type `Bound1 + Bound2 + Bound3`
1348     /// where `Bound` is a trait or a lifetime.
1349     TraitObject(TyParamBounds),
1350     /// An `impl Bound1 + Bound2 + Bound3` type
1351     /// where `Bound` is a trait or a lifetime.
1352     ImplTrait(TyParamBounds),
1353     /// No-op; kept solely so that we can pretty-print faithfully
1354     Paren(P<Ty>),
1355     /// Unused for now
1356     Typeof(P<Expr>),
1357     /// TyKind::Infer means the type should be inferred instead of it having been
1358     /// specified. This can appear anywhere in a type.
1359     Infer,
1360     /// Inferred type of a `self` or `&self` argument in a method.
1361     ImplicitSelf,
1362     // A macro in the type position.
1363     Mac(Mac),
1364     /// Placeholder for a kind that has failed to be defined.
1365     Err,
1366 }
1367
1368 /// Inline assembly dialect.
1369 ///
1370 /// E.g. `"intel"` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")``
1371 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1372 pub enum AsmDialect {
1373     Att,
1374     Intel,
1375 }
1376
1377 /// Inline assembly.
1378 ///
1379 /// E.g. `"={eax}"(result)` as in `asm!("mov eax, 2" : "={eax}"(result) : : : "intel")``
1380 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1381 pub struct InlineAsmOutput {
1382     pub constraint: Symbol,
1383     pub expr: P<Expr>,
1384     pub is_rw: bool,
1385     pub is_indirect: bool,
1386 }
1387
1388 /// Inline assembly.
1389 ///
1390 /// E.g. `asm!("NOP");`
1391 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1392 pub struct InlineAsm {
1393     pub asm: Symbol,
1394     pub asm_str_style: StrStyle,
1395     pub outputs: Vec<InlineAsmOutput>,
1396     pub inputs: Vec<(Symbol, P<Expr>)>,
1397     pub clobbers: Vec<Symbol>,
1398     pub volatile: bool,
1399     pub alignstack: bool,
1400     pub dialect: AsmDialect,
1401     pub ctxt: SyntaxContext,
1402 }
1403
1404 /// An argument in a function header.
1405 ///
1406 /// E.g. `bar: usize` as in `fn foo(bar: usize)`
1407 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1408 pub struct Arg {
1409     pub ty: P<Ty>,
1410     pub pat: P<Pat>,
1411     pub id: NodeId,
1412 }
1413
1414 /// Alternative representation for `Arg`s describing `self` parameter of methods.
1415 ///
1416 /// E.g. `&mut self` as in `fn foo(&mut self)`
1417 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1418 pub enum SelfKind {
1419     /// `self`, `mut self`
1420     Value(Mutability),
1421     /// `&'lt self`, `&'lt mut self`
1422     Region(Option<Lifetime>, Mutability),
1423     /// `self: TYPE`, `mut self: TYPE`
1424     Explicit(P<Ty>, Mutability),
1425 }
1426
1427 pub type ExplicitSelf = Spanned<SelfKind>;
1428
1429 impl Arg {
1430     pub fn to_self(&self) -> Option<ExplicitSelf> {
1431         if let PatKind::Ident(BindingMode::ByValue(mutbl), ident, _) = self.pat.node {
1432             if ident.node.name == keywords::SelfValue.name() {
1433                 return match self.ty.node {
1434                     TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
1435                     TyKind::Rptr(lt, MutTy{ref ty, mutbl}) if ty.node == TyKind::ImplicitSelf => {
1436                         Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
1437                     }
1438                     _ => Some(respan(self.pat.span.to(self.ty.span),
1439                                      SelfKind::Explicit(self.ty.clone(), mutbl))),
1440                 }
1441             }
1442         }
1443         None
1444     }
1445
1446     pub fn is_self(&self) -> bool {
1447         if let PatKind::Ident(_, ident, _) = self.pat.node {
1448             ident.node.name == keywords::SelfValue.name()
1449         } else {
1450             false
1451         }
1452     }
1453
1454     pub fn from_self(eself: ExplicitSelf, eself_ident: SpannedIdent) -> Arg {
1455         let span = eself.span.to(eself_ident.span);
1456         let infer_ty = P(Ty {
1457             id: DUMMY_NODE_ID,
1458             node: TyKind::ImplicitSelf,
1459             span: span,
1460         });
1461         let arg = |mutbl, ty| Arg {
1462             pat: P(Pat {
1463                 id: DUMMY_NODE_ID,
1464                 node: PatKind::Ident(BindingMode::ByValue(mutbl), eself_ident, None),
1465                 span: span,
1466             }),
1467             ty: ty,
1468             id: DUMMY_NODE_ID,
1469         };
1470         match eself.node {
1471             SelfKind::Explicit(ty, mutbl) => arg(mutbl, ty),
1472             SelfKind::Value(mutbl) => arg(mutbl, infer_ty),
1473             SelfKind::Region(lt, mutbl) => arg(Mutability::Immutable, P(Ty {
1474                 id: DUMMY_NODE_ID,
1475                 node: TyKind::Rptr(lt, MutTy { ty: infer_ty, mutbl: mutbl }),
1476                 span: span,
1477             })),
1478         }
1479     }
1480 }
1481
1482 /// Header (not the body) of a function declaration.
1483 ///
1484 /// E.g. `fn foo(bar: baz)`
1485 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1486 pub struct FnDecl {
1487     pub inputs: Vec<Arg>,
1488     pub output: FunctionRetTy,
1489     pub variadic: bool
1490 }
1491
1492 impl FnDecl {
1493     pub fn get_self(&self) -> Option<ExplicitSelf> {
1494         self.inputs.get(0).and_then(Arg::to_self)
1495     }
1496     pub fn has_self(&self) -> bool {
1497         self.inputs.get(0).map(Arg::is_self).unwrap_or(false)
1498     }
1499 }
1500
1501 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1502 pub enum Unsafety {
1503     Unsafe,
1504     Normal,
1505 }
1506
1507 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1508 pub enum Constness {
1509     Const,
1510     NotConst,
1511 }
1512
1513 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1514 pub enum Defaultness {
1515     Default,
1516     Final,
1517 }
1518
1519 impl fmt::Display for Unsafety {
1520     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1521         fmt::Display::fmt(match *self {
1522             Unsafety::Normal => "normal",
1523             Unsafety::Unsafe => "unsafe",
1524         }, f)
1525     }
1526 }
1527
1528 #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
1529 pub enum ImplPolarity {
1530     /// `impl Trait for Type`
1531     Positive,
1532     /// `impl !Trait for Type`
1533     Negative,
1534 }
1535
1536 impl fmt::Debug for ImplPolarity {
1537     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1538         match *self {
1539             ImplPolarity::Positive => "positive".fmt(f),
1540             ImplPolarity::Negative => "negative".fmt(f),
1541         }
1542     }
1543 }
1544
1545
1546 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1547 pub enum FunctionRetTy {
1548     /// Return type is not specified.
1549     ///
1550     /// Functions default to `()` and
1551     /// closures default to inference. Span points to where return
1552     /// type would be inserted.
1553     Default(Span),
1554     /// Everything else
1555     Ty(P<Ty>),
1556 }
1557
1558 impl FunctionRetTy {
1559     pub fn span(&self) -> Span {
1560         match *self {
1561             FunctionRetTy::Default(span) => span,
1562             FunctionRetTy::Ty(ref ty) => ty.span,
1563         }
1564     }
1565 }
1566
1567 /// Module declaration.
1568 ///
1569 /// E.g. `mod foo;` or `mod foo { .. }`
1570 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1571 pub struct Mod {
1572     /// A span from the first token past `{` to the last token until `}`.
1573     /// For `mod foo;`, the inner span ranges from the first token
1574     /// to the last token in the external file.
1575     pub inner: Span,
1576     pub items: Vec<P<Item>>,
1577 }
1578
1579 /// Foreign module declaration.
1580 ///
1581 /// E.g. `extern { .. }` or `extern C { .. }`
1582 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1583 pub struct ForeignMod {
1584     pub abi: Abi,
1585     pub items: Vec<ForeignItem>,
1586 }
1587
1588 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1589 pub struct EnumDef {
1590     pub variants: Vec<Variant>,
1591 }
1592
1593 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1594 pub struct Variant_ {
1595     pub name: Ident,
1596     pub attrs: Vec<Attribute>,
1597     pub data: VariantData,
1598     /// Explicit discriminant, e.g. `Foo = 1`
1599     pub disr_expr: Option<P<Expr>>,
1600 }
1601
1602 pub type Variant = Spanned<Variant_>;
1603
1604 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1605 pub struct PathListItem_ {
1606     pub name: Ident,
1607     /// renamed in list, e.g. `use foo::{bar as baz};`
1608     pub rename: Option<Ident>,
1609     pub id: NodeId,
1610 }
1611
1612 pub type PathListItem = Spanned<PathListItem_>;
1613
1614 pub type ViewPath = Spanned<ViewPath_>;
1615
1616 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1617 pub enum ViewPath_ {
1618
1619     /// `foo::bar::baz as quux`
1620     ///
1621     /// or just
1622     ///
1623     /// `foo::bar::baz` (with `as baz` implicitly on the right)
1624     ViewPathSimple(Ident, Path),
1625
1626     /// `foo::bar::*`
1627     ViewPathGlob(Path),
1628
1629     /// `foo::bar::{a,b,c}`
1630     ViewPathList(Path, Vec<PathListItem>)
1631 }
1632
1633 impl ViewPath_ {
1634     pub fn path(&self) -> &Path {
1635         match *self {
1636             ViewPathSimple(_, ref path) |
1637             ViewPathGlob (ref path) |
1638             ViewPathList(ref path, _) => path
1639         }
1640     }
1641 }
1642
1643
1644 /// Distinguishes between Attributes that decorate items and Attributes that
1645 /// are contained as statements within items. These two cases need to be
1646 /// distinguished for pretty-printing.
1647 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1648 pub enum AttrStyle {
1649     Outer,
1650     Inner,
1651 }
1652
1653 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1654 pub struct AttrId(pub usize);
1655
1656 /// Meta-data associated with an item
1657 /// Doc-comments are promoted to attributes that have is_sugared_doc = true
1658 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1659 pub struct Attribute {
1660     pub id: AttrId,
1661     pub style: AttrStyle,
1662     pub path: Path,
1663     pub tokens: TokenStream,
1664     pub is_sugared_doc: bool,
1665     pub span: Span,
1666 }
1667
1668 /// TraitRef's appear in impls.
1669 ///
1670 /// resolve maps each TraitRef's ref_id to its defining trait; that's all
1671 /// that the ref_id is for. The impl_id maps to the "self type" of this impl.
1672 /// If this impl is an ItemKind::Impl, the impl_id is redundant (it could be the
1673 /// same as the impl's node id).
1674 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1675 pub struct TraitRef {
1676     pub path: Path,
1677     pub ref_id: NodeId,
1678 }
1679
1680 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1681 pub struct PolyTraitRef {
1682     /// The `'a` in `<'a> Foo<&'a T>`
1683     pub bound_lifetimes: Vec<LifetimeDef>,
1684
1685     /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`
1686     pub trait_ref: TraitRef,
1687
1688     pub span: Span,
1689 }
1690
1691 impl PolyTraitRef {
1692     pub fn new(lifetimes: Vec<LifetimeDef>, path: Path, span: Span) -> Self {
1693         PolyTraitRef {
1694             bound_lifetimes: lifetimes,
1695             trait_ref: TraitRef { path: path, ref_id: DUMMY_NODE_ID },
1696             span: span,
1697         }
1698     }
1699 }
1700
1701 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1702 pub enum Visibility {
1703     Public,
1704     Crate(Span),
1705     Restricted { path: P<Path>, id: NodeId },
1706     Inherited,
1707 }
1708
1709 /// Field of a struct.
1710 ///
1711 /// E.g. `bar: usize` as in `struct Foo { bar: usize }`
1712 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1713 pub struct StructField {
1714     pub span: Span,
1715     pub ident: Option<Ident>,
1716     pub vis: Visibility,
1717     pub id: NodeId,
1718     pub ty: P<Ty>,
1719     pub attrs: Vec<Attribute>,
1720 }
1721
1722 /// Fields and Ids of enum variants and structs
1723 ///
1724 /// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all
1725 /// variant kinds) and an Id of the variant's constructor (not relevant for `Struct`-variants).
1726 /// One shared Id can be successfully used for these two purposes.
1727 /// Id of the whole enum lives in `Item`.
1728 ///
1729 /// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually
1730 /// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of
1731 /// the variant itself" from enum variants.
1732 /// Id of the whole struct lives in `Item`.
1733 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1734 pub enum VariantData {
1735     /// Struct variant.
1736     ///
1737     /// E.g. `Bar { .. }` as in `enum Foo { Bar { .. } }`
1738     Struct(Vec<StructField>, NodeId),
1739     /// Tuple variant.
1740     ///
1741     /// E.g. `Bar(..)` as in `enum Foo { Bar(..) }`
1742     Tuple(Vec<StructField>, NodeId),
1743     /// Unit variant.
1744     ///
1745     /// E.g. `Bar = ..` as in `enum Foo { Bar = .. }`
1746     Unit(NodeId),
1747 }
1748
1749 impl VariantData {
1750     pub fn fields(&self) -> &[StructField] {
1751         match *self {
1752             VariantData::Struct(ref fields, _) | VariantData::Tuple(ref fields, _) => fields,
1753             _ => &[],
1754         }
1755     }
1756     pub fn id(&self) -> NodeId {
1757         match *self {
1758             VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id
1759         }
1760     }
1761     pub fn is_struct(&self) -> bool {
1762         if let VariantData::Struct(..) = *self { true } else { false }
1763     }
1764     pub fn is_tuple(&self) -> bool {
1765         if let VariantData::Tuple(..) = *self { true } else { false }
1766     }
1767     pub fn is_unit(&self) -> bool {
1768         if let VariantData::Unit(..) = *self { true } else { false }
1769     }
1770 }
1771
1772 /// An item
1773 ///
1774 /// The name might be a dummy name in case of anonymous items
1775 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1776 pub struct Item {
1777     pub ident: Ident,
1778     pub attrs: Vec<Attribute>,
1779     pub id: NodeId,
1780     pub node: ItemKind,
1781     pub vis: Visibility,
1782     pub span: Span,
1783 }
1784
1785 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1786 pub enum ItemKind {
1787     /// An`extern crate` item, with optional original crate name.
1788     ///
1789     /// E.g. `extern crate foo` or `extern crate foo_bar as foo`
1790     ExternCrate(Option<Name>),
1791     /// A use declaration (`use` or `pub use`) item.
1792     ///
1793     /// E.g. `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`
1794     Use(P<ViewPath>),
1795     /// A static item (`static` or `pub static`).
1796     ///
1797     /// E.g. `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`
1798     Static(P<Ty>, Mutability, P<Expr>),
1799     /// A constant item (`const` or `pub const`).
1800     ///
1801     /// E.g. `const FOO: i32 = 42;`
1802     Const(P<Ty>, P<Expr>),
1803     /// A function declaration (`fn` or `pub fn`).
1804     ///
1805     /// E.g. `fn foo(bar: usize) -> usize { .. }`
1806     Fn(P<FnDecl>, Unsafety, Spanned<Constness>, Abi, Generics, P<Block>),
1807     /// A module declaration (`mod` or `pub mod`).
1808     ///
1809     /// E.g. `mod foo;` or `mod foo { .. }`
1810     Mod(Mod),
1811     /// An external module (`extern` or `pub extern`).
1812     ///
1813     /// E.g. `extern {}` or `extern "C" {}`
1814     ForeignMod(ForeignMod),
1815     /// A type alias (`type` or `pub type`).
1816     ///
1817     /// E.g. `type Foo = Bar<u8>;`
1818     Ty(P<Ty>, Generics),
1819     /// An enum definition (`enum` or `pub enum`).
1820     ///
1821     /// E.g. `enum Foo<A, B> { C<A>, D<B> }`
1822     Enum(EnumDef, Generics),
1823     /// A struct definition (`struct` or `pub struct`).
1824     ///
1825     /// E.g. `struct Foo<A> { x: A }`
1826     Struct(VariantData, Generics),
1827     /// A union definition (`union` or `pub union`).
1828     ///
1829     /// E.g. `union Foo<A, B> { x: A, y: B }`
1830     Union(VariantData, Generics),
1831     /// A Trait declaration (`trait` or `pub trait`).
1832     ///
1833     /// E.g. `trait Foo { .. }` or `trait Foo<T> { .. }`
1834     Trait(Unsafety, Generics, TyParamBounds, Vec<TraitItem>),
1835     // Default trait implementation.
1836     ///
1837     /// E.g. `impl Trait for .. {}` or `impl<T> Trait<T> for .. {}`
1838     DefaultImpl(Unsafety, TraitRef),
1839     /// An implementation.
1840     ///
1841     /// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
1842     Impl(Unsafety,
1843              ImplPolarity,
1844              Generics,
1845              Option<TraitRef>, // (optional) trait this impl implements
1846              P<Ty>, // self
1847              Vec<ImplItem>),
1848     /// A macro invocation.
1849     ///
1850     /// E.g. `macro_rules! foo { .. }` or `foo!(..)`
1851     Mac(Mac),
1852
1853     /// A macro definition.
1854     MacroDef(ThinTokenStream),
1855 }
1856
1857 impl ItemKind {
1858     pub fn descriptive_variant(&self) -> &str {
1859         match *self {
1860             ItemKind::ExternCrate(..) => "extern crate",
1861             ItemKind::Use(..) => "use",
1862             ItemKind::Static(..) => "static item",
1863             ItemKind::Const(..) => "constant item",
1864             ItemKind::Fn(..) => "function",
1865             ItemKind::Mod(..) => "module",
1866             ItemKind::ForeignMod(..) => "foreign module",
1867             ItemKind::Ty(..) => "type alias",
1868             ItemKind::Enum(..) => "enum",
1869             ItemKind::Struct(..) => "struct",
1870             ItemKind::Union(..) => "union",
1871             ItemKind::Trait(..) => "trait",
1872             ItemKind::Mac(..) |
1873             ItemKind::MacroDef(..) |
1874             ItemKind::Impl(..) |
1875             ItemKind::DefaultImpl(..) => "item"
1876         }
1877     }
1878 }
1879
1880 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1881 pub struct ForeignItem {
1882     pub ident: Ident,
1883     pub attrs: Vec<Attribute>,
1884     pub node: ForeignItemKind,
1885     pub id: NodeId,
1886     pub span: Span,
1887     pub vis: Visibility,
1888 }
1889
1890 /// An item within an `extern` block
1891 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1892 pub enum ForeignItemKind {
1893     /// A foreign function
1894     Fn(P<FnDecl>, Generics),
1895     /// A foreign static item (`static ext: u8`), with optional mutability
1896     /// (the boolean is true when mutable)
1897     Static(P<Ty>, bool),
1898 }
1899
1900 impl ForeignItemKind {
1901     pub fn descriptive_variant(&self) -> &str {
1902         match *self {
1903             ForeignItemKind::Fn(..) => "foreign function",
1904             ForeignItemKind::Static(..) => "foreign static item"
1905         }
1906     }
1907 }
1908
1909 #[cfg(test)]
1910 mod tests {
1911     use serialize;
1912     use super::*;
1913
1914     // are ASTs encodable?
1915     #[test]
1916     fn check_asts_encodable() {
1917         fn assert_encodable<T: serialize::Encodable>() {}
1918         assert_encodable::<Crate>();
1919     }
1920 }