]> git.lizzy.rs Git - rust.git/blob - src/libsyntax/ext/build.rs
e0fb46ff5eb095a01c659ab0a6e124c30f82c577
[rust.git] / src / libsyntax / ext / build.rs
1 // Copyright 2012 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 use abi::Abi;
12 use ast::{self, Ident, Generics, Expr, BlockCheckMode, UnOp, PatKind};
13 use attr;
14 use syntax_pos::{Span, DUMMY_SP};
15 use codemap::{dummy_spanned, respan, Spanned};
16 use ext::base::ExtCtxt;
17 use ptr::P;
18 use symbol::{Symbol, keywords};
19
20 // Transitional reexports so qquote can find the paths it is looking for
21 mod syntax {
22     pub use ext;
23     pub use parse;
24 }
25
26 pub trait AstBuilder {
27     // paths
28     fn path(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path;
29     fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path;
30     fn path_global(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path;
31     fn path_all(&self, sp: Span,
32                 global: bool,
33                 idents: Vec<ast::Ident> ,
34                 lifetimes: Vec<ast::Lifetime>,
35                 types: Vec<P<ast::Ty>>,
36                 bindings: Vec<ast::TypeBinding> )
37         -> ast::Path;
38
39     fn qpath(&self, self_type: P<ast::Ty>,
40              trait_path: ast::Path,
41              ident: ast::SpannedIdent)
42              -> (ast::QSelf, ast::Path);
43     fn qpath_all(&self, self_type: P<ast::Ty>,
44                 trait_path: ast::Path,
45                 ident: ast::SpannedIdent,
46                 lifetimes: Vec<ast::Lifetime>,
47                 types: Vec<P<ast::Ty>>,
48                 bindings: Vec<ast::TypeBinding>)
49                 -> (ast::QSelf, ast::Path);
50
51     // types
52     fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy;
53
54     fn ty(&self, span: Span, ty: ast::TyKind) -> P<ast::Ty>;
55     fn ty_path(&self, ast::Path) -> P<ast::Ty>;
56     fn ty_ident(&self, span: Span, idents: ast::Ident) -> P<ast::Ty>;
57
58     fn ty_rptr(&self, span: Span,
59                ty: P<ast::Ty>,
60                lifetime: Option<ast::Lifetime>,
61                mutbl: ast::Mutability) -> P<ast::Ty>;
62     fn ty_ptr(&self, span: Span,
63               ty: P<ast::Ty>,
64               mutbl: ast::Mutability) -> P<ast::Ty>;
65
66     fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty>;
67     fn ty_infer(&self, sp: Span) -> P<ast::Ty>;
68
69     fn typaram(&self,
70                span: Span,
71                id: ast::Ident,
72                attrs: Vec<ast::Attribute>,
73                bounds: ast::TyParamBounds,
74                default: Option<P<ast::Ty>>) -> ast::TyParam;
75
76     fn trait_ref(&self, path: ast::Path) -> ast::TraitRef;
77     fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef;
78     fn typarambound(&self, path: ast::Path) -> ast::TyParamBound;
79     fn lifetime(&self, span: Span, ident: ast::Name) -> ast::Lifetime;
80     fn lifetime_def(&self,
81                     span: Span,
82                     name: ast::Name,
83                     attrs: Vec<ast::Attribute>,
84                     bounds: Vec<ast::Lifetime>)
85                     -> ast::LifetimeDef;
86
87     // statements
88     fn stmt_expr(&self, expr: P<ast::Expr>) -> ast::Stmt;
89     fn stmt_semi(&self, expr: P<ast::Expr>) -> ast::Stmt;
90     fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: P<ast::Expr>) -> ast::Stmt;
91     fn stmt_let_typed(&self,
92                       sp: Span,
93                       mutbl: bool,
94                       ident: ast::Ident,
95                       typ: P<ast::Ty>,
96                       ex: P<ast::Expr>)
97                       -> ast::Stmt;
98     fn stmt_let_type_only(&self, span: Span, ty: P<ast::Ty>) -> ast::Stmt;
99     fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> ast::Stmt;
100
101     // blocks
102     fn block(&self, span: Span, stmts: Vec<ast::Stmt>) -> P<ast::Block>;
103     fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block>;
104
105     // expressions
106     fn expr(&self, span: Span, node: ast::ExprKind) -> P<ast::Expr>;
107     fn expr_path(&self, path: ast::Path) -> P<ast::Expr>;
108     fn expr_qpath(&self, span: Span, qself: ast::QSelf, path: ast::Path) -> P<ast::Expr>;
109     fn expr_ident(&self, span: Span, id: ast::Ident) -> P<ast::Expr>;
110
111     fn expr_self(&self, span: Span) -> P<ast::Expr>;
112     fn expr_binary(&self, sp: Span, op: ast::BinOpKind,
113                    lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> P<ast::Expr>;
114     fn expr_deref(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr>;
115     fn expr_unary(&self, sp: Span, op: ast::UnOp, e: P<ast::Expr>) -> P<ast::Expr>;
116
117     fn expr_addr_of(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr>;
118     fn expr_mut_addr_of(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr>;
119     fn expr_field_access(&self, span: Span, expr: P<ast::Expr>, ident: ast::Ident) -> P<ast::Expr>;
120     fn expr_tup_field_access(&self, sp: Span, expr: P<ast::Expr>,
121                              idx: usize) -> P<ast::Expr>;
122     fn expr_call(&self, span: Span, expr: P<ast::Expr>, args: Vec<P<ast::Expr>>) -> P<ast::Expr>;
123     fn expr_call_ident(&self, span: Span, id: ast::Ident, args: Vec<P<ast::Expr>>) -> P<ast::Expr>;
124     fn expr_call_global(&self, sp: Span, fn_path: Vec<ast::Ident>,
125                         args: Vec<P<ast::Expr>> ) -> P<ast::Expr>;
126     fn expr_method_call(&self, span: Span,
127                         expr: P<ast::Expr>, ident: ast::Ident,
128                         args: Vec<P<ast::Expr>> ) -> P<ast::Expr>;
129     fn expr_block(&self, b: P<ast::Block>) -> P<ast::Expr>;
130     fn expr_cast(&self, sp: Span, expr: P<ast::Expr>, ty: P<ast::Ty>) -> P<ast::Expr>;
131
132     fn field_imm(&self, span: Span, name: Ident, e: P<ast::Expr>) -> ast::Field;
133     fn expr_struct(&self, span: Span, path: ast::Path, fields: Vec<ast::Field>) -> P<ast::Expr>;
134     fn expr_struct_ident(&self, span: Span, id: ast::Ident,
135                          fields: Vec<ast::Field>) -> P<ast::Expr>;
136
137     fn expr_lit(&self, sp: Span, lit: ast::LitKind) -> P<ast::Expr>;
138
139     fn expr_usize(&self, span: Span, i: usize) -> P<ast::Expr>;
140     fn expr_isize(&self, sp: Span, i: isize) -> P<ast::Expr>;
141     fn expr_u8(&self, sp: Span, u: u8) -> P<ast::Expr>;
142     fn expr_u32(&self, sp: Span, u: u32) -> P<ast::Expr>;
143     fn expr_bool(&self, sp: Span, value: bool) -> P<ast::Expr>;
144
145     fn expr_vec(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr>;
146     fn expr_vec_ng(&self, sp: Span) -> P<ast::Expr>;
147     fn expr_vec_slice(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr>;
148     fn expr_str(&self, sp: Span, s: Symbol) -> P<ast::Expr>;
149
150     fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr>;
151     fn expr_none(&self, sp: Span) -> P<ast::Expr>;
152
153     fn expr_break(&self, sp: Span) -> P<ast::Expr>;
154
155     fn expr_tuple(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr>;
156
157     fn expr_fail(&self, span: Span, msg: Symbol) -> P<ast::Expr>;
158     fn expr_unreachable(&self, span: Span) -> P<ast::Expr>;
159
160     fn expr_ok(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Expr>;
161     fn expr_err(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Expr>;
162     fn expr_try(&self, span: Span, head: P<ast::Expr>) -> P<ast::Expr>;
163
164     fn pat(&self, span: Span, pat: PatKind) -> P<ast::Pat>;
165     fn pat_wild(&self, span: Span) -> P<ast::Pat>;
166     fn pat_lit(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Pat>;
167     fn pat_ident(&self, span: Span, ident: ast::Ident) -> P<ast::Pat>;
168
169     fn pat_ident_binding_mode(&self,
170                               span: Span,
171                               ident: ast::Ident,
172                               bm: ast::BindingMode) -> P<ast::Pat>;
173     fn pat_path(&self, span: Span, path: ast::Path) -> P<ast::Pat>;
174     fn pat_tuple_struct(&self, span: Span, path: ast::Path,
175                         subpats: Vec<P<ast::Pat>>) -> P<ast::Pat>;
176     fn pat_struct(&self, span: Span, path: ast::Path,
177                   field_pats: Vec<Spanned<ast::FieldPat>>) -> P<ast::Pat>;
178     fn pat_tuple(&self, span: Span, pats: Vec<P<ast::Pat>>) -> P<ast::Pat>;
179
180     fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat>;
181     fn pat_none(&self, span: Span) -> P<ast::Pat>;
182
183     fn pat_ok(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat>;
184     fn pat_err(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat>;
185
186     fn arm(&self, span: Span, pats: Vec<P<ast::Pat>>, expr: P<ast::Expr>) -> ast::Arm;
187     fn arm_unreachable(&self, span: Span) -> ast::Arm;
188
189     fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: Vec<ast::Arm> ) -> P<ast::Expr>;
190     fn expr_if(&self, span: Span,
191                cond: P<ast::Expr>, then: P<ast::Expr>, els: Option<P<ast::Expr>>) -> P<ast::Expr>;
192     fn expr_loop(&self, span: Span, block: P<ast::Block>) -> P<ast::Expr>;
193
194     fn lambda_fn_decl(&self,
195                       span: Span,
196                       fn_decl: P<ast::FnDecl>,
197                       body: P<ast::Expr>,
198                       fn_decl_span: Span)
199                       -> P<ast::Expr>;
200
201     fn lambda(&self, span: Span, ids: Vec<ast::Ident>, body: P<ast::Expr>) -> P<ast::Expr>;
202     fn lambda0(&self, span: Span, body: P<ast::Expr>) -> P<ast::Expr>;
203     fn lambda1(&self, span: Span, body: P<ast::Expr>, ident: ast::Ident) -> P<ast::Expr>;
204
205     fn lambda_stmts(&self, span: Span, ids: Vec<ast::Ident>,
206                     blk: Vec<ast::Stmt>) -> P<ast::Expr>;
207     fn lambda_stmts_0(&self, span: Span, stmts: Vec<ast::Stmt>) -> P<ast::Expr>;
208     fn lambda_stmts_1(&self, span: Span, stmts: Vec<ast::Stmt>,
209                       ident: ast::Ident) -> P<ast::Expr>;
210
211     // items
212     fn item(&self, span: Span,
213             name: Ident, attrs: Vec<ast::Attribute> , node: ast::ItemKind) -> P<ast::Item>;
214
215     fn arg(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> ast::Arg;
216     // FIXME unused self
217     fn fn_decl(&self, inputs: Vec<ast::Arg> , output: P<ast::Ty>) -> P<ast::FnDecl>;
218
219     fn item_fn_poly(&self,
220                     span: Span,
221                     name: Ident,
222                     inputs: Vec<ast::Arg> ,
223                     output: P<ast::Ty>,
224                     generics: Generics,
225                     body: P<ast::Block>) -> P<ast::Item>;
226     fn item_fn(&self,
227                span: Span,
228                name: Ident,
229                inputs: Vec<ast::Arg> ,
230                output: P<ast::Ty>,
231                body: P<ast::Block>) -> P<ast::Item>;
232
233     fn variant(&self, span: Span, name: Ident, tys: Vec<P<ast::Ty>> ) -> ast::Variant;
234     fn item_enum_poly(&self,
235                       span: Span,
236                       name: Ident,
237                       enum_definition: ast::EnumDef,
238                       generics: Generics) -> P<ast::Item>;
239     fn item_enum(&self, span: Span, name: Ident, enum_def: ast::EnumDef) -> P<ast::Item>;
240
241     fn item_struct_poly(&self,
242                         span: Span,
243                         name: Ident,
244                         struct_def: ast::VariantData,
245                         generics: Generics) -> P<ast::Item>;
246     fn item_struct(&self, span: Span, name: Ident, struct_def: ast::VariantData) -> P<ast::Item>;
247
248     fn item_mod(&self, span: Span, inner_span: Span,
249                 name: Ident, attrs: Vec<ast::Attribute>,
250                 items: Vec<P<ast::Item>>) -> P<ast::Item>;
251
252     fn item_static(&self,
253                    span: Span,
254                    name: Ident,
255                    ty: P<ast::Ty>,
256                    mutbl: ast::Mutability,
257                    expr: P<ast::Expr>)
258                    -> P<ast::Item>;
259
260     fn item_const(&self,
261                    span: Span,
262                    name: Ident,
263                    ty: P<ast::Ty>,
264                    expr: P<ast::Expr>)
265                    -> P<ast::Item>;
266
267     fn item_ty_poly(&self,
268                     span: Span,
269                     name: Ident,
270                     ty: P<ast::Ty>,
271                     generics: Generics) -> P<ast::Item>;
272     fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> P<ast::Item>;
273
274     fn attribute(&self, sp: Span, mi: ast::MetaItem) -> ast::Attribute;
275
276     fn meta_word(&self, sp: Span, w: ast::Name) -> ast::MetaItem;
277
278     fn meta_list_item_word(&self, sp: Span, w: ast::Name) -> ast::NestedMetaItem;
279
280     fn meta_list(&self,
281                  sp: Span,
282                  name: ast::Name,
283                  mis: Vec<ast::NestedMetaItem> )
284                  -> ast::MetaItem;
285     fn meta_name_value(&self,
286                        sp: Span,
287                        name: ast::Name,
288                        value: ast::LitKind)
289                        -> ast::MetaItem;
290
291     fn item_use(&self, sp: Span,
292                 vis: ast::Visibility, vp: P<ast::ViewPath>) -> P<ast::Item>;
293     fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P<ast::Item>;
294     fn item_use_simple_(&self, sp: Span, vis: ast::Visibility,
295                         ident: ast::Ident, path: ast::Path) -> P<ast::Item>;
296     fn item_use_list(&self, sp: Span, vis: ast::Visibility,
297                      path: Vec<ast::Ident>, imports: &[ast::Ident]) -> P<ast::Item>;
298     fn item_use_glob(&self, sp: Span,
299                      vis: ast::Visibility, path: Vec<ast::Ident>) -> P<ast::Item>;
300 }
301
302 impl<'a> AstBuilder for ExtCtxt<'a> {
303     fn path(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path {
304         self.path_all(span, false, strs, Vec::new(), Vec::new(), Vec::new())
305     }
306     fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path {
307         self.path(span, vec![id])
308     }
309     fn path_global(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path {
310         self.path_all(span, true, strs, Vec::new(), Vec::new(), Vec::new())
311     }
312     fn path_all(&self,
313                 sp: Span,
314                 global: bool,
315                 mut idents: Vec<ast::Ident> ,
316                 lifetimes: Vec<ast::Lifetime>,
317                 types: Vec<P<ast::Ty>>,
318                 bindings: Vec<ast::TypeBinding> )
319                 -> ast::Path {
320         let last_identifier = idents.pop().unwrap();
321         let mut segments: Vec<ast::PathSegment> = Vec::new();
322         if global {
323             segments.push(ast::PathSegment::crate_root());
324         }
325
326         segments.extend(idents.into_iter().map(|i| ast::PathSegment::from_ident(i, sp)));
327         let parameters = if lifetimes.is_empty() && types.is_empty() && bindings.is_empty() {
328             None
329         } else {
330             Some(P(ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
331                 lifetimes: lifetimes,
332                 types: types,
333                 bindings: bindings,
334             })))
335         };
336         segments.push(ast::PathSegment {
337             identifier: last_identifier,
338             span: sp,
339             parameters: parameters
340         });
341         ast::Path {
342             span: sp,
343             segments: segments,
344         }
345     }
346
347     /// Constructs a qualified path.
348     ///
349     /// Constructs a path like `<self_type as trait_path>::ident`.
350     fn qpath(&self,
351              self_type: P<ast::Ty>,
352              trait_path: ast::Path,
353              ident: ast::SpannedIdent)
354              -> (ast::QSelf, ast::Path) {
355         self.qpath_all(self_type, trait_path, ident, vec![], vec![], vec![])
356     }
357
358     /// Constructs a qualified path.
359     ///
360     /// Constructs a path like `<self_type as trait_path>::ident<'a, T, A=Bar>`.
361     fn qpath_all(&self,
362                  self_type: P<ast::Ty>,
363                  trait_path: ast::Path,
364                  ident: ast::SpannedIdent,
365                  lifetimes: Vec<ast::Lifetime>,
366                  types: Vec<P<ast::Ty>>,
367                  bindings: Vec<ast::TypeBinding>)
368                  -> (ast::QSelf, ast::Path) {
369         let mut path = trait_path;
370         let parameters = ast::AngleBracketedParameterData {
371             lifetimes: lifetimes,
372             types: types,
373             bindings: bindings,
374         };
375         path.segments.push(ast::PathSegment {
376             identifier: ident.node,
377             span: ident.span,
378             parameters: Some(P(ast::PathParameters::AngleBracketed(parameters))),
379         });
380
381         (ast::QSelf {
382             ty: self_type,
383             position: path.segments.len() - 1
384         }, path)
385     }
386
387     fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy {
388         ast::MutTy {
389             ty: ty,
390             mutbl: mutbl
391         }
392     }
393
394     fn ty(&self, span: Span, ty: ast::TyKind) -> P<ast::Ty> {
395         P(ast::Ty {
396             id: ast::DUMMY_NODE_ID,
397             span: span,
398             node: ty
399         })
400     }
401
402     fn ty_path(&self, path: ast::Path) -> P<ast::Ty> {
403         self.ty(path.span, ast::TyKind::Path(None, path))
404     }
405
406     // Might need to take bounds as an argument in the future, if you ever want
407     // to generate a bounded existential trait type.
408     fn ty_ident(&self, span: Span, ident: ast::Ident)
409         -> P<ast::Ty> {
410         self.ty_path(self.path_ident(span, ident))
411     }
412
413     fn ty_rptr(&self,
414                span: Span,
415                ty: P<ast::Ty>,
416                lifetime: Option<ast::Lifetime>,
417                mutbl: ast::Mutability)
418         -> P<ast::Ty> {
419         self.ty(span,
420                 ast::TyKind::Rptr(lifetime, self.ty_mt(ty, mutbl)))
421     }
422
423     fn ty_ptr(&self,
424               span: Span,
425               ty: P<ast::Ty>,
426               mutbl: ast::Mutability)
427         -> P<ast::Ty> {
428         self.ty(span,
429                 ast::TyKind::Ptr(self.ty_mt(ty, mutbl)))
430     }
431
432     fn ty_option(&self, ty: P<ast::Ty>) -> P<ast::Ty> {
433         self.ty_path(
434             self.path_all(DUMMY_SP,
435                           true,
436                           self.std_path(&["option", "Option"]),
437                           Vec::new(),
438                           vec![ ty ],
439                           Vec::new()))
440     }
441
442     fn ty_infer(&self, span: Span) -> P<ast::Ty> {
443         self.ty(span, ast::TyKind::Infer)
444     }
445
446     fn typaram(&self,
447                span: Span,
448                id: ast::Ident,
449                attrs: Vec<ast::Attribute>,
450                bounds: ast::TyParamBounds,
451                default: Option<P<ast::Ty>>) -> ast::TyParam {
452         ast::TyParam {
453             ident: id,
454             id: ast::DUMMY_NODE_ID,
455             attrs: attrs.into(),
456             bounds: bounds,
457             default: default,
458             span: span
459         }
460     }
461
462     fn trait_ref(&self, path: ast::Path) -> ast::TraitRef {
463         ast::TraitRef {
464             path: path,
465             ref_id: ast::DUMMY_NODE_ID,
466         }
467     }
468
469     fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef {
470         ast::PolyTraitRef {
471             bound_lifetimes: Vec::new(),
472             trait_ref: self.trait_ref(path),
473             span: span,
474         }
475     }
476
477     fn typarambound(&self, path: ast::Path) -> ast::TyParamBound {
478         ast::TraitTyParamBound(self.poly_trait_ref(path.span, path), ast::TraitBoundModifier::None)
479     }
480
481     fn lifetime(&self, span: Span, name: ast::Name) -> ast::Lifetime {
482         ast::Lifetime { id: ast::DUMMY_NODE_ID, span: span, name: name }
483     }
484
485     fn lifetime_def(&self,
486                     span: Span,
487                     name: ast::Name,
488                     attrs: Vec<ast::Attribute>,
489                     bounds: Vec<ast::Lifetime>)
490                     -> ast::LifetimeDef {
491         ast::LifetimeDef {
492             attrs: attrs.into(),
493             lifetime: self.lifetime(span, name),
494             bounds: bounds
495         }
496     }
497
498     fn stmt_expr(&self, expr: P<ast::Expr>) -> ast::Stmt {
499         ast::Stmt {
500             id: ast::DUMMY_NODE_ID,
501             span: expr.span,
502             node: ast::StmtKind::Expr(expr),
503         }
504     }
505
506     fn stmt_semi(&self, expr: P<ast::Expr>) -> ast::Stmt {
507         ast::Stmt {
508             id: ast::DUMMY_NODE_ID,
509             span: expr.span,
510             node: ast::StmtKind::Semi(expr),
511         }
512     }
513
514     fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident,
515                 ex: P<ast::Expr>) -> ast::Stmt {
516         let pat = if mutbl {
517             let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Mutable);
518             self.pat_ident_binding_mode(sp, ident, binding_mode)
519         } else {
520             self.pat_ident(sp, ident)
521         };
522         let local = P(ast::Local {
523             pat: pat,
524             ty: None,
525             init: Some(ex),
526             id: ast::DUMMY_NODE_ID,
527             span: sp,
528             attrs: ast::ThinVec::new(),
529         });
530         ast::Stmt {
531             id: ast::DUMMY_NODE_ID,
532             node: ast::StmtKind::Local(local),
533             span: sp,
534         }
535     }
536
537     fn stmt_let_typed(&self,
538                       sp: Span,
539                       mutbl: bool,
540                       ident: ast::Ident,
541                       typ: P<ast::Ty>,
542                       ex: P<ast::Expr>)
543                       -> ast::Stmt {
544         let pat = if mutbl {
545             let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Mutable);
546             self.pat_ident_binding_mode(sp, ident, binding_mode)
547         } else {
548             self.pat_ident(sp, ident)
549         };
550         let local = P(ast::Local {
551             pat: pat,
552             ty: Some(typ),
553             init: Some(ex),
554             id: ast::DUMMY_NODE_ID,
555             span: sp,
556             attrs: ast::ThinVec::new(),
557         });
558         ast::Stmt {
559             id: ast::DUMMY_NODE_ID,
560             node: ast::StmtKind::Local(local),
561             span: sp,
562         }
563     }
564
565     // Generate `let _: Type;`, usually used for type assertions.
566     fn stmt_let_type_only(&self, span: Span, ty: P<ast::Ty>) -> ast::Stmt {
567         let local = P(ast::Local {
568             pat: self.pat_wild(span),
569             ty: Some(ty),
570             init: None,
571             id: ast::DUMMY_NODE_ID,
572             span: span,
573             attrs: ast::ThinVec::new(),
574         });
575         ast::Stmt {
576             id: ast::DUMMY_NODE_ID,
577             node: ast::StmtKind::Local(local),
578             span: span,
579         }
580     }
581
582     fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> ast::Stmt {
583         ast::Stmt {
584             id: ast::DUMMY_NODE_ID,
585             node: ast::StmtKind::Item(item),
586             span: sp,
587         }
588     }
589
590     fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> {
591         self.block(expr.span, vec![ast::Stmt {
592             id: ast::DUMMY_NODE_ID,
593             span: expr.span,
594             node: ast::StmtKind::Expr(expr),
595         }])
596     }
597     fn block(&self, span: Span, stmts: Vec<ast::Stmt>) -> P<ast::Block> {
598         P(ast::Block {
599            stmts: stmts,
600            id: ast::DUMMY_NODE_ID,
601            rules: BlockCheckMode::Default,
602            span: span,
603         })
604     }
605
606     fn expr(&self, span: Span, node: ast::ExprKind) -> P<ast::Expr> {
607         P(ast::Expr {
608             id: ast::DUMMY_NODE_ID,
609             node: node,
610             span: span,
611             attrs: ast::ThinVec::new(),
612         })
613     }
614
615     fn expr_path(&self, path: ast::Path) -> P<ast::Expr> {
616         self.expr(path.span, ast::ExprKind::Path(None, path))
617     }
618
619     /// Constructs a QPath expression.
620     fn expr_qpath(&self, span: Span, qself: ast::QSelf, path: ast::Path) -> P<ast::Expr> {
621         self.expr(span, ast::ExprKind::Path(Some(qself), path))
622     }
623
624     fn expr_ident(&self, span: Span, id: ast::Ident) -> P<ast::Expr> {
625         self.expr_path(self.path_ident(span, id))
626     }
627     fn expr_self(&self, span: Span) -> P<ast::Expr> {
628         self.expr_ident(span, keywords::SelfValue.ident())
629     }
630
631     fn expr_binary(&self, sp: Span, op: ast::BinOpKind,
632                    lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> P<ast::Expr> {
633         self.expr(sp, ast::ExprKind::Binary(Spanned { node: op, span: sp }, lhs, rhs))
634     }
635
636     fn expr_deref(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> {
637         self.expr_unary(sp, UnOp::Deref, e)
638     }
639     fn expr_unary(&self, sp: Span, op: ast::UnOp, e: P<ast::Expr>) -> P<ast::Expr> {
640         self.expr(sp, ast::ExprKind::Unary(op, e))
641     }
642
643     fn expr_field_access(&self, sp: Span, expr: P<ast::Expr>, ident: ast::Ident) -> P<ast::Expr> {
644         let id = Spanned { node: ident, span: sp };
645         self.expr(sp, ast::ExprKind::Field(expr, id))
646     }
647     fn expr_tup_field_access(&self, sp: Span, expr: P<ast::Expr>, idx: usize) -> P<ast::Expr> {
648         let id = Spanned { node: idx, span: sp };
649         self.expr(sp, ast::ExprKind::TupField(expr, id))
650     }
651     fn expr_addr_of(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> {
652         self.expr(sp, ast::ExprKind::AddrOf(ast::Mutability::Immutable, e))
653     }
654     fn expr_mut_addr_of(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> {
655         self.expr(sp, ast::ExprKind::AddrOf(ast::Mutability::Mutable, e))
656     }
657
658     fn expr_call(&self, span: Span, expr: P<ast::Expr>, args: Vec<P<ast::Expr>>) -> P<ast::Expr> {
659         self.expr(span, ast::ExprKind::Call(expr, args))
660     }
661     fn expr_call_ident(&self, span: Span, id: ast::Ident,
662                        args: Vec<P<ast::Expr>>) -> P<ast::Expr> {
663         self.expr(span, ast::ExprKind::Call(self.expr_ident(span, id), args))
664     }
665     fn expr_call_global(&self, sp: Span, fn_path: Vec<ast::Ident> ,
666                       args: Vec<P<ast::Expr>> ) -> P<ast::Expr> {
667         let pathexpr = self.expr_path(self.path_global(sp, fn_path));
668         self.expr_call(sp, pathexpr, args)
669     }
670     fn expr_method_call(&self, span: Span,
671                         expr: P<ast::Expr>,
672                         ident: ast::Ident,
673                         mut args: Vec<P<ast::Expr>> ) -> P<ast::Expr> {
674         let id = Spanned { node: ident, span: span };
675         args.insert(0, expr);
676         self.expr(span, ast::ExprKind::MethodCall(id, Vec::new(), args))
677     }
678     fn expr_block(&self, b: P<ast::Block>) -> P<ast::Expr> {
679         self.expr(b.span, ast::ExprKind::Block(b))
680     }
681     fn field_imm(&self, span: Span, name: Ident, e: P<ast::Expr>) -> ast::Field {
682         ast::Field {
683             ident: respan(span, name),
684             expr: e,
685             span: span,
686             is_shorthand: false,
687             attrs: ast::ThinVec::new(),
688         }
689     }
690     fn expr_struct(&self, span: Span, path: ast::Path, fields: Vec<ast::Field>) -> P<ast::Expr> {
691         self.expr(span, ast::ExprKind::Struct(path, fields, None))
692     }
693     fn expr_struct_ident(&self, span: Span,
694                          id: ast::Ident, fields: Vec<ast::Field>) -> P<ast::Expr> {
695         self.expr_struct(span, self.path_ident(span, id), fields)
696     }
697
698     fn expr_lit(&self, sp: Span, lit: ast::LitKind) -> P<ast::Expr> {
699         self.expr(sp, ast::ExprKind::Lit(P(respan(sp, lit))))
700     }
701     fn expr_usize(&self, span: Span, i: usize) -> P<ast::Expr> {
702         self.expr_lit(span, ast::LitKind::Int(i as u128,
703                                               ast::LitIntType::Unsigned(ast::UintTy::Us)))
704     }
705     fn expr_isize(&self, sp: Span, i: isize) -> P<ast::Expr> {
706         if i < 0 {
707             let i = (-i) as u128;
708             let lit_ty = ast::LitIntType::Signed(ast::IntTy::Is);
709             let lit = self.expr_lit(sp, ast::LitKind::Int(i, lit_ty));
710             self.expr_unary(sp, ast::UnOp::Neg, lit)
711         } else {
712             self.expr_lit(sp, ast::LitKind::Int(i as u128,
713                                                 ast::LitIntType::Signed(ast::IntTy::Is)))
714         }
715     }
716     fn expr_u32(&self, sp: Span, u: u32) -> P<ast::Expr> {
717         self.expr_lit(sp, ast::LitKind::Int(u as u128,
718                                             ast::LitIntType::Unsigned(ast::UintTy::U32)))
719     }
720     fn expr_u8(&self, sp: Span, u: u8) -> P<ast::Expr> {
721         self.expr_lit(sp, ast::LitKind::Int(u as u128, ast::LitIntType::Unsigned(ast::UintTy::U8)))
722     }
723     fn expr_bool(&self, sp: Span, value: bool) -> P<ast::Expr> {
724         self.expr_lit(sp, ast::LitKind::Bool(value))
725     }
726
727     fn expr_vec(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
728         self.expr(sp, ast::ExprKind::Array(exprs))
729     }
730     fn expr_vec_ng(&self, sp: Span) -> P<ast::Expr> {
731         self.expr_call_global(sp, self.std_path(&["vec", "Vec", "new"]),
732                               Vec::new())
733     }
734     fn expr_vec_slice(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
735         self.expr_addr_of(sp, self.expr_vec(sp, exprs))
736     }
737     fn expr_str(&self, sp: Span, s: Symbol) -> P<ast::Expr> {
738         self.expr_lit(sp, ast::LitKind::Str(s, ast::StrStyle::Cooked))
739     }
740
741     fn expr_cast(&self, sp: Span, expr: P<ast::Expr>, ty: P<ast::Ty>) -> P<ast::Expr> {
742         self.expr(sp, ast::ExprKind::Cast(expr, ty))
743     }
744
745
746     fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
747         let some = self.std_path(&["option", "Option", "Some"]);
748         self.expr_call_global(sp, some, vec![expr])
749     }
750
751     fn expr_none(&self, sp: Span) -> P<ast::Expr> {
752         let none = self.std_path(&["option", "Option", "None"]);
753         let none = self.path_global(sp, none);
754         self.expr_path(none)
755     }
756
757
758     fn expr_break(&self, sp: Span) -> P<ast::Expr> {
759         self.expr(sp, ast::ExprKind::Break(None, None))
760     }
761
762
763     fn expr_tuple(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
764         self.expr(sp, ast::ExprKind::Tup(exprs))
765     }
766
767     fn expr_fail(&self, span: Span, msg: Symbol) -> P<ast::Expr> {
768         let loc = self.codemap().lookup_char_pos(span.lo);
769         let expr_file = self.expr_str(span, Symbol::intern(&loc.file.name));
770         let expr_line = self.expr_u32(span, loc.line as u32);
771         let expr_file_line_tuple = self.expr_tuple(span, vec![expr_file, expr_line]);
772         let expr_file_line_ptr = self.expr_addr_of(span, expr_file_line_tuple);
773         self.expr_call_global(
774             span,
775             self.std_path(&["rt", "begin_panic"]),
776             vec![
777                 self.expr_str(span, msg),
778                 expr_file_line_ptr])
779     }
780
781     fn expr_unreachable(&self, span: Span) -> P<ast::Expr> {
782         self.expr_fail(span, Symbol::intern("internal error: entered unreachable code"))
783     }
784
785     fn expr_ok(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
786         let ok = self.std_path(&["result", "Result", "Ok"]);
787         self.expr_call_global(sp, ok, vec![expr])
788     }
789
790     fn expr_err(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
791         let err = self.std_path(&["result", "Result", "Err"]);
792         self.expr_call_global(sp, err, vec![expr])
793     }
794
795     fn expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr> {
796         let ok = self.std_path(&["result", "Result", "Ok"]);
797         let ok_path = self.path_global(sp, ok);
798         let err = self.std_path(&["result", "Result", "Err"]);
799         let err_path = self.path_global(sp, err);
800
801         let binding_variable = self.ident_of("__try_var");
802         let binding_pat = self.pat_ident(sp, binding_variable);
803         let binding_expr = self.expr_ident(sp, binding_variable);
804
805         // Ok(__try_var) pattern
806         let ok_pat = self.pat_tuple_struct(sp, ok_path, vec![binding_pat.clone()]);
807
808         // Err(__try_var)  (pattern and expression resp.)
809         let err_pat = self.pat_tuple_struct(sp, err_path.clone(), vec![binding_pat]);
810         let err_inner_expr = self.expr_call(sp, self.expr_path(err_path),
811                                             vec![binding_expr.clone()]);
812         // return Err(__try_var)
813         let err_expr = self.expr(sp, ast::ExprKind::Ret(Some(err_inner_expr)));
814
815         // Ok(__try_var) => __try_var
816         let ok_arm = self.arm(sp, vec![ok_pat], binding_expr);
817         // Err(__try_var) => return Err(__try_var)
818         let err_arm = self.arm(sp, vec![err_pat], err_expr);
819
820         // match head { Ok() => ..., Err() => ... }
821         self.expr_match(sp, head, vec![ok_arm, err_arm])
822     }
823
824
825     fn pat(&self, span: Span, pat: PatKind) -> P<ast::Pat> {
826         P(ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span: span })
827     }
828     fn pat_wild(&self, span: Span) -> P<ast::Pat> {
829         self.pat(span, PatKind::Wild)
830     }
831     fn pat_lit(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Pat> {
832         self.pat(span, PatKind::Lit(expr))
833     }
834     fn pat_ident(&self, span: Span, ident: ast::Ident) -> P<ast::Pat> {
835         let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Immutable);
836         self.pat_ident_binding_mode(span, ident, binding_mode)
837     }
838
839     fn pat_ident_binding_mode(&self,
840                               span: Span,
841                               ident: ast::Ident,
842                               bm: ast::BindingMode) -> P<ast::Pat> {
843         let pat = PatKind::Ident(bm, Spanned{span: span, node: ident}, None);
844         self.pat(span, pat)
845     }
846     fn pat_path(&self, span: Span, path: ast::Path) -> P<ast::Pat> {
847         self.pat(span, PatKind::Path(None, path))
848     }
849     fn pat_tuple_struct(&self, span: Span, path: ast::Path,
850                         subpats: Vec<P<ast::Pat>>) -> P<ast::Pat> {
851         self.pat(span, PatKind::TupleStruct(path, subpats, None))
852     }
853     fn pat_struct(&self, span: Span, path: ast::Path,
854                   field_pats: Vec<Spanned<ast::FieldPat>>) -> P<ast::Pat> {
855         self.pat(span, PatKind::Struct(path, field_pats, false))
856     }
857     fn pat_tuple(&self, span: Span, pats: Vec<P<ast::Pat>>) -> P<ast::Pat> {
858         self.pat(span, PatKind::Tuple(pats, None))
859     }
860
861     fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
862         let some = self.std_path(&["option", "Option", "Some"]);
863         let path = self.path_global(span, some);
864         self.pat_tuple_struct(span, path, vec![pat])
865     }
866
867     fn pat_none(&self, span: Span) -> P<ast::Pat> {
868         let some = self.std_path(&["option", "Option", "None"]);
869         let path = self.path_global(span, some);
870         self.pat_path(span, path)
871     }
872
873     fn pat_ok(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
874         let some = self.std_path(&["result", "Result", "Ok"]);
875         let path = self.path_global(span, some);
876         self.pat_tuple_struct(span, path, vec![pat])
877     }
878
879     fn pat_err(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
880         let some = self.std_path(&["result", "Result", "Err"]);
881         let path = self.path_global(span, some);
882         self.pat_tuple_struct(span, path, vec![pat])
883     }
884
885     fn arm(&self, _span: Span, pats: Vec<P<ast::Pat>>, expr: P<ast::Expr>) -> ast::Arm {
886         ast::Arm {
887             attrs: vec![],
888             pats: pats,
889             guard: None,
890             body: expr
891         }
892     }
893
894     fn arm_unreachable(&self, span: Span) -> ast::Arm {
895         self.arm(span, vec![self.pat_wild(span)], self.expr_unreachable(span))
896     }
897
898     fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: Vec<ast::Arm>) -> P<Expr> {
899         self.expr(span, ast::ExprKind::Match(arg, arms))
900     }
901
902     fn expr_if(&self, span: Span, cond: P<ast::Expr>,
903                then: P<ast::Expr>, els: Option<P<ast::Expr>>) -> P<ast::Expr> {
904         let els = els.map(|x| self.expr_block(self.block_expr(x)));
905         self.expr(span, ast::ExprKind::If(cond, self.block_expr(then), els))
906     }
907
908     fn expr_loop(&self, span: Span, block: P<ast::Block>) -> P<ast::Expr> {
909         self.expr(span, ast::ExprKind::Loop(block, None))
910     }
911
912     fn lambda_fn_decl(&self,
913                       span: Span,
914                       fn_decl: P<ast::FnDecl>,
915                       body: P<ast::Expr>,
916                       fn_decl_span: Span) // span of the `|...|` part
917                       -> P<ast::Expr> {
918         self.expr(span, ast::ExprKind::Closure(ast::CaptureBy::Ref,
919                                                fn_decl,
920                                                body,
921                                                fn_decl_span))
922     }
923
924     fn lambda(&self,
925               span: Span,
926               ids: Vec<ast::Ident>,
927               body: P<ast::Expr>)
928               -> P<ast::Expr> {
929         let fn_decl = self.fn_decl(
930             ids.iter().map(|id| self.arg(span, *id, self.ty_infer(span))).collect(),
931             self.ty_infer(span));
932
933         // FIXME -- We are using `span` as the span of the `|...|`
934         // part of the lambda, but it probably (maybe?) corresponds to
935         // the entire lambda body. Probably we should extend the API
936         // here, but that's not entirely clear.
937         self.expr(span, ast::ExprKind::Closure(ast::CaptureBy::Ref, fn_decl, body, span))
938     }
939
940     fn lambda0(&self, span: Span, body: P<ast::Expr>) -> P<ast::Expr> {
941         self.lambda(span, Vec::new(), body)
942     }
943
944     fn lambda1(&self, span: Span, body: P<ast::Expr>, ident: ast::Ident) -> P<ast::Expr> {
945         self.lambda(span, vec![ident], body)
946     }
947
948     fn lambda_stmts(&self,
949                     span: Span,
950                     ids: Vec<ast::Ident>,
951                     stmts: Vec<ast::Stmt>)
952                     -> P<ast::Expr> {
953         self.lambda(span, ids, self.expr_block(self.block(span, stmts)))
954     }
955     fn lambda_stmts_0(&self, span: Span, stmts: Vec<ast::Stmt>) -> P<ast::Expr> {
956         self.lambda0(span, self.expr_block(self.block(span, stmts)))
957     }
958     fn lambda_stmts_1(&self, span: Span, stmts: Vec<ast::Stmt>,
959                       ident: ast::Ident) -> P<ast::Expr> {
960         self.lambda1(span, self.expr_block(self.block(span, stmts)), ident)
961     }
962
963     fn arg(&self, span: Span, ident: ast::Ident, ty: P<ast::Ty>) -> ast::Arg {
964         let arg_pat = self.pat_ident(span, ident);
965         ast::Arg {
966             ty: ty,
967             pat: arg_pat,
968             id: ast::DUMMY_NODE_ID
969         }
970     }
971
972     // FIXME unused self
973     fn fn_decl(&self, inputs: Vec<ast::Arg>, output: P<ast::Ty>) -> P<ast::FnDecl> {
974         P(ast::FnDecl {
975             inputs: inputs,
976             output: ast::FunctionRetTy::Ty(output),
977             variadic: false
978         })
979     }
980
981     fn item(&self, span: Span, name: Ident,
982             attrs: Vec<ast::Attribute>, node: ast::ItemKind) -> P<ast::Item> {
983         // FIXME: Would be nice if our generated code didn't violate
984         // Rust coding conventions
985         P(ast::Item {
986             ident: name,
987             attrs: attrs,
988             id: ast::DUMMY_NODE_ID,
989             node: node,
990             vis: ast::Visibility::Inherited,
991             span: span
992         })
993     }
994
995     fn item_fn_poly(&self,
996                     span: Span,
997                     name: Ident,
998                     inputs: Vec<ast::Arg> ,
999                     output: P<ast::Ty>,
1000                     generics: Generics,
1001                     body: P<ast::Block>) -> P<ast::Item> {
1002         self.item(span,
1003                   name,
1004                   Vec::new(),
1005                   ast::ItemKind::Fn(self.fn_decl(inputs, output),
1006                               ast::Unsafety::Normal,
1007                               dummy_spanned(ast::Constness::NotConst),
1008                               Abi::Rust,
1009                               generics,
1010                               body))
1011     }
1012
1013     fn item_fn(&self,
1014                span: Span,
1015                name: Ident,
1016                inputs: Vec<ast::Arg> ,
1017                output: P<ast::Ty>,
1018                body: P<ast::Block>
1019               ) -> P<ast::Item> {
1020         self.item_fn_poly(
1021             span,
1022             name,
1023             inputs,
1024             output,
1025             Generics::default(),
1026             body)
1027     }
1028
1029     fn variant(&self, span: Span, name: Ident, tys: Vec<P<ast::Ty>> ) -> ast::Variant {
1030         let fields: Vec<_> = tys.into_iter().map(|ty| {
1031             ast::StructField {
1032                 span: ty.span,
1033                 ty: ty,
1034                 ident: None,
1035                 vis: ast::Visibility::Inherited,
1036                 attrs: Vec::new(),
1037                 id: ast::DUMMY_NODE_ID,
1038             }
1039         }).collect();
1040
1041         let vdata = if fields.is_empty() {
1042             ast::VariantData::Unit(ast::DUMMY_NODE_ID)
1043         } else {
1044             ast::VariantData::Tuple(fields, ast::DUMMY_NODE_ID)
1045         };
1046
1047         respan(span,
1048                ast::Variant_ {
1049                    name: name,
1050                    attrs: Vec::new(),
1051                    data: vdata,
1052                    disr_expr: None,
1053                })
1054     }
1055
1056     fn item_enum_poly(&self, span: Span, name: Ident,
1057                       enum_definition: ast::EnumDef,
1058                       generics: Generics) -> P<ast::Item> {
1059         self.item(span, name, Vec::new(), ast::ItemKind::Enum(enum_definition, generics))
1060     }
1061
1062     fn item_enum(&self, span: Span, name: Ident,
1063                  enum_definition: ast::EnumDef) -> P<ast::Item> {
1064         self.item_enum_poly(span, name, enum_definition,
1065                             Generics::default())
1066     }
1067
1068     fn item_struct(&self, span: Span, name: Ident,
1069                    struct_def: ast::VariantData) -> P<ast::Item> {
1070         self.item_struct_poly(
1071             span,
1072             name,
1073             struct_def,
1074             Generics::default()
1075         )
1076     }
1077
1078     fn item_struct_poly(&self, span: Span, name: Ident,
1079         struct_def: ast::VariantData, generics: Generics) -> P<ast::Item> {
1080         self.item(span, name, Vec::new(), ast::ItemKind::Struct(struct_def, generics))
1081     }
1082
1083     fn item_mod(&self, span: Span, inner_span: Span, name: Ident,
1084                 attrs: Vec<ast::Attribute>,
1085                 items: Vec<P<ast::Item>>) -> P<ast::Item> {
1086         self.item(
1087             span,
1088             name,
1089             attrs,
1090             ast::ItemKind::Mod(ast::Mod {
1091                 inner: inner_span,
1092                 items: items,
1093             })
1094         )
1095     }
1096
1097     fn item_static(&self,
1098                    span: Span,
1099                    name: Ident,
1100                    ty: P<ast::Ty>,
1101                    mutbl: ast::Mutability,
1102                    expr: P<ast::Expr>)
1103                    -> P<ast::Item> {
1104         self.item(span, name, Vec::new(), ast::ItemKind::Static(ty, mutbl, expr))
1105     }
1106
1107     fn item_const(&self,
1108                   span: Span,
1109                   name: Ident,
1110                   ty: P<ast::Ty>,
1111                   expr: P<ast::Expr>)
1112                   -> P<ast::Item> {
1113         self.item(span, name, Vec::new(), ast::ItemKind::Const(ty, expr))
1114     }
1115
1116     fn item_ty_poly(&self, span: Span, name: Ident, ty: P<ast::Ty>,
1117                     generics: Generics) -> P<ast::Item> {
1118         self.item(span, name, Vec::new(), ast::ItemKind::Ty(ty, generics))
1119     }
1120
1121     fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> P<ast::Item> {
1122         self.item_ty_poly(span, name, ty, Generics::default())
1123     }
1124
1125     fn attribute(&self, sp: Span, mi: ast::MetaItem) -> ast::Attribute {
1126         attr::mk_spanned_attr_outer(sp, attr::mk_attr_id(), mi)
1127     }
1128
1129     fn meta_word(&self, sp: Span, w: ast::Name) -> ast::MetaItem {
1130         attr::mk_spanned_word_item(sp, w)
1131     }
1132
1133     fn meta_list_item_word(&self, sp: Span, w: ast::Name) -> ast::NestedMetaItem {
1134         respan(sp, ast::NestedMetaItemKind::MetaItem(attr::mk_spanned_word_item(sp, w)))
1135     }
1136
1137     fn meta_list(&self, sp: Span, name: ast::Name, mis: Vec<ast::NestedMetaItem>)
1138                  -> ast::MetaItem {
1139         attr::mk_spanned_list_item(sp, name, mis)
1140     }
1141
1142     fn meta_name_value(&self, sp: Span, name: ast::Name, value: ast::LitKind)
1143                        -> ast::MetaItem {
1144         attr::mk_spanned_name_value_item(sp, name, respan(sp, value))
1145     }
1146
1147     fn item_use(&self, sp: Span,
1148                 vis: ast::Visibility, vp: P<ast::ViewPath>) -> P<ast::Item> {
1149         P(ast::Item {
1150             id: ast::DUMMY_NODE_ID,
1151             ident: keywords::Invalid.ident(),
1152             attrs: vec![],
1153             node: ast::ItemKind::Use(vp),
1154             vis: vis,
1155             span: sp
1156         })
1157     }
1158
1159     fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P<ast::Item> {
1160         let last = path.segments.last().unwrap().identifier;
1161         self.item_use_simple_(sp, vis, last, path)
1162     }
1163
1164     fn item_use_simple_(&self, sp: Span, vis: ast::Visibility,
1165                         ident: ast::Ident, path: ast::Path) -> P<ast::Item> {
1166         self.item_use(sp, vis,
1167                       P(respan(sp,
1168                                ast::ViewPathSimple(ident,
1169                                                    path))))
1170     }
1171
1172     fn item_use_list(&self, sp: Span, vis: ast::Visibility,
1173                      path: Vec<ast::Ident>, imports: &[ast::Ident]) -> P<ast::Item> {
1174         let imports = imports.iter().map(|id| {
1175             let item = ast::PathListItem_ {
1176                 name: *id,
1177                 rename: None,
1178                 id: ast::DUMMY_NODE_ID,
1179             };
1180             respan(sp, item)
1181         }).collect();
1182
1183         self.item_use(sp, vis,
1184                       P(respan(sp,
1185                                ast::ViewPathList(self.path(sp, path),
1186                                                  imports))))
1187     }
1188
1189     fn item_use_glob(&self, sp: Span,
1190                      vis: ast::Visibility, path: Vec<ast::Ident>) -> P<ast::Item> {
1191         self.item_use(sp, vis,
1192                       P(respan(sp,
1193                                ast::ViewPathGlob(self.path(sp, path)))))
1194     }
1195 }