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