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