]> git.lizzy.rs Git - rust.git/blob - src/librustc_front/lowering.rs
c3544ff1aa0a48f3251a802ef24f23a2fa2b6d92
[rust.git] / src / librustc_front / lowering.rs
1 // Copyright 2015 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 // Lowers the AST to the HIR
12
13 use hir;
14
15 use syntax::ast::*;
16 use syntax::ptr::P;
17 use syntax::codemap::{respan, Spanned};
18 use syntax::owned_slice::OwnedSlice;
19
20 pub struct LoweringContext<'hir> {
21     // TODO
22     foo: &'hir i32,
23 }
24
25 impl<'hir> LoweringContext<'hir> {
26     pub fn new(foo: &'hir i32) -> LoweringContext<'hir> {
27         LoweringContext {
28             foo: foo,
29         }
30     }
31 }
32
33 pub fn lower_view_path(_lctx: &LoweringContext, view_path: &ViewPath) -> P<hir::ViewPath> {
34     P(Spanned {
35         node: match view_path.node {
36             ViewPathSimple(ident, ref path) => {
37                 hir::ViewPathSimple(ident.name, lower_path(_lctx, path))
38             }
39             ViewPathGlob(ref path) => {
40                 hir::ViewPathGlob(lower_path(_lctx, path))
41             }
42             ViewPathList(ref path, ref path_list_idents) => {
43                 hir::ViewPathList(lower_path(_lctx, path),
44                              path_list_idents.iter().map(|path_list_ident| {
45                                 Spanned {
46                                     node: match path_list_ident.node {
47                                         PathListIdent { id, name, rename } =>
48                                             hir::PathListIdent {
49                                                 id: id,
50                                                 name: name.name,
51                                                 rename: rename.map(|x| x.name),
52                                             },
53                                         PathListMod { id, rename } =>
54                                             hir::PathListMod {
55                                                 id: id,
56                                                 rename: rename.map(|x| x.name)
57                                             }
58                                     },
59                                     span: path_list_ident.span
60                                 }
61                              }).collect())
62             }
63         },
64         span: view_path.span,
65     })
66 }
67
68 pub fn lower_arm(_lctx: &LoweringContext, arm: &Arm) -> hir::Arm {
69     hir::Arm {
70         attrs: arm.attrs.clone(),
71         pats: arm.pats.iter().map(|x| lower_pat(_lctx, x)).collect(),
72         guard: arm.guard.as_ref().map(|ref x| lower_expr(_lctx, x)),
73         body: lower_expr(_lctx, &arm.body),
74     }
75 }
76
77 pub fn lower_decl(_lctx: &LoweringContext, d: &Decl) -> P<hir::Decl> {
78     match d.node {
79         DeclLocal(ref l) => P(Spanned {
80             node: hir::DeclLocal(lower_local(_lctx, l)),
81             span: d.span
82         }),
83         DeclItem(ref it) => P(Spanned {
84             node: hir::DeclItem(lower_item(_lctx, it)),
85             span: d.span
86         }),
87     }
88 }
89
90 pub fn lower_ty_binding(_lctx: &LoweringContext, b: &TypeBinding) -> P<hir::TypeBinding> {
91     P(hir::TypeBinding { id: b.id, name: b.ident.name, ty: lower_ty(_lctx, &b.ty), span: b.span })
92 }
93
94 pub fn lower_ty(_lctx: &LoweringContext, t: &Ty) -> P<hir::Ty> {
95     P(hir::Ty {
96         id: t.id,
97         node: match t.node {
98             TyInfer => hir::TyInfer,
99             TyVec(ref ty) => hir::TyVec(lower_ty(_lctx, ty)),
100             TyPtr(ref mt) => hir::TyPtr(lower_mt(_lctx, mt)),
101             TyRptr(ref region, ref mt) => {
102                 hir::TyRptr(lower_opt_lifetime(_lctx, region), lower_mt(_lctx, mt))
103             }
104             TyBareFn(ref f) => {
105                 hir::TyBareFn(P(hir::BareFnTy {
106                     lifetimes: lower_lifetime_defs(_lctx, &f.lifetimes),
107                     unsafety: lower_unsafety(_lctx, f.unsafety),
108                     abi: f.abi,
109                     decl: lower_fn_decl(_lctx, &f.decl),
110                 }))
111             }
112             TyTup(ref tys) => hir::TyTup(tys.iter().map(|ty| lower_ty(_lctx, ty)).collect()),
113             TyParen(ref ty) => hir::TyParen(lower_ty(_lctx, ty)),
114             TyPath(ref qself, ref path) => {
115                 let qself = qself.as_ref().map(|&QSelf { ref ty, position }| {
116                     hir::QSelf {
117                         ty: lower_ty(_lctx, ty),
118                         position: position,
119                     }
120                 });
121                 hir::TyPath(qself, lower_path(_lctx, path))
122             }
123             TyObjectSum(ref ty, ref bounds) => {
124                 hir::TyObjectSum(lower_ty(_lctx, ty),
125                             lower_bounds(_lctx, bounds))
126             }
127             TyFixedLengthVec(ref ty, ref e) => {
128                 hir::TyFixedLengthVec(lower_ty(_lctx, ty), lower_expr(_lctx, e))
129             }
130             TyTypeof(ref expr) => {
131                 hir::TyTypeof(lower_expr(_lctx, expr))
132             }
133             TyPolyTraitRef(ref bounds) => {
134                 hir::TyPolyTraitRef(bounds.iter().map(|b| lower_ty_param_bound(_lctx, b)).collect())
135             }
136             TyMac(_) => panic!("TyMac should have been expanded by now."),
137         },
138         span: t.span,
139     })
140 }
141
142 pub fn lower_foreign_mod(_lctx: &LoweringContext, fm: &ForeignMod) -> hir::ForeignMod {
143     hir::ForeignMod {
144         abi: fm.abi,
145         items: fm.items.iter().map(|x| lower_foreign_item(_lctx, x)).collect(),
146     }
147 }
148
149 pub fn lower_variant(_lctx: &LoweringContext, v: &Variant) -> P<hir::Variant> {
150     P(Spanned {
151         node: hir::Variant_ {
152             id: v.node.id,
153             name: v.node.name.name,
154             attrs: v.node.attrs.clone(),
155             kind: match v.node.kind {
156                 TupleVariantKind(ref variant_args) => {
157                     hir::TupleVariantKind(variant_args.iter().map(|ref x|
158                         lower_variant_arg(_lctx, x)).collect())
159                 }
160                 StructVariantKind(ref struct_def) => {
161                     hir::StructVariantKind(lower_struct_def(_lctx, struct_def))
162                 }
163             },
164             disr_expr: v.node.disr_expr.as_ref().map(|e| lower_expr(_lctx, e)),
165         },
166         span: v.span,
167     })
168 }
169
170 pub fn lower_path(_lctx: &LoweringContext, p: &Path) -> hir::Path {
171     hir::Path {
172         global: p.global,
173         segments: p.segments.iter().map(|&PathSegment {identifier, ref parameters}|
174             hir::PathSegment {
175                 identifier: identifier,
176                 parameters: lower_path_parameters(_lctx, parameters),
177             }).collect(),
178         span: p.span,
179     }
180 }
181
182 pub fn lower_path_parameters(_lctx: &LoweringContext,
183                              path_parameters: &PathParameters)
184                              -> hir::PathParameters {
185     match *path_parameters {
186         AngleBracketedParameters(ref data) =>
187             hir::AngleBracketedParameters(lower_angle_bracketed_parameter_data(_lctx, data)),
188         ParenthesizedParameters(ref data) =>
189             hir::ParenthesizedParameters(lower_parenthesized_parameter_data(_lctx, data)),
190     }
191 }
192
193 pub fn lower_angle_bracketed_parameter_data(_lctx: &LoweringContext,
194                                             data: &AngleBracketedParameterData)
195                                             -> hir::AngleBracketedParameterData {
196     let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings } = data;
197     hir::AngleBracketedParameterData {
198         lifetimes: lower_lifetimes(_lctx, lifetimes),
199         types: types.iter().map(|ty| lower_ty(_lctx, ty)).collect(),
200         bindings: bindings.iter().map(|b| lower_ty_binding(_lctx, b)).collect(),
201     }
202 }
203
204 pub fn lower_parenthesized_parameter_data(_lctx: &LoweringContext,
205                                           data: &ParenthesizedParameterData)
206                                           -> hir::ParenthesizedParameterData {
207     let &ParenthesizedParameterData { ref inputs, ref output, span } = data;
208     hir::ParenthesizedParameterData {
209         inputs: inputs.iter().map(|ty| lower_ty(_lctx, ty)).collect(),
210         output: output.as_ref().map(|ty| lower_ty(_lctx, ty)),
211         span: span,
212     }
213 }
214
215 pub fn lower_local(_lctx: &LoweringContext, l: &Local) -> P<hir::Local> {
216     P(hir::Local {
217             id: l.id,
218             ty: l.ty.as_ref().map(|t| lower_ty(_lctx, t)),
219             pat: lower_pat(_lctx, &l.pat),
220             init: l.init.as_ref().map(|e| lower_expr(_lctx, e)),
221             span: l.span,
222         })
223 }
224
225 pub fn lower_explicit_self_underscore(_lctx: &LoweringContext,
226                                       es: &ExplicitSelf_)
227                                       -> hir::ExplicitSelf_ {
228     match *es {
229         SelfStatic => hir::SelfStatic,
230         SelfValue(v) => hir::SelfValue(v.name),
231         SelfRegion(ref lifetime, m, ident) => {
232             hir::SelfRegion(lower_opt_lifetime(_lctx, lifetime),
233                             lower_mutability(_lctx, m),
234                             ident.name)
235         }
236         SelfExplicit(ref typ, ident) => {
237             hir::SelfExplicit(lower_ty(_lctx, typ), ident.name)
238         }
239     }
240 }
241
242 pub fn lower_mutability(_lctx: &LoweringContext, m: Mutability) -> hir::Mutability {
243     match m {
244         MutMutable => hir::MutMutable,
245         MutImmutable => hir::MutImmutable,
246     }
247 }
248
249 pub fn lower_explicit_self(_lctx: &LoweringContext, s: &ExplicitSelf) -> hir::ExplicitSelf {
250     Spanned { node: lower_explicit_self_underscore(_lctx, &s.node), span: s.span }
251 }
252
253 pub fn lower_arg(_lctx: &LoweringContext, arg: &Arg) -> hir::Arg {
254     hir::Arg { id: arg.id, pat: lower_pat(_lctx, &arg.pat), ty: lower_ty(_lctx, &arg.ty) }
255 }
256
257 pub fn lower_fn_decl(_lctx: &LoweringContext, decl: &FnDecl) -> P<hir::FnDecl> {
258     P(hir::FnDecl {
259         inputs: decl.inputs.iter().map(|x| lower_arg(_lctx, x)).collect(),
260         output: match decl.output {
261             Return(ref ty) => hir::Return(lower_ty(_lctx, ty)),
262             DefaultReturn(span) => hir::DefaultReturn(span),
263             NoReturn(span) => hir::NoReturn(span),
264         },
265         variadic: decl.variadic,
266     })
267 }
268
269 pub fn lower_ty_param_bound(_lctx: &LoweringContext, tpb: &TyParamBound) -> hir::TyParamBound {
270     match *tpb {
271         TraitTyParamBound(ref ty, modifier) => {
272             hir::TraitTyParamBound(lower_poly_trait_ref(_lctx, ty),
273                                    lower_trait_bound_modifier(_lctx, modifier))
274         }
275         RegionTyParamBound(ref lifetime) => {
276             hir::RegionTyParamBound(lower_lifetime(_lctx, lifetime))
277         }
278     }
279 }
280
281 pub fn lower_ty_param(_lctx: &LoweringContext, tp: &TyParam) -> hir::TyParam {
282     hir::TyParam {
283         id: tp.id,
284         name: tp.ident.name,
285         bounds: lower_bounds(_lctx, &tp.bounds),
286         default: tp.default.as_ref().map(|x| lower_ty(_lctx, x)),
287         span: tp.span,
288     }
289 }
290
291 pub fn lower_ty_params(_lctx: &LoweringContext,
292                        tps: &OwnedSlice<TyParam>)
293                        -> OwnedSlice<hir::TyParam> {
294     tps.iter().map(|tp| lower_ty_param(_lctx, tp)).collect()
295 }
296
297 pub fn lower_lifetime(_lctx: &LoweringContext, l: &Lifetime) -> hir::Lifetime {
298     hir::Lifetime { id: l.id, name: l.name, span: l.span }
299 }
300
301 pub fn lower_lifetime_def(_lctx: &LoweringContext, l: &LifetimeDef) -> hir::LifetimeDef {
302     hir::LifetimeDef {
303         lifetime: lower_lifetime(_lctx, &l.lifetime),
304         bounds: lower_lifetimes(_lctx, &l.bounds)
305     }
306 }
307
308 pub fn lower_lifetimes(_lctx: &LoweringContext, lts: &Vec<Lifetime>) -> Vec<hir::Lifetime> {
309     lts.iter().map(|l| lower_lifetime(_lctx, l)).collect()
310 }
311
312 pub fn lower_lifetime_defs(_lctx: &LoweringContext,
313                            lts: &Vec<LifetimeDef>)
314                            -> Vec<hir::LifetimeDef> {
315     lts.iter().map(|l| lower_lifetime_def(_lctx, l)).collect()
316 }
317
318 pub fn lower_opt_lifetime(_lctx: &LoweringContext,
319                           o_lt: &Option<Lifetime>)
320                           -> Option<hir::Lifetime> {
321     o_lt.as_ref().map(|lt| lower_lifetime(_lctx, lt))
322 }
323
324 pub fn lower_generics(_lctx: &LoweringContext, g: &Generics) -> hir::Generics {
325     hir::Generics {
326         ty_params: lower_ty_params(_lctx, &g.ty_params),
327         lifetimes: lower_lifetime_defs(_lctx, &g.lifetimes),
328         where_clause: lower_where_clause(_lctx, &g.where_clause),
329     }
330 }
331
332 pub fn lower_where_clause(_lctx: &LoweringContext, wc: &WhereClause) -> hir::WhereClause {
333     hir::WhereClause {
334         id: wc.id,
335         predicates: wc.predicates.iter().map(|predicate|
336             lower_where_predicate(_lctx, predicate)).collect(),
337     }
338 }
339
340 pub fn lower_where_predicate(_lctx: &LoweringContext,
341                              pred: &WherePredicate)
342                              -> hir::WherePredicate {
343     match *pred {
344         WherePredicate::BoundPredicate(WhereBoundPredicate{ ref bound_lifetimes,
345                                                             ref bounded_ty,
346                                                             ref bounds,
347                                                             span}) => {
348             hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
349                 bound_lifetimes: lower_lifetime_defs(_lctx, bound_lifetimes),
350                 bounded_ty: lower_ty(_lctx, bounded_ty),
351                 bounds: bounds.iter().map(|x| lower_ty_param_bound(_lctx, x)).collect(),
352                 span: span
353             })
354         }
355         WherePredicate::RegionPredicate(WhereRegionPredicate{ ref lifetime,
356                                                               ref bounds,
357                                                               span}) => {
358             hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
359                 span: span,
360                 lifetime: lower_lifetime(_lctx, lifetime),
361                 bounds: bounds.iter().map(|bound| lower_lifetime(_lctx, bound)).collect()
362             })
363         }
364         WherePredicate::EqPredicate(WhereEqPredicate{ id,
365                                                       ref path,
366                                                       ref ty,
367                                                       span}) => {
368             hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
369                 id: id,
370                 path: lower_path(_lctx, path),
371                 ty:lower_ty(_lctx, ty),
372                 span: span
373             })
374         }
375     }
376 }
377
378 pub fn lower_struct_def(_lctx: &LoweringContext, sd: &StructDef) -> P<hir::StructDef> {
379     P(hir::StructDef {
380         fields: sd.fields.iter().map(|f| lower_struct_field(_lctx, f)).collect(),
381         ctor_id: sd.ctor_id,
382     })
383 }
384
385 pub fn lower_trait_ref(_lctx: &LoweringContext, p: &TraitRef) -> hir::TraitRef {
386     hir::TraitRef { path: lower_path(_lctx, &p.path), ref_id: p.ref_id }
387 }
388
389 pub fn lower_poly_trait_ref(_lctx: &LoweringContext, p: &PolyTraitRef) -> hir::PolyTraitRef {
390     hir::PolyTraitRef {
391         bound_lifetimes: lower_lifetime_defs(_lctx, &p.bound_lifetimes),
392         trait_ref: lower_trait_ref(_lctx, &p.trait_ref),
393         span: p.span,
394     }
395 }
396
397 pub fn lower_struct_field(_lctx: &LoweringContext, f: &StructField) -> hir::StructField {
398     Spanned {
399         node: hir::StructField_ {
400             id: f.node.id,
401             kind: lower_struct_field_kind(_lctx, &f.node.kind),
402             ty: lower_ty(_lctx, &f.node.ty),
403             attrs: f.node.attrs.clone(),
404         },
405         span: f.span,
406     }
407 }
408
409 pub fn lower_field(_lctx: &LoweringContext, f: &Field) -> hir::Field {
410     hir::Field {
411         name: respan(f.ident.span, f.ident.node.name),
412         expr: lower_expr(_lctx, &f.expr), span: f.span
413     }
414 }
415
416 pub fn lower_mt(_lctx: &LoweringContext, mt: &MutTy) -> hir::MutTy {
417     hir::MutTy { ty: lower_ty(_lctx, &mt.ty), mutbl: lower_mutability(_lctx, mt.mutbl) }
418 }
419
420 pub fn lower_opt_bounds(_lctx: &LoweringContext, b: &Option<OwnedSlice<TyParamBound>>)
421                         -> Option<OwnedSlice<hir::TyParamBound>> {
422     b.as_ref().map(|ref bounds| lower_bounds(_lctx, bounds))
423 }
424
425 fn lower_bounds(_lctx: &LoweringContext, bounds: &TyParamBounds) -> hir::TyParamBounds {
426     bounds.iter().map(|bound| lower_ty_param_bound(_lctx, bound)).collect()
427 }
428
429 fn lower_variant_arg(_lctx: &LoweringContext, va: &VariantArg) -> hir::VariantArg {
430     hir::VariantArg { id: va.id, ty: lower_ty(_lctx, &va.ty) }
431 }
432
433 pub fn lower_block(_lctx: &LoweringContext, b: &Block) -> P<hir::Block> {
434     P(hir::Block {
435         id: b.id,
436         stmts: b.stmts.iter().map(|s| lower_stmt(_lctx, s)).collect(),
437         expr: b.expr.as_ref().map(|ref x| lower_expr(_lctx, x)),
438         rules: lower_block_check_mode(_lctx, &b.rules),
439         span: b.span,
440     })
441 }
442
443 pub fn lower_item_underscore(_lctx: &LoweringContext, i: &Item_) -> hir::Item_ {
444     match *i {
445         ItemExternCrate(string) => hir::ItemExternCrate(string),
446         ItemUse(ref view_path) => {
447             hir::ItemUse(lower_view_path(_lctx, view_path))
448         }
449         ItemStatic(ref t, m, ref e) => {
450             hir::ItemStatic(lower_ty(_lctx, t), lower_mutability(_lctx, m), lower_expr(_lctx, e))
451         }
452         ItemConst(ref t, ref e) => {
453             hir::ItemConst(lower_ty(_lctx, t), lower_expr(_lctx, e))
454         }
455         ItemFn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
456             hir::ItemFn(
457                 lower_fn_decl(_lctx, decl),
458                 lower_unsafety(_lctx, unsafety),
459                 lower_constness(_lctx, constness),
460                 abi,
461                 lower_generics(_lctx, generics),
462                 lower_block(_lctx, body)
463             )
464         }
465         ItemMod(ref m) => hir::ItemMod(lower_mod(_lctx, m)),
466         ItemForeignMod(ref nm) => hir::ItemForeignMod(lower_foreign_mod(_lctx, nm)),
467         ItemTy(ref t, ref generics) => {
468             hir::ItemTy(lower_ty(_lctx, t), lower_generics(_lctx, generics))
469         }
470         ItemEnum(ref enum_definition, ref generics) => {
471             hir::ItemEnum(
472                 hir::EnumDef {
473                     variants: enum_definition.variants.iter().map(|x| {
474                         lower_variant(_lctx, x)
475                     }).collect(),
476                 },
477                 lower_generics(_lctx, generics))
478         }
479         ItemStruct(ref struct_def, ref generics) => {
480             let struct_def = lower_struct_def(_lctx, struct_def);
481             hir::ItemStruct(struct_def, lower_generics(_lctx, generics))
482         }
483         ItemDefaultImpl(unsafety, ref trait_ref) => {
484             hir::ItemDefaultImpl(lower_unsafety(_lctx, unsafety), lower_trait_ref(_lctx, trait_ref))
485         }
486         ItemImpl(unsafety, polarity, ref generics, ref ifce, ref ty, ref impl_items) => {
487             let new_impl_items =
488                 impl_items.iter().map(|item| lower_impl_item(_lctx, item)).collect();
489             let ifce = ifce.as_ref().map(|trait_ref| lower_trait_ref(_lctx, trait_ref));
490             hir::ItemImpl(lower_unsafety(_lctx, unsafety),
491                           lower_impl_polarity(_lctx, polarity),
492                           lower_generics(_lctx, generics),
493                           ifce,
494                           lower_ty(_lctx, ty),
495                           new_impl_items)
496         }
497         ItemTrait(unsafety, ref generics, ref bounds, ref items) => {
498             let bounds = lower_bounds(_lctx, bounds);
499             let items = items.iter().map(|item| lower_trait_item(_lctx, item)).collect();
500             hir::ItemTrait(lower_unsafety(_lctx, unsafety),
501                            lower_generics(_lctx, generics),
502                            bounds,
503                            items)
504         }
505         ItemMac(_) => panic!("Shouldn't still be around"),
506     }
507 }
508
509 pub fn lower_trait_item(_lctx: &LoweringContext, i: &TraitItem) -> P<hir::TraitItem> {
510     P(hir::TraitItem {
511         id: i.id,
512         name: i.ident.name,
513         attrs: i.attrs.clone(),
514         node: match i.node {
515             ConstTraitItem(ref ty, ref default) => {
516                 hir::ConstTraitItem(lower_ty(_lctx, ty),
517                                     default.as_ref().map(|x| lower_expr(_lctx, x)))
518             }
519             MethodTraitItem(ref sig, ref body) => {
520                 hir::MethodTraitItem(lower_method_sig(_lctx, sig),
521                                      body.as_ref().map(|x| lower_block(_lctx, x)))
522             }
523             TypeTraitItem(ref bounds, ref default) => {
524                 hir::TypeTraitItem(lower_bounds(_lctx, bounds),
525                                    default.as_ref().map(|x| lower_ty(_lctx, x)))
526             }
527         },
528         span: i.span,
529     })
530 }
531
532 pub fn lower_impl_item(_lctx: &LoweringContext, i: &ImplItem) -> P<hir::ImplItem> {
533     P(hir::ImplItem {
534             id: i.id,
535             name: i.ident.name,
536             attrs: i.attrs.clone(),
537             vis: lower_visibility(_lctx, i.vis),
538             node: match i.node  {
539             ConstImplItem(ref ty, ref expr) => {
540                 hir::ConstImplItem(lower_ty(_lctx, ty), lower_expr(_lctx, expr))
541             }
542             MethodImplItem(ref sig, ref body) => {
543                 hir::MethodImplItem(lower_method_sig(_lctx, sig),
544                                     lower_block(_lctx, body))
545             }
546             TypeImplItem(ref ty) => hir::TypeImplItem(lower_ty(_lctx, ty)),
547             MacImplItem(..) => panic!("Shouldn't exist any more"),
548         },
549         span: i.span,
550     })
551 }
552
553 pub fn lower_mod(_lctx: &LoweringContext, m: &Mod) -> hir::Mod {
554     hir::Mod { inner: m.inner, items: m.items.iter().map(|x| lower_item(_lctx, x)).collect() }
555 }
556
557 pub fn lower_crate(_lctx: &LoweringContext, c: &Crate) -> hir::Crate {
558     hir::Crate {
559         module: lower_mod(_lctx, &c.module),
560         attrs: c.attrs.clone(),
561         config: c.config.clone(),
562         span: c.span,
563         exported_macros: c.exported_macros.iter().map(|m| lower_macro_def(_lctx, m)).collect(),
564     }
565 }
566
567 pub fn lower_macro_def(_lctx: &LoweringContext, m: &MacroDef) -> hir::MacroDef {
568     hir::MacroDef {
569         name: m.ident.name,
570         attrs: m.attrs.clone(),
571         id: m.id,
572         span: m.span,
573         imported_from: m.imported_from.map(|x| x.name),
574         export: m.export,
575         use_locally: m.use_locally,
576         allow_internal_unstable: m.allow_internal_unstable,
577         body: m.body.clone(),
578     }
579 }
580
581 // fold one item into possibly many items
582 pub fn lower_item(_lctx: &LoweringContext, i: &Item) -> P<hir::Item> {
583     P(lower_item_simple(_lctx, i))
584 }
585
586 // fold one item into exactly one item
587 pub fn lower_item_simple(_lctx: &LoweringContext, i: &Item) -> hir::Item {
588     let node = lower_item_underscore(_lctx, &i.node);
589
590     hir::Item {
591         id: i.id,
592         name: i.ident.name,
593         attrs: i.attrs.clone(),
594         node: node,
595         vis: lower_visibility(_lctx, i.vis),
596         span: i.span,
597     }
598 }
599
600 pub fn lower_foreign_item(_lctx: &LoweringContext, i: &ForeignItem) -> P<hir::ForeignItem> {
601     P(hir::ForeignItem {
602         id: i.id,
603         name: i.ident.name,
604         attrs: i.attrs.clone(),
605         node: match i.node {
606             ForeignItemFn(ref fdec, ref generics) => {
607                 hir::ForeignItemFn(lower_fn_decl(_lctx, fdec), lower_generics(_lctx, generics))
608             }
609             ForeignItemStatic(ref t, m) => {
610                 hir::ForeignItemStatic(lower_ty(_lctx, t), m)
611             }
612         },
613             vis: lower_visibility(_lctx, i.vis),
614             span: i.span,
615         })
616 }
617
618 pub fn lower_method_sig(_lctx: &LoweringContext, sig: &MethodSig) -> hir::MethodSig {
619     hir::MethodSig {
620         generics: lower_generics(_lctx, &sig.generics),
621         abi: sig.abi,
622         explicit_self: lower_explicit_self(_lctx, &sig.explicit_self),
623         unsafety: lower_unsafety(_lctx, sig.unsafety),
624         constness: lower_constness(_lctx, sig.constness),
625         decl: lower_fn_decl(_lctx, &sig.decl),
626     }
627 }
628
629 pub fn lower_unsafety(_lctx: &LoweringContext, u: Unsafety) -> hir::Unsafety {
630     match u {
631         Unsafety::Unsafe => hir::Unsafety::Unsafe,
632         Unsafety::Normal => hir::Unsafety::Normal,
633     }
634 }
635
636 pub fn lower_constness(_lctx: &LoweringContext, c: Constness) -> hir::Constness {
637     match c {
638         Constness::Const => hir::Constness::Const,
639         Constness::NotConst => hir::Constness::NotConst,
640     }
641 }
642
643 pub fn lower_unop(_lctx: &LoweringContext, u: UnOp) -> hir::UnOp {
644     match u {
645         UnDeref => hir::UnDeref,
646         UnNot => hir::UnNot,
647         UnNeg => hir::UnNeg,
648     }
649 }
650
651 pub fn lower_binop(_lctx: &LoweringContext, b: BinOp) -> hir::BinOp {
652     Spanned {
653         node: match b.node {
654             BiAdd => hir::BiAdd,
655             BiSub => hir::BiSub,
656             BiMul => hir::BiMul,
657             BiDiv => hir::BiDiv,
658             BiRem => hir::BiRem,
659             BiAnd => hir::BiAnd,
660             BiOr => hir::BiOr,
661             BiBitXor => hir::BiBitXor,
662             BiBitAnd => hir::BiBitAnd,
663             BiBitOr => hir::BiBitOr,
664             BiShl => hir::BiShl,
665             BiShr => hir::BiShr,
666             BiEq => hir::BiEq,
667             BiLt => hir::BiLt,
668             BiLe => hir::BiLe,
669             BiNe => hir::BiNe,
670             BiGe => hir::BiGe,
671             BiGt => hir::BiGt,
672         },
673         span: b.span,
674     }
675 }
676
677 pub fn lower_pat(_lctx: &LoweringContext, p: &Pat) -> P<hir::Pat> {
678     P(hir::Pat {
679             id: p.id,
680             node: match p.node {
681             PatWild(k) => hir::PatWild(lower_pat_wild_kind(_lctx, k)),
682             PatIdent(ref binding_mode, pth1, ref sub) => {
683                 hir::PatIdent(lower_binding_mode(_lctx, binding_mode),
684                         pth1,
685                         sub.as_ref().map(|x| lower_pat(_lctx, x)))
686             }
687             PatLit(ref e) => hir::PatLit(lower_expr(_lctx, e)),
688             PatEnum(ref pth, ref pats) => {
689                 hir::PatEnum(lower_path(_lctx, pth),
690                              pats.as_ref()
691                                  .map(|pats| pats.iter().map(|x| lower_pat(_lctx, x)).collect()))
692             }
693             PatQPath(ref qself, ref pth) => {
694                 let qself = hir::QSelf {
695                     ty: lower_ty(_lctx, &qself.ty),
696                     position: qself.position,
697                 };
698                 hir::PatQPath(qself, lower_path(_lctx, pth))
699             }
700             PatStruct(ref pth, ref fields, etc) => {
701                 let pth = lower_path(_lctx, pth);
702                 let fs = fields.iter().map(|f| {
703                     Spanned { span: f.span,
704                               node: hir::FieldPat {
705                                   name: f.node.ident.name,
706                                   pat: lower_pat(_lctx, &f.node.pat),
707                                   is_shorthand: f.node.is_shorthand,
708                               }}
709                 }).collect();
710                 hir::PatStruct(pth, fs, etc)
711             }
712             PatTup(ref elts) => hir::PatTup(elts.iter().map(|x| lower_pat(_lctx, x)).collect()),
713             PatBox(ref inner) => hir::PatBox(lower_pat(_lctx, inner)),
714             PatRegion(ref inner, mutbl) => hir::PatRegion(lower_pat(_lctx, inner),
715                                                           lower_mutability(_lctx, mutbl)),
716             PatRange(ref e1, ref e2) => {
717                 hir::PatRange(lower_expr(_lctx, e1), lower_expr(_lctx, e2))
718             },
719             PatVec(ref before, ref slice, ref after) => {
720                 hir::PatVec(before.iter().map(|x| lower_pat(_lctx, x)).collect(),
721                        slice.as_ref().map(|x| lower_pat(_lctx, x)),
722                        after.iter().map(|x| lower_pat(_lctx, x)).collect())
723             }
724             PatMac(_) => panic!("Shouldn't exist here"),
725         },
726         span: p.span,
727     })
728 }
729
730 pub fn lower_expr(_lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
731     P(hir::Expr {
732             id: e.id,
733             node: match e.node {
734                 ExprBox(ref e) => {
735                     hir::ExprBox(lower_expr(_lctx, e))
736                 }
737                 ExprVec(ref exprs) => {
738                     hir::ExprVec(exprs.iter().map(|x| lower_expr(_lctx, x)).collect())
739                 }
740                 ExprRepeat(ref expr, ref count) => {
741                     hir::ExprRepeat(lower_expr(_lctx, expr), lower_expr(_lctx, count))
742                 }
743                 ExprTup(ref elts) => {
744                     hir::ExprTup(elts.iter().map(|x| lower_expr(_lctx, x)).collect())
745                 }
746                 ExprCall(ref f, ref args) => {
747                     hir::ExprCall(lower_expr(_lctx, f),
748                              args.iter().map(|x| lower_expr(_lctx, x)).collect())
749                 }
750                 ExprMethodCall(i, ref tps, ref args) => {
751                     hir::ExprMethodCall(
752                         respan(i.span, i.node.name),
753                         tps.iter().map(|x| lower_ty(_lctx, x)).collect(),
754                         args.iter().map(|x| lower_expr(_lctx, x)).collect())
755                 }
756                 ExprBinary(binop, ref lhs, ref rhs) => {
757                     hir::ExprBinary(lower_binop(_lctx, binop),
758                             lower_expr(_lctx, lhs),
759                             lower_expr(_lctx, rhs))
760                 }
761                 ExprUnary(op, ref ohs) => {
762                     hir::ExprUnary(lower_unop(_lctx, op), lower_expr(_lctx, ohs))
763                 }
764                 ExprLit(ref l) => hir::ExprLit(P((**l).clone())),
765                 ExprCast(ref expr, ref ty) => {
766                     hir::ExprCast(lower_expr(_lctx, expr), lower_ty(_lctx, ty))
767                 }
768                 ExprAddrOf(m, ref ohs) => {
769                     hir::ExprAddrOf(lower_mutability(_lctx, m), lower_expr(_lctx, ohs))
770                 }
771                 ExprIf(ref cond, ref tr, ref fl) => {
772                     hir::ExprIf(lower_expr(_lctx, cond),
773                            lower_block(_lctx, tr),
774                            fl.as_ref().map(|x| lower_expr(_lctx, x)))
775                 }
776                 ExprWhile(ref cond, ref body, opt_ident) => {
777                     hir::ExprWhile(lower_expr(_lctx, cond),
778                               lower_block(_lctx, body),
779                               opt_ident)
780                 }
781                 ExprLoop(ref body, opt_ident) => {
782                     hir::ExprLoop(lower_block(_lctx, body),
783                             opt_ident)
784                 }
785                 ExprMatch(ref expr, ref arms, ref source) => {
786                     hir::ExprMatch(lower_expr(_lctx, expr),
787                             arms.iter().map(|x| lower_arm(_lctx, x)).collect(),
788                             lower_match_source(_lctx, source))
789                 }
790                 ExprClosure(capture_clause, ref decl, ref body) => {
791                     hir::ExprClosure(lower_capture_clause(_lctx, capture_clause),
792                                 lower_fn_decl(_lctx, decl),
793                                 lower_block(_lctx, body))
794                 }
795                 ExprBlock(ref blk) => hir::ExprBlock(lower_block(_lctx, blk)),
796                 ExprAssign(ref el, ref er) => {
797                     hir::ExprAssign(lower_expr(_lctx, el), lower_expr(_lctx, er))
798                 }
799                 ExprAssignOp(op, ref el, ref er) => {
800                     hir::ExprAssignOp(lower_binop(_lctx, op),
801                                 lower_expr(_lctx, el),
802                                 lower_expr(_lctx, er))
803                 }
804                 ExprField(ref el, ident) => {
805                     hir::ExprField(lower_expr(_lctx, el), respan(ident.span, ident.node.name))
806                 }
807                 ExprTupField(ref el, ident) => {
808                     hir::ExprTupField(lower_expr(_lctx, el), ident)
809                 }
810                 ExprIndex(ref el, ref er) => {
811                     hir::ExprIndex(lower_expr(_lctx, el), lower_expr(_lctx, er))
812                 }
813                 ExprRange(ref e1, ref e2) => {
814                     hir::ExprRange(e1.as_ref().map(|x| lower_expr(_lctx, x)),
815                               e2.as_ref().map(|x| lower_expr(_lctx, x)))
816                 }
817                 ExprPath(ref qself, ref path) => {
818                     let qself = qself.as_ref().map(|&QSelf { ref ty, position }| {
819                         hir::QSelf {
820                             ty: lower_ty(_lctx, ty),
821                             position: position
822                         }
823                     });
824                     hir::ExprPath(qself, lower_path(_lctx, path))
825                 }
826                 ExprBreak(opt_ident) => hir::ExprBreak(opt_ident),
827                 ExprAgain(opt_ident) => hir::ExprAgain(opt_ident),
828                 ExprRet(ref e) => hir::ExprRet(e.as_ref().map(|x| lower_expr(_lctx, x))),
829                 ExprInlineAsm(InlineAsm {
830                     ref inputs,
831                     ref outputs,
832                     ref asm,
833                     asm_str_style,
834                     ref clobbers,
835                     volatile,
836                     alignstack,
837                     dialect,
838                     expn_id,
839                 }) => hir::ExprInlineAsm(hir::InlineAsm {
840                     inputs: inputs.iter().map(|&(ref c, ref input)| {
841                         (c.clone(), lower_expr(_lctx, input))
842                     }).collect(),
843                     outputs: outputs.iter().map(|&(ref c, ref out, ref is_rw)| {
844                         (c.clone(), lower_expr(_lctx, out), *is_rw)
845                     }).collect(),
846                     asm: asm.clone(),
847                     asm_str_style: asm_str_style,
848                     clobbers: clobbers.clone(),
849                     volatile: volatile,
850                     alignstack: alignstack,
851                     dialect: dialect,
852                     expn_id: expn_id,
853                 }),
854                 ExprStruct(ref path, ref fields, ref maybe_expr) => {
855                     hir::ExprStruct(lower_path(_lctx, path),
856                             fields.iter().map(|x| lower_field(_lctx, x)).collect(),
857                             maybe_expr.as_ref().map(|x| lower_expr(_lctx, x)))
858                 },
859                 ExprParen(ref ex) => {
860                     return lower_expr(_lctx, ex);
861                 }
862                 ExprInPlace(..) |
863                 ExprIfLet(..) |
864                 ExprWhileLet(..) |
865                 ExprForLoop(..) |
866                 ExprMac(_) => panic!("Shouldn't exist here"),
867             },
868             span: e.span,
869         })
870 }
871
872 pub fn lower_stmt(_lctx: &LoweringContext, s: &Stmt) -> P<hir::Stmt> {
873     match s.node {
874         StmtDecl(ref d, id) => {
875             P(Spanned {
876                 node: hir::StmtDecl(lower_decl(_lctx, d), id),
877                 span: s.span
878             })
879         }
880         StmtExpr(ref e, id) => {
881             P(Spanned {
882                 node: hir::StmtExpr(lower_expr(_lctx, e), id),
883                 span: s.span
884             })
885         }
886         StmtSemi(ref e, id) => {
887             P(Spanned {
888                 node: hir::StmtSemi(lower_expr(_lctx, e), id),
889                 span: s.span
890             })
891         }
892         StmtMac(..) => panic!("Shouldn't exist here"),
893     }
894 }
895
896 pub fn lower_match_source(_lctx: &LoweringContext, m: &MatchSource) -> hir::MatchSource {
897     match *m {
898         MatchSource::Normal => hir::MatchSource::Normal,
899         MatchSource::IfLetDesugar { contains_else_clause } => {
900             hir::MatchSource::IfLetDesugar { contains_else_clause: contains_else_clause }
901         }
902         MatchSource::WhileLetDesugar => hir::MatchSource::WhileLetDesugar,
903         MatchSource::ForLoopDesugar => hir::MatchSource::ForLoopDesugar,
904     }
905 }
906
907 pub fn lower_capture_clause(_lctx: &LoweringContext, c: CaptureClause) -> hir::CaptureClause {
908     match c {
909         CaptureByValue => hir::CaptureByValue,
910         CaptureByRef => hir::CaptureByRef,
911     }
912 }
913
914 pub fn lower_visibility(_lctx: &LoweringContext, v: Visibility) -> hir::Visibility {
915     match v {
916         Public => hir::Public,
917         Inherited => hir::Inherited,
918     }
919 }
920
921 pub fn lower_block_check_mode(_lctx: &LoweringContext, b: &BlockCheckMode) -> hir::BlockCheckMode {
922     match *b {
923         DefaultBlock => hir::DefaultBlock,
924         UnsafeBlock(u) => hir::UnsafeBlock(lower_unsafe_source(_lctx, u)),
925         PushUnsafeBlock(u) => hir::PushUnsafeBlock(lower_unsafe_source(_lctx, u)),
926         PopUnsafeBlock(u) => hir::PopUnsafeBlock(lower_unsafe_source(_lctx, u)),
927     }
928 }
929
930 pub fn lower_pat_wild_kind(_lctx: &LoweringContext, p: PatWildKind) -> hir::PatWildKind {
931     match p {
932         PatWildSingle => hir::PatWildSingle,
933         PatWildMulti => hir::PatWildMulti,
934     }
935 }
936
937 pub fn lower_binding_mode(_lctx: &LoweringContext, b: &BindingMode) -> hir::BindingMode {
938     match *b {
939         BindByRef(m) => hir::BindByRef(lower_mutability(_lctx, m)),
940         BindByValue(m) => hir::BindByValue(lower_mutability(_lctx, m)),
941     }
942 }
943
944 pub fn lower_struct_field_kind(_lctx: &LoweringContext,
945                                s: &StructFieldKind)
946                                -> hir::StructFieldKind {
947     match *s {
948         NamedField(ident, vis) => hir::NamedField(ident.name, lower_visibility(_lctx, vis)),
949         UnnamedField(vis) => hir::UnnamedField(lower_visibility(_lctx, vis)),
950     }
951 }
952
953 pub fn lower_unsafe_source(_lctx: &LoweringContext, u: UnsafeSource) -> hir::UnsafeSource {
954     match u {
955         CompilerGenerated => hir::CompilerGenerated,
956         UserProvided => hir::UserProvided,
957     }
958 }
959
960 pub fn lower_impl_polarity(_lctx: &LoweringContext, i: ImplPolarity) -> hir::ImplPolarity {
961     match i {
962         ImplPolarity::Positive => hir::ImplPolarity::Positive,
963         ImplPolarity::Negative => hir::ImplPolarity::Negative,
964     }
965 }
966
967 pub fn lower_trait_bound_modifier(_lctx: &LoweringContext,
968                                   f: TraitBoundModifier)
969                                   -> hir::TraitBoundModifier {
970     match f {
971         TraitBoundModifier::None => hir::TraitBoundModifier::None,
972         TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe,
973     }
974 }