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