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