]> git.proxmox.com Git - rustc.git/blame - src/librustc/hir/lowering.rs
New upstream version 1.13.0+dfsg1
[rustc.git] / src / librustc / hir / lowering.rs
CommitLineData
e9174d1e
SL
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
b039eaaf
SL
11// Lowers the AST to the HIR.
12//
13// Since the AST and HIR are fairly similar, this is mostly a simple procedure,
14// much like a fold. Where lowering involves a bit more work things get more
15// interesting and there are some invariants you should know about. These mostly
16// concern spans and ids.
17//
18// Spans are assigned to AST nodes during parsing and then are modified during
19// expansion to indicate the origin of a node and the process it went through
20// being expanded. Ids are assigned to AST nodes just before lowering.
21//
22// For the simpler lowering steps, ids and spans should be preserved. Unlike
23// expansion we do not preserve the process of lowering in the spans, so spans
24// should not be modified here. When creating a new node (as opposed to
25// 'folding' an existing one), then you create a new id using `next_id()`.
26//
27// You must ensure that ids are unique. That means that you should only use the
28// id from an AST node in a single HIR node (you can assume that AST node ids
29// are unique). Every new node must have a unique id. Avoid cloning HIR nodes.
30// If you do, you must then set the new node's id to a fresh one.
31//
b039eaaf
SL
32// Spans are used for error messages and for tools to map semantics back to
33// source code. It is therefore not as important with spans as ids to be strict
34// about use (you can't break the compiler by screwing up a span). Obviously, a
35// HIR node can only have a single span. But multiple nodes can have the same
36// span and spans don't need to be kept in order, etc. Where code is preserved
37// by lowering, it should have the same span as in the AST. Where HIR nodes are
38// new it is probably best to give a span for the whole AST node being lowered.
39// All nodes should have real spans, don't use dummy spans. Tools are likely to
40// get confused if the spans from leaf AST nodes occur in multiple places
41// in the HIR, especially for multiple identifiers.
e9174d1e
SL
42
43use hir;
a7813a04
XL
44use hir::map::Definitions;
45use hir::map::definitions::DefPathData;
46use hir::def_id::{DefIndex, DefId};
47use hir::def::{Def, PathResolution};
48use session::Session;
e9174d1e 49
92a42be0 50use std::collections::BTreeMap;
54a0048b 51use std::iter;
e9174d1e 52use syntax::ast::*;
3157f602 53use syntax::errors;
e9174d1e 54use syntax::ptr::P;
3157f602
XL
55use syntax::codemap::{respan, Spanned};
56use syntax::parse::token;
b039eaaf 57use syntax::std_inject;
92a42be0 58use syntax::visit::{self, Visitor};
3157f602 59use syntax_pos::Span;
b039eaaf 60
b039eaaf
SL
61pub struct LoweringContext<'a> {
62 crate_root: Option<&'static str>,
a7813a04 63 // Use to assign ids to hir nodes that do not directly correspond to an ast node
9e0c209e 64 sess: &'a Session,
a7813a04
XL
65 // As we walk the AST we must keep track of the current 'parent' def id (in
66 // the form of a DefIndex) so that if we create a new node which introduces
67 // a definition, then we can properly create the def id.
68 parent_def: Option<DefIndex>,
69 resolver: &'a mut Resolver,
b039eaaf
SL
70}
71
a7813a04
XL
72pub trait Resolver {
73 // Resolve a global hir path generated by the lowerer when expanding `for`, `if let`, etc.
74 fn resolve_generated_global_path(&mut self, path: &hir::Path, is_value: bool) -> Def;
75
76 // Obtain the resolution for a node id
77 fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution>;
78
79 // Record the resolution of a path or binding generated by the lowerer when expanding.
80 fn record_resolution(&mut self, id: NodeId, def: Def);
81
82 // We must keep the set of definitions up to date as we add nodes that weren't in the AST.
83 // This should only return `None` during testing.
9e0c209e 84 fn definitions(&mut self) -> &mut Definitions;
a7813a04 85}
b039eaaf 86
a7813a04
XL
87pub fn lower_crate(sess: &Session,
88 krate: &Crate,
a7813a04
XL
89 resolver: &mut Resolver)
90 -> hir::Crate {
91 // We're constructing the HIR here; we don't care what we will
92 // read, since we haven't even constructed the *input* to
93 // incr. comp. yet.
94 let _ignore = sess.dep_graph.in_ignore();
95
96 LoweringContext {
97 crate_root: if std_inject::no_core(krate) {
98 None
99 } else if std_inject::no_std(krate) {
100 Some("core")
101 } else {
102 Some("std")
103 },
9e0c209e 104 sess: sess,
a7813a04
XL
105 parent_def: None,
106 resolver: resolver,
107 }.lower_crate(krate)
108}
109
110impl<'a> LoweringContext<'a> {
a7813a04
XL
111 fn lower_crate(&mut self, c: &Crate) -> hir::Crate {
112 struct ItemLowerer<'lcx, 'interner: 'lcx> {
113 items: BTreeMap<NodeId, hir::Item>,
114 lctx: &'lcx mut LoweringContext<'interner>,
b039eaaf 115 }
e9174d1e 116
3157f602
XL
117 impl<'lcx, 'interner> Visitor for ItemLowerer<'lcx, 'interner> {
118 fn visit_item(&mut self, item: &Item) {
a7813a04
XL
119 self.items.insert(item.id, self.lctx.lower_item(item));
120 visit::walk_item(self, item);
121 }
b039eaaf
SL
122 }
123
a7813a04
XL
124 let items = {
125 let mut item_lowerer = ItemLowerer { items: BTreeMap::new(), lctx: self };
126 visit::walk_crate(&mut item_lowerer, c);
127 item_lowerer.items
128 };
129
130 hir::Crate {
131 module: self.lower_mod(&c.module),
132 attrs: self.lower_attrs(&c.attrs),
133 config: c.config.clone().into(),
134 span: c.span,
135 exported_macros: c.exported_macros.iter().map(|m| self.lower_macro_def(m)).collect(),
136 items: items,
b039eaaf
SL
137 }
138 }
54a0048b 139
a7813a04 140 fn next_id(&self) -> NodeId {
9e0c209e 141 self.sess.next_node_id()
3157f602
XL
142 }
143
144 fn diagnostic(&self) -> &errors::Handler {
9e0c209e 145 self.sess.diagnostic()
54a0048b 146 }
e9174d1e 147
a7813a04
XL
148 fn str_to_ident(&self, s: &'static str) -> Name {
149 token::gensym(s)
150 }
7453a54e 151
a7813a04
XL
152 fn with_parent_def<T, F>(&mut self, parent_id: NodeId, f: F) -> T
153 where F: FnOnce(&mut LoweringContext) -> T
7453a54e 154 {
a7813a04 155 let old_def = self.parent_def;
9e0c209e
SL
156 self.parent_def = {
157 let defs = self.resolver.definitions();
158 Some(defs.opt_def_index(parent_id).unwrap())
a7813a04 159 };
7453a54e 160
a7813a04 161 let result = f(self);
7453a54e 162
a7813a04
XL
163 self.parent_def = old_def;
164 result
7453a54e 165 }
7453a54e 166
3157f602
XL
167 fn lower_opt_sp_ident(&mut self, o_id: Option<Spanned<Ident>>) -> Option<Spanned<Name>> {
168 o_id.map(|sp_ident| respan(sp_ident.span, sp_ident.node.name))
92a42be0 169 }
92a42be0 170
a7813a04
XL
171 fn lower_attrs(&mut self, attrs: &Vec<Attribute>) -> hir::HirVec<Attribute> {
172 attrs.clone().into()
173 }
e9174d1e 174
a7813a04
XL
175 fn lower_view_path(&mut self, view_path: &ViewPath) -> P<hir::ViewPath> {
176 P(Spanned {
177 node: match view_path.node {
178 ViewPathSimple(ident, ref path) => {
179 hir::ViewPathSimple(ident.name, self.lower_path(path))
180 }
181 ViewPathGlob(ref path) => {
182 hir::ViewPathGlob(self.lower_path(path))
183 }
184 ViewPathList(ref path, ref path_list_idents) => {
185 hir::ViewPathList(self.lower_path(path),
186 path_list_idents.iter()
187 .map(|item| self.lower_path_list_item(item))
188 .collect())
189 }
7453a54e 190 },
a7813a04
XL
191 span: view_path.span,
192 })
193 }
194
195 fn lower_path_list_item(&mut self, path_list_ident: &PathListItem) -> hir::PathListItem {
196 Spanned {
9e0c209e
SL
197 node: hir::PathListItem_ {
198 id: path_list_ident.node.id,
199 name: path_list_ident.node.name.name,
200 rename: path_list_ident.node.rename.map(|rename| rename.name),
7453a54e 201 },
a7813a04
XL
202 span: path_list_ident.span,
203 }
7453a54e 204 }
7453a54e 205
a7813a04
XL
206 fn lower_arm(&mut self, arm: &Arm) -> hir::Arm {
207 hir::Arm {
208 attrs: self.lower_attrs(&arm.attrs),
209 pats: arm.pats.iter().map(|x| self.lower_pat(x)).collect(),
210 guard: arm.guard.as_ref().map(|ref x| self.lower_expr(x)),
211 body: self.lower_expr(&arm.body),
212 }
e9174d1e 213 }
e9174d1e 214
a7813a04
XL
215 fn lower_ty_binding(&mut self, b: &TypeBinding) -> hir::TypeBinding {
216 hir::TypeBinding {
217 id: b.id,
218 name: b.ident.name,
219 ty: self.lower_ty(&b.ty),
220 span: b.span,
221 }
92a42be0 222 }
e9174d1e 223
a7813a04
XL
224 fn lower_ty(&mut self, t: &Ty) -> P<hir::Ty> {
225 use syntax::ast::TyKind::*;
226 P(hir::Ty {
227 id: t.id,
228 node: match t.node {
3157f602 229 Infer | ImplicitSelf => hir::TyInfer,
a7813a04
XL
230 Vec(ref ty) => hir::TyVec(self.lower_ty(ty)),
231 Ptr(ref mt) => hir::TyPtr(self.lower_mt(mt)),
232 Rptr(ref region, ref mt) => {
233 hir::TyRptr(self.lower_opt_lifetime(region), self.lower_mt(mt))
234 }
235 BareFn(ref f) => {
236 hir::TyBareFn(P(hir::BareFnTy {
237 lifetimes: self.lower_lifetime_defs(&f.lifetimes),
238 unsafety: self.lower_unsafety(f.unsafety),
239 abi: f.abi,
240 decl: self.lower_fn_decl(&f.decl),
241 }))
242 }
5bcae85e 243 Never => hir::TyNever,
a7813a04
XL
244 Tup(ref tys) => hir::TyTup(tys.iter().map(|ty| self.lower_ty(ty)).collect()),
245 Paren(ref ty) => {
246 return self.lower_ty(ty);
247 }
248 Path(ref qself, ref path) => {
249 let qself = qself.as_ref().map(|&QSelf { ref ty, position }| {
250 hir::QSelf {
251 ty: self.lower_ty(ty),
252 position: position,
253 }
254 });
255 hir::TyPath(qself, self.lower_path(path))
256 }
257 ObjectSum(ref ty, ref bounds) => {
258 hir::TyObjectSum(self.lower_ty(ty), self.lower_bounds(bounds))
259 }
260 FixedLengthVec(ref ty, ref e) => {
261 hir::TyFixedLengthVec(self.lower_ty(ty), self.lower_expr(e))
262 }
263 Typeof(ref expr) => {
264 hir::TyTypeof(self.lower_expr(expr))
265 }
266 PolyTraitRef(ref bounds) => {
5bcae85e
SL
267 hir::TyPolyTraitRef(self.lower_bounds(bounds))
268 }
269 ImplTrait(ref bounds) => {
270 hir::TyImplTrait(self.lower_bounds(bounds))
a7813a04
XL
271 }
272 Mac(_) => panic!("TyMac should have been expanded by now."),
273 },
274 span: t.span,
275 })
276 }
e9174d1e 277
a7813a04
XL
278 fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod {
279 hir::ForeignMod {
280 abi: fm.abi,
281 items: fm.items.iter().map(|x| self.lower_foreign_item(x)).collect(),
282 }
e9174d1e 283 }
e9174d1e 284
a7813a04
XL
285 fn lower_variant(&mut self, v: &Variant) -> hir::Variant {
286 Spanned {
287 node: hir::Variant_ {
288 name: v.node.name.name,
289 attrs: self.lower_attrs(&v.node.attrs),
290 data: self.lower_variant_data(&v.node.data),
291 disr_expr: v.node.disr_expr.as_ref().map(|e| self.lower_expr(e)),
292 },
293 span: v.span,
294 }
92a42be0 295 }
e9174d1e 296
3157f602 297 fn lower_path(&mut self, p: &Path) -> hir::Path {
a7813a04
XL
298 hir::Path {
299 global: p.global,
300 segments: p.segments
301 .iter()
302 .map(|&PathSegment { identifier, ref parameters }| {
303 hir::PathSegment {
3157f602 304 name: identifier.name,
a7813a04
XL
305 parameters: self.lower_path_parameters(parameters),
306 }
307 })
308 .collect(),
309 span: p.span,
310 }
e9174d1e 311 }
e9174d1e 312
a7813a04
XL
313 fn lower_path_parameters(&mut self, path_parameters: &PathParameters) -> hir::PathParameters {
314 match *path_parameters {
315 PathParameters::AngleBracketed(ref data) =>
316 hir::AngleBracketedParameters(self.lower_angle_bracketed_parameter_data(data)),
317 PathParameters::Parenthesized(ref data) =>
318 hir::ParenthesizedParameters(self.lower_parenthesized_parameter_data(data)),
319 }
e9174d1e 320 }
e9174d1e 321
a7813a04 322 fn lower_angle_bracketed_parameter_data(&mut self,
b039eaaf 323 data: &AngleBracketedParameterData)
e9174d1e 324 -> hir::AngleBracketedParameterData {
a7813a04
XL
325 let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings } = data;
326 hir::AngleBracketedParameterData {
327 lifetimes: self.lower_lifetimes(lifetimes),
328 types: types.iter().map(|ty| self.lower_ty(ty)).collect(),
329 bindings: bindings.iter().map(|b| self.lower_ty_binding(b)).collect(),
330 }
e9174d1e 331 }
e9174d1e 332
a7813a04 333 fn lower_parenthesized_parameter_data(&mut self,
b039eaaf 334 data: &ParenthesizedParameterData)
e9174d1e 335 -> hir::ParenthesizedParameterData {
a7813a04
XL
336 let &ParenthesizedParameterData { ref inputs, ref output, span } = data;
337 hir::ParenthesizedParameterData {
338 inputs: inputs.iter().map(|ty| self.lower_ty(ty)).collect(),
339 output: output.as_ref().map(|ty| self.lower_ty(ty)),
340 span: span,
341 }
e9174d1e 342 }
e9174d1e 343
a7813a04
XL
344 fn lower_local(&mut self, l: &Local) -> P<hir::Local> {
345 P(hir::Local {
346 id: l.id,
347 ty: l.ty.as_ref().map(|t| self.lower_ty(t)),
348 pat: self.lower_pat(&l.pat),
349 init: l.init.as_ref().map(|e| self.lower_expr(e)),
350 span: l.span,
351 attrs: l.attrs.clone(),
352 })
353 }
e9174d1e 354
a7813a04
XL
355 fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability {
356 match m {
357 Mutability::Mutable => hir::MutMutable,
358 Mutability::Immutable => hir::MutImmutable,
e9174d1e
SL
359 }
360 }
e9174d1e 361
a7813a04
XL
362 fn lower_arg(&mut self, arg: &Arg) -> hir::Arg {
363 hir::Arg {
364 id: arg.id,
365 pat: self.lower_pat(&arg.pat),
366 ty: self.lower_ty(&arg.ty),
367 }
e9174d1e 368 }
e9174d1e 369
a7813a04
XL
370 fn lower_fn_decl(&mut self, decl: &FnDecl) -> P<hir::FnDecl> {
371 P(hir::FnDecl {
372 inputs: decl.inputs.iter().map(|x| self.lower_arg(x)).collect(),
373 output: match decl.output {
374 FunctionRetTy::Ty(ref ty) => hir::Return(self.lower_ty(ty)),
375 FunctionRetTy::Default(span) => hir::DefaultReturn(span),
a7813a04
XL
376 },
377 variadic: decl.variadic,
378 })
b039eaaf 379 }
e9174d1e 380
a7813a04
XL
381 fn lower_ty_param_bound(&mut self, tpb: &TyParamBound) -> hir::TyParamBound {
382 match *tpb {
383 TraitTyParamBound(ref ty, modifier) => {
384 hir::TraitTyParamBound(self.lower_poly_trait_ref(ty),
385 self.lower_trait_bound_modifier(modifier))
386 }
387 RegionTyParamBound(ref lifetime) => {
388 hir::RegionTyParamBound(self.lower_lifetime(lifetime))
389 }
390 }
b039eaaf 391 }
e9174d1e 392
a7813a04 393 fn lower_ty_param(&mut self, tp: &TyParam) -> hir::TyParam {
9e0c209e
SL
394 let mut name = tp.ident.name;
395
396 // Don't expose `Self` (recovered "keyword used as ident" parse error).
397 // `rustc::ty` expects `Self` to be only used for a trait's `Self`.
398 // Instead, use gensym("Self") to create a distinct name that looks the same.
399 if name == token::keywords::SelfType.name() {
400 name = token::gensym("Self");
401 }
402
a7813a04
XL
403 hir::TyParam {
404 id: tp.id,
9e0c209e 405 name: name,
a7813a04
XL
406 bounds: self.lower_bounds(&tp.bounds),
407 default: tp.default.as_ref().map(|x| self.lower_ty(x)),
408 span: tp.span,
e9174d1e 409 }
e9174d1e 410 }
e9174d1e 411
a7813a04
XL
412 fn lower_ty_params(&mut self, tps: &P<[TyParam]>) -> hir::HirVec<hir::TyParam> {
413 tps.iter().map(|tp| self.lower_ty_param(tp)).collect()
e9174d1e 414 }
e9174d1e 415
a7813a04
XL
416 fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
417 hir::Lifetime {
418 id: l.id,
419 name: l.name,
420 span: l.span,
421 }
b039eaaf 422 }
e9174d1e 423
a7813a04
XL
424 fn lower_lifetime_def(&mut self, l: &LifetimeDef) -> hir::LifetimeDef {
425 hir::LifetimeDef {
426 lifetime: self.lower_lifetime(&l.lifetime),
427 bounds: self.lower_lifetimes(&l.bounds),
428 }
b039eaaf 429 }
e9174d1e 430
a7813a04
XL
431 fn lower_lifetimes(&mut self, lts: &Vec<Lifetime>) -> hir::HirVec<hir::Lifetime> {
432 lts.iter().map(|l| self.lower_lifetime(l)).collect()
433 }
e9174d1e 434
a7813a04
XL
435 fn lower_lifetime_defs(&mut self, lts: &Vec<LifetimeDef>) -> hir::HirVec<hir::LifetimeDef> {
436 lts.iter().map(|l| self.lower_lifetime_def(l)).collect()
e9174d1e 437 }
e9174d1e 438
a7813a04
XL
439 fn lower_opt_lifetime(&mut self, o_lt: &Option<Lifetime>) -> Option<hir::Lifetime> {
440 o_lt.as_ref().map(|lt| self.lower_lifetime(lt))
e9174d1e 441 }
e9174d1e 442
a7813a04
XL
443 fn lower_generics(&mut self, g: &Generics) -> hir::Generics {
444 hir::Generics {
445 ty_params: self.lower_ty_params(&g.ty_params),
446 lifetimes: self.lower_lifetime_defs(&g.lifetimes),
447 where_clause: self.lower_where_clause(&g.where_clause),
9e0c209e 448 span: g.span,
e9174d1e
SL
449 }
450 }
e9174d1e 451
a7813a04
XL
452 fn lower_where_clause(&mut self, wc: &WhereClause) -> hir::WhereClause {
453 hir::WhereClause {
454 id: wc.id,
455 predicates: wc.predicates
456 .iter()
457 .map(|predicate| self.lower_where_predicate(predicate))
458 .collect(),
b039eaaf 459 }
b039eaaf 460 }
e9174d1e 461
a7813a04
XL
462 fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate {
463 match *pred {
464 WherePredicate::BoundPredicate(WhereBoundPredicate{ ref bound_lifetimes,
465 ref bounded_ty,
466 ref bounds,
467 span}) => {
468 hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
469 bound_lifetimes: self.lower_lifetime_defs(bound_lifetimes),
470 bounded_ty: self.lower_ty(bounded_ty),
471 bounds: bounds.iter().map(|x| self.lower_ty_param_bound(x)).collect(),
472 span: span,
473 })
474 }
475 WherePredicate::RegionPredicate(WhereRegionPredicate{ ref lifetime,
476 ref bounds,
477 span}) => {
478 hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
479 span: span,
480 lifetime: self.lower_lifetime(lifetime),
481 bounds: bounds.iter().map(|bound| self.lower_lifetime(bound)).collect(),
482 })
483 }
484 WherePredicate::EqPredicate(WhereEqPredicate{ id,
485 ref path,
486 ref ty,
487 span}) => {
488 hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
489 id: id,
490 path: self.lower_path(path),
491 ty: self.lower_ty(ty),
492 span: span,
493 })
494 }
495 }
b039eaaf 496 }
e9174d1e 497
a7813a04
XL
498 fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData {
499 match *vdata {
500 VariantData::Struct(ref fields, id) => {
501 hir::VariantData::Struct(fields.iter()
502 .enumerate()
503 .map(|f| self.lower_struct_field(f))
504 .collect(),
505 id)
506 }
507 VariantData::Tuple(ref fields, id) => {
508 hir::VariantData::Tuple(fields.iter()
509 .enumerate()
510 .map(|f| self.lower_struct_field(f))
511 .collect(),
512 id)
513 }
514 VariantData::Unit(id) => hir::VariantData::Unit(id),
515 }
e9174d1e 516 }
e9174d1e 517
a7813a04
XL
518 fn lower_trait_ref(&mut self, p: &TraitRef) -> hir::TraitRef {
519 hir::TraitRef {
520 path: self.lower_path(&p.path),
521 ref_id: p.ref_id,
522 }
e9174d1e 523 }
e9174d1e 524
a7813a04
XL
525 fn lower_poly_trait_ref(&mut self, p: &PolyTraitRef) -> hir::PolyTraitRef {
526 hir::PolyTraitRef {
527 bound_lifetimes: self.lower_lifetime_defs(&p.bound_lifetimes),
528 trait_ref: self.lower_trait_ref(&p.trait_ref),
529 span: p.span,
530 }
b039eaaf 531 }
e9174d1e 532
a7813a04
XL
533 fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::StructField {
534 hir::StructField {
535 span: f.span,
536 id: f.id,
537 name: f.ident.map(|ident| ident.name).unwrap_or(token::intern(&index.to_string())),
538 vis: self.lower_visibility(&f.vis),
539 ty: self.lower_ty(&f.ty),
540 attrs: self.lower_attrs(&f.attrs),
541 }
b039eaaf 542 }
e9174d1e 543
a7813a04
XL
544 fn lower_field(&mut self, f: &Field) -> hir::Field {
545 hir::Field {
546 name: respan(f.ident.span, f.ident.node.name),
547 expr: self.lower_expr(&f.expr),
548 span: f.span,
549 }
550 }
e9174d1e 551
a7813a04
XL
552 fn lower_mt(&mut self, mt: &MutTy) -> hir::MutTy {
553 hir::MutTy {
554 ty: self.lower_ty(&mt.ty),
555 mutbl: self.lower_mutability(mt.mutbl),
556 }
557 }
e9174d1e 558
a7813a04
XL
559 fn lower_bounds(&mut self, bounds: &TyParamBounds) -> hir::TyParamBounds {
560 bounds.iter().map(|bound| self.lower_ty_param_bound(bound)).collect()
561 }
e9174d1e 562
a7813a04 563 fn lower_block(&mut self, b: &Block) -> P<hir::Block> {
3157f602
XL
564 let mut stmts = Vec::new();
565 let mut expr = None;
566
567 if let Some((last, rest)) = b.stmts.split_last() {
568 stmts = rest.iter().map(|s| self.lower_stmt(s)).collect::<Vec<_>>();
569 let last = self.lower_stmt(last);
570 if let hir::StmtExpr(e, _) = last.node {
571 expr = Some(e);
572 } else {
573 stmts.push(last);
574 }
575 }
576
a7813a04
XL
577 P(hir::Block {
578 id: b.id,
3157f602
XL
579 stmts: stmts.into(),
580 expr: expr,
a7813a04
XL
581 rules: self.lower_block_check_mode(&b.rules),
582 span: b.span,
583 })
e9174d1e 584 }
e9174d1e 585
a7813a04
XL
586 fn lower_item_kind(&mut self, i: &ItemKind) -> hir::Item_ {
587 match *i {
588 ItemKind::ExternCrate(string) => hir::ItemExternCrate(string),
589 ItemKind::Use(ref view_path) => {
590 hir::ItemUse(self.lower_view_path(view_path))
e9174d1e 591 }
a7813a04
XL
592 ItemKind::Static(ref t, m, ref e) => {
593 hir::ItemStatic(self.lower_ty(t),
594 self.lower_mutability(m),
595 self.lower_expr(e))
e9174d1e 596 }
a7813a04
XL
597 ItemKind::Const(ref t, ref e) => {
598 hir::ItemConst(self.lower_ty(t), self.lower_expr(e))
e9174d1e 599 }
a7813a04
XL
600 ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
601 hir::ItemFn(self.lower_fn_decl(decl),
602 self.lower_unsafety(unsafety),
603 self.lower_constness(constness),
604 abi,
605 self.lower_generics(generics),
606 self.lower_block(body))
e9174d1e 607 }
a7813a04
XL
608 ItemKind::Mod(ref m) => hir::ItemMod(self.lower_mod(m)),
609 ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(self.lower_foreign_mod(nm)),
610 ItemKind::Ty(ref t, ref generics) => {
611 hir::ItemTy(self.lower_ty(t), self.lower_generics(generics))
e9174d1e 612 }
a7813a04
XL
613 ItemKind::Enum(ref enum_definition, ref generics) => {
614 hir::ItemEnum(hir::EnumDef {
615 variants: enum_definition.variants
616 .iter()
617 .map(|x| self.lower_variant(x))
618 .collect(),
619 },
620 self.lower_generics(generics))
621 }
622 ItemKind::Struct(ref struct_def, ref generics) => {
623 let struct_def = self.lower_variant_data(struct_def);
624 hir::ItemStruct(struct_def, self.lower_generics(generics))
625 }
9e0c209e
SL
626 ItemKind::Union(ref vdata, ref generics) => {
627 let vdata = self.lower_variant_data(vdata);
628 hir::ItemUnion(vdata, self.lower_generics(generics))
629 }
a7813a04
XL
630 ItemKind::DefaultImpl(unsafety, ref trait_ref) => {
631 hir::ItemDefaultImpl(self.lower_unsafety(unsafety),
632 self.lower_trait_ref(trait_ref))
633 }
634 ItemKind::Impl(unsafety, polarity, ref generics, ref ifce, ref ty, ref impl_items) => {
635 let new_impl_items = impl_items.iter()
636 .map(|item| self.lower_impl_item(item))
637 .collect();
638 let ifce = ifce.as_ref().map(|trait_ref| self.lower_trait_ref(trait_ref));
639 hir::ItemImpl(self.lower_unsafety(unsafety),
640 self.lower_impl_polarity(polarity),
641 self.lower_generics(generics),
642 ifce,
643 self.lower_ty(ty),
644 new_impl_items)
645 }
646 ItemKind::Trait(unsafety, ref generics, ref bounds, ref items) => {
647 let bounds = self.lower_bounds(bounds);
648 let items = items.iter().map(|item| self.lower_trait_item(item)).collect();
649 hir::ItemTrait(self.lower_unsafety(unsafety),
650 self.lower_generics(generics),
651 bounds,
652 items)
653 }
654 ItemKind::Mac(_) => panic!("Shouldn't still be around"),
655 }
92a42be0 656 }
e9174d1e 657
a7813a04
XL
658 fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
659 self.with_parent_def(i.id, |this| {
660 hir::TraitItem {
661 id: i.id,
662 name: i.ident.name,
663 attrs: this.lower_attrs(&i.attrs),
664 node: match i.node {
665 TraitItemKind::Const(ref ty, ref default) => {
666 hir::ConstTraitItem(this.lower_ty(ty),
667 default.as_ref().map(|x| this.lower_expr(x)))
668 }
669 TraitItemKind::Method(ref sig, ref body) => {
670 hir::MethodTraitItem(this.lower_method_sig(sig),
671 body.as_ref().map(|x| this.lower_block(x)))
672 }
673 TraitItemKind::Type(ref bounds, ref default) => {
674 hir::TypeTraitItem(this.lower_bounds(bounds),
675 default.as_ref().map(|x| this.lower_ty(x)))
676 }
3157f602 677 TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"),
a7813a04
XL
678 },
679 span: i.span,
680 }
681 })
682 }
683
684 fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
685 self.with_parent_def(i.id, |this| {
686 hir::ImplItem {
687 id: i.id,
688 name: i.ident.name,
689 attrs: this.lower_attrs(&i.attrs),
690 vis: this.lower_visibility(&i.vis),
691 defaultness: this.lower_defaultness(i.defaultness),
692 node: match i.node {
693 ImplItemKind::Const(ref ty, ref expr) => {
694 hir::ImplItemKind::Const(this.lower_ty(ty), this.lower_expr(expr))
695 }
696 ImplItemKind::Method(ref sig, ref body) => {
697 hir::ImplItemKind::Method(this.lower_method_sig(sig),
698 this.lower_block(body))
699 }
700 ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(this.lower_ty(ty)),
701 ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
702 },
703 span: i.span,
704 }
705 })
92a42be0 706 }
92a42be0 707
a7813a04
XL
708 fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
709 hir::Mod {
710 inner: m.inner,
711 item_ids: m.items.iter().map(|x| self.lower_item_id(x)).collect(),
712 }
b039eaaf 713 }
e9174d1e 714
a7813a04
XL
715 fn lower_macro_def(&mut self, m: &MacroDef) -> hir::MacroDef {
716 hir::MacroDef {
717 name: m.ident.name,
718 attrs: self.lower_attrs(&m.attrs),
719 id: m.id,
720 span: m.span,
721 imported_from: m.imported_from.map(|x| x.name),
722 export: m.export,
723 use_locally: m.use_locally,
724 allow_internal_unstable: m.allow_internal_unstable,
725 body: m.body.clone().into(),
726 }
e9174d1e 727 }
e9174d1e 728
a7813a04
XL
729 fn lower_item_id(&mut self, i: &Item) -> hir::ItemId {
730 hir::ItemId { id: i.id }
e9174d1e 731 }
e9174d1e 732
a7813a04
XL
733 pub fn lower_item(&mut self, i: &Item) -> hir::Item {
734 let node = self.with_parent_def(i.id, |this| {
735 this.lower_item_kind(&i.node)
736 });
e9174d1e 737
a7813a04
XL
738 hir::Item {
739 id: i.id,
740 name: i.ident.name,
741 attrs: self.lower_attrs(&i.attrs),
742 node: node,
743 vis: self.lower_visibility(&i.vis),
744 span: i.span,
745 }
e9174d1e 746 }
e9174d1e 747
a7813a04
XL
748 fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
749 self.with_parent_def(i.id, |this| {
750 hir::ForeignItem {
751 id: i.id,
752 name: i.ident.name,
753 attrs: this.lower_attrs(&i.attrs),
754 node: match i.node {
755 ForeignItemKind::Fn(ref fdec, ref generics) => {
756 hir::ForeignItemFn(this.lower_fn_decl(fdec), this.lower_generics(generics))
757 }
758 ForeignItemKind::Static(ref t, m) => {
759 hir::ForeignItemStatic(this.lower_ty(t), m)
760 }
761 },
762 vis: this.lower_visibility(&i.vis),
763 span: i.span,
e9174d1e 764 }
a7813a04 765 })
92a42be0 766 }
e9174d1e 767
a7813a04 768 fn lower_method_sig(&mut self, sig: &MethodSig) -> hir::MethodSig {
3157f602 769 let hir_sig = hir::MethodSig {
a7813a04
XL
770 generics: self.lower_generics(&sig.generics),
771 abi: sig.abi,
772 unsafety: self.lower_unsafety(sig.unsafety),
773 constness: self.lower_constness(sig.constness),
774 decl: self.lower_fn_decl(&sig.decl),
3157f602
XL
775 };
776 // Check for `self: _` and `self: &_`
777 if let Some(SelfKind::Explicit(..)) = sig.decl.get_self().map(|eself| eself.node) {
778 match hir_sig.decl.get_self().map(|eself| eself.node) {
779 Some(hir::SelfKind::Value(..)) | Some(hir::SelfKind::Region(..)) => {
780 self.diagnostic().span_err(sig.decl.inputs[0].ty.span,
781 "the type placeholder `_` is not allowed within types on item signatures");
782 }
783 _ => {}
784 }
a7813a04 785 }
3157f602 786 hir_sig
e9174d1e 787 }
e9174d1e 788
a7813a04
XL
789 fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
790 match u {
791 Unsafety::Unsafe => hir::Unsafety::Unsafe,
792 Unsafety::Normal => hir::Unsafety::Normal,
793 }
e9174d1e 794 }
e9174d1e 795
9e0c209e
SL
796 fn lower_constness(&mut self, c: Spanned<Constness>) -> hir::Constness {
797 match c.node {
a7813a04
XL
798 Constness::Const => hir::Constness::Const,
799 Constness::NotConst => hir::Constness::NotConst,
800 }
e9174d1e 801 }
e9174d1e 802
a7813a04
XL
803 fn lower_unop(&mut self, u: UnOp) -> hir::UnOp {
804 match u {
805 UnOp::Deref => hir::UnDeref,
806 UnOp::Not => hir::UnNot,
807 UnOp::Neg => hir::UnNeg,
808 }
e9174d1e 809 }
e9174d1e 810
a7813a04
XL
811 fn lower_binop(&mut self, b: BinOp) -> hir::BinOp {
812 Spanned {
813 node: match b.node {
814 BinOpKind::Add => hir::BiAdd,
815 BinOpKind::Sub => hir::BiSub,
816 BinOpKind::Mul => hir::BiMul,
817 BinOpKind::Div => hir::BiDiv,
818 BinOpKind::Rem => hir::BiRem,
819 BinOpKind::And => hir::BiAnd,
820 BinOpKind::Or => hir::BiOr,
821 BinOpKind::BitXor => hir::BiBitXor,
822 BinOpKind::BitAnd => hir::BiBitAnd,
823 BinOpKind::BitOr => hir::BiBitOr,
824 BinOpKind::Shl => hir::BiShl,
825 BinOpKind::Shr => hir::BiShr,
826 BinOpKind::Eq => hir::BiEq,
827 BinOpKind::Lt => hir::BiLt,
828 BinOpKind::Le => hir::BiLe,
829 BinOpKind::Ne => hir::BiNe,
830 BinOpKind::Ge => hir::BiGe,
831 BinOpKind::Gt => hir::BiGt,
832 },
833 span: b.span,
834 }
e9174d1e 835 }
e9174d1e 836
a7813a04
XL
837 fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
838 P(hir::Pat {
839 id: p.id,
840 node: match p.node {
841 PatKind::Wild => hir::PatKind::Wild,
842 PatKind::Ident(ref binding_mode, pth1, ref sub) => {
843 self.with_parent_def(p.id, |this| {
3157f602
XL
844 match this.resolver.get_resolution(p.id).map(|d| d.base_def) {
845 // `None` can occur in body-less function signatures
846 None | Some(Def::Local(..)) => {
847 hir::PatKind::Binding(this.lower_binding_mode(binding_mode),
848 respan(pth1.span, pth1.node.name),
849 sub.as_ref().map(|x| this.lower_pat(x)))
850 }
5bcae85e
SL
851 _ => hir::PatKind::Path(None, hir::Path::from_name(pth1.span,
852 pth1.node.name))
3157f602 853 }
a7813a04
XL
854 })
855 }
856 PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)),
3157f602 857 PatKind::TupleStruct(ref pth, ref pats, ddpos) => {
a7813a04 858 hir::PatKind::TupleStruct(self.lower_path(pth),
3157f602
XL
859 pats.iter().map(|x| self.lower_pat(x)).collect(),
860 ddpos)
a7813a04 861 }
5bcae85e
SL
862 PatKind::Path(ref opt_qself, ref path) => {
863 let opt_qself = opt_qself.as_ref().map(|qself| {
864 hir::QSelf { ty: self.lower_ty(&qself.ty), position: qself.position }
865 });
866 hir::PatKind::Path(opt_qself, self.lower_path(path))
a7813a04
XL
867 }
868 PatKind::Struct(ref pth, ref fields, etc) => {
869 let pth = self.lower_path(pth);
870 let fs = fields.iter()
871 .map(|f| {
872 Spanned {
873 span: f.span,
874 node: hir::FieldPat {
875 name: f.node.ident.name,
876 pat: self.lower_pat(&f.node.pat),
877 is_shorthand: f.node.is_shorthand,
878 },
879 }
880 })
881 .collect();
882 hir::PatKind::Struct(pth, fs, etc)
883 }
3157f602
XL
884 PatKind::Tuple(ref elts, ddpos) => {
885 hir::PatKind::Tuple(elts.iter().map(|x| self.lower_pat(x)).collect(), ddpos)
a7813a04
XL
886 }
887 PatKind::Box(ref inner) => hir::PatKind::Box(self.lower_pat(inner)),
888 PatKind::Ref(ref inner, mutbl) => {
889 hir::PatKind::Ref(self.lower_pat(inner), self.lower_mutability(mutbl))
890 }
891 PatKind::Range(ref e1, ref e2) => {
892 hir::PatKind::Range(self.lower_expr(e1), self.lower_expr(e2))
893 }
894 PatKind::Vec(ref before, ref slice, ref after) => {
895 hir::PatKind::Vec(before.iter().map(|x| self.lower_pat(x)).collect(),
896 slice.as_ref().map(|x| self.lower_pat(x)),
897 after.iter().map(|x| self.lower_pat(x)).collect())
898 }
899 PatKind::Mac(_) => panic!("Shouldn't exist here"),
900 },
901 span: p.span,
902 })
903 }
904
905 fn lower_expr(&mut self, e: &Expr) -> P<hir::Expr> {
906 P(hir::Expr {
907 id: e.id,
908 node: match e.node {
909 // Issue #22181:
910 // Eventually a desugaring for `box EXPR`
911 // (similar to the desugaring above for `in PLACE BLOCK`)
912 // should go here, desugaring
913 //
b039eaaf
SL
914 // to:
915 //
a7813a04 916 // let mut place = BoxPlace::make_place();
b039eaaf 917 // let raw_place = Place::pointer(&mut place);
a7813a04
XL
918 // let value = $value;
919 // unsafe {
920 // ::std::ptr::write(raw_place, value);
921 // Boxed::finalize(place)
922 // }
923 //
924 // But for now there are type-inference issues doing that.
925 ExprKind::Box(ref e) => {
926 hir::ExprBox(self.lower_expr(e))
927 }
928
929 // Desugar ExprBox: `in (PLACE) EXPR`
930 ExprKind::InPlace(ref placer, ref value_expr) => {
931 // to:
932 //
933 // let p = PLACE;
934 // let mut place = Placer::make_place(p);
935 // let raw_place = Place::pointer(&mut place);
936 // push_unsafe!({
937 // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR ));
938 // InPlace::finalize(place)
939 // })
940 let placer_expr = self.lower_expr(placer);
941 let value_expr = self.lower_expr(value_expr);
942
943 let placer_ident = self.str_to_ident("placer");
944 let place_ident = self.str_to_ident("place");
945 let p_ptr_ident = self.str_to_ident("p_ptr");
92a42be0
SL
946
947 let make_place = ["ops", "Placer", "make_place"];
948 let place_pointer = ["ops", "Place", "pointer"];
949 let move_val_init = ["intrinsics", "move_val_init"];
950 let inplace_finalize = ["ops", "InPlace", "finalize"];
951
a7813a04 952 let make_call = |this: &mut LoweringContext, p, args| {
9e0c209e 953 let path = this.std_path(e.span, p);
3157f602
XL
954 let path = this.expr_path(path, ThinVec::new());
955 this.expr_call(e.span, path, args)
92a42be0 956 };
b039eaaf 957
a7813a04 958 let mk_stmt_let = |this: &mut LoweringContext, bind, expr| {
3157f602 959 this.stmt_let(e.span, false, bind, expr)
92a42be0 960 };
b039eaaf 961
a7813a04 962 let mk_stmt_let_mut = |this: &mut LoweringContext, bind, expr| {
3157f602 963 this.stmt_let(e.span, true, bind, expr)
92a42be0 964 };
b039eaaf 965
92a42be0 966 // let placer = <placer_expr> ;
a7813a04
XL
967 let (s1, placer_binding) = {
968 let placer_expr = self.signal_block_expr(hir_vec![],
969 placer_expr,
970 e.span,
971 hir::PopUnstableBlock,
3157f602 972 ThinVec::new());
a7813a04 973 mk_stmt_let(self, placer_ident, placer_expr)
92a42be0 974 };
b039eaaf 975
92a42be0 976 // let mut place = Placer::make_place(placer);
a7813a04 977 let (s2, place_binding) = {
3157f602 978 let placer = self.expr_ident(e.span, placer_ident, placer_binding);
a7813a04
XL
979 let call = make_call(self, &make_place, hir_vec![placer]);
980 mk_stmt_let_mut(self, place_ident, call)
92a42be0 981 };
b039eaaf 982
92a42be0 983 // let p_ptr = Place::pointer(&mut place);
a7813a04 984 let (s3, p_ptr_binding) = {
3157f602
XL
985 let agent = self.expr_ident(e.span, place_ident, place_binding);
986 let args = hir_vec![self.expr_mut_addr_of(e.span, agent)];
a7813a04
XL
987 let call = make_call(self, &place_pointer, args);
988 mk_stmt_let(self, p_ptr_ident, call)
92a42be0 989 };
b039eaaf 990
92a42be0
SL
991 // pop_unsafe!(EXPR));
992 let pop_unsafe_expr = {
a7813a04
XL
993 let value_expr = self.signal_block_expr(hir_vec![],
994 value_expr,
995 e.span,
996 hir::PopUnstableBlock,
3157f602 997 ThinVec::new());
a7813a04
XL
998 self.signal_block_expr(hir_vec![],
999 value_expr,
1000 e.span,
3157f602
XL
1001 hir::PopUnsafeBlock(hir::CompilerGenerated),
1002 ThinVec::new())
92a42be0 1003 };
b039eaaf 1004
92a42be0
SL
1005 // push_unsafe!({
1006 // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR ));
1007 // InPlace::finalize(place)
1008 // })
1009 let expr = {
3157f602 1010 let ptr = self.expr_ident(e.span, p_ptr_ident, p_ptr_binding);
92a42be0
SL
1011 let call_move_val_init =
1012 hir::StmtSemi(
a7813a04
XL
1013 make_call(self, &move_val_init, hir_vec![ptr, pop_unsafe_expr]),
1014 self.next_id());
92a42be0
SL
1015 let call_move_val_init = respan(e.span, call_move_val_init);
1016
3157f602 1017 let place = self.expr_ident(e.span, place_ident, place_binding);
a7813a04
XL
1018 let call = make_call(self, &inplace_finalize, hir_vec![place]);
1019 self.signal_block_expr(hir_vec![call_move_val_init],
1020 call,
1021 e.span,
3157f602
XL
1022 hir::PushUnsafeBlock(hir::CompilerGenerated),
1023 ThinVec::new())
92a42be0 1024 };
b039eaaf 1025
a7813a04
XL
1026 return self.signal_block_expr(hir_vec![s1, s2, s3],
1027 expr,
1028 e.span,
1029 hir::PushUnstableBlock,
1030 e.attrs.clone());
1031 }
b039eaaf 1032
a7813a04
XL
1033 ExprKind::Vec(ref exprs) => {
1034 hir::ExprVec(exprs.iter().map(|x| self.lower_expr(x)).collect())
1035 }
1036 ExprKind::Repeat(ref expr, ref count) => {
1037 let expr = self.lower_expr(expr);
1038 let count = self.lower_expr(count);
1039 hir::ExprRepeat(expr, count)
1040 }
1041 ExprKind::Tup(ref elts) => {
1042 hir::ExprTup(elts.iter().map(|x| self.lower_expr(x)).collect())
1043 }
1044 ExprKind::Call(ref f, ref args) => {
1045 let f = self.lower_expr(f);
1046 hir::ExprCall(f, args.iter().map(|x| self.lower_expr(x)).collect())
1047 }
1048 ExprKind::MethodCall(i, ref tps, ref args) => {
1049 let tps = tps.iter().map(|x| self.lower_ty(x)).collect();
1050 let args = args.iter().map(|x| self.lower_expr(x)).collect();
1051 hir::ExprMethodCall(respan(i.span, i.node.name), tps, args)
1052 }
1053 ExprKind::Binary(binop, ref lhs, ref rhs) => {
1054 let binop = self.lower_binop(binop);
1055 let lhs = self.lower_expr(lhs);
1056 let rhs = self.lower_expr(rhs);
1057 hir::ExprBinary(binop, lhs, rhs)
1058 }
1059 ExprKind::Unary(op, ref ohs) => {
1060 let op = self.lower_unop(op);
1061 let ohs = self.lower_expr(ohs);
1062 hir::ExprUnary(op, ohs)
1063 }
1064 ExprKind::Lit(ref l) => hir::ExprLit(P((**l).clone())),
1065 ExprKind::Cast(ref expr, ref ty) => {
1066 let expr = self.lower_expr(expr);
1067 hir::ExprCast(expr, self.lower_ty(ty))
1068 }
1069 ExprKind::Type(ref expr, ref ty) => {
1070 let expr = self.lower_expr(expr);
1071 hir::ExprType(expr, self.lower_ty(ty))
1072 }
1073 ExprKind::AddrOf(m, ref ohs) => {
1074 let m = self.lower_mutability(m);
1075 let ohs = self.lower_expr(ohs);
1076 hir::ExprAddrOf(m, ohs)
1077 }
1078 // More complicated than you might expect because the else branch
1079 // might be `if let`.
1080 ExprKind::If(ref cond, ref blk, ref else_opt) => {
1081 let else_opt = else_opt.as_ref().map(|els| {
1082 match els.node {
1083 ExprKind::IfLet(..) => {
92a42be0
SL
1084 // wrap the if-let expr in a block
1085 let span = els.span;
a7813a04
XL
1086 let els = self.lower_expr(els);
1087 let id = self.next_id();
92a42be0 1088 let blk = P(hir::Block {
9cc50fc6 1089 stmts: hir_vec![],
92a42be0
SL
1090 expr: Some(els),
1091 id: id,
1092 rules: hir::DefaultBlock,
1093 span: span,
1094 });
3157f602 1095 self.expr_block(blk, ThinVec::new())
a7813a04
XL
1096 }
1097 _ => self.lower_expr(els),
e9174d1e 1098 }
a7813a04 1099 });
54a0048b 1100
a7813a04
XL
1101 hir::ExprIf(self.lower_expr(cond), self.lower_block(blk), else_opt)
1102 }
1103 ExprKind::While(ref cond, ref body, opt_ident) => {
1104 hir::ExprWhile(self.lower_expr(cond), self.lower_block(body),
3157f602 1105 self.lower_opt_sp_ident(opt_ident))
a7813a04
XL
1106 }
1107 ExprKind::Loop(ref body, opt_ident) => {
3157f602 1108 hir::ExprLoop(self.lower_block(body), self.lower_opt_sp_ident(opt_ident))
a7813a04
XL
1109 }
1110 ExprKind::Match(ref expr, ref arms) => {
1111 hir::ExprMatch(self.lower_expr(expr),
1112 arms.iter().map(|x| self.lower_arm(x)).collect(),
1113 hir::MatchSource::Normal)
1114 }
1115 ExprKind::Closure(capture_clause, ref decl, ref body, fn_decl_span) => {
1116 self.with_parent_def(e.id, |this| {
1117 hir::ExprClosure(this.lower_capture_clause(capture_clause),
1118 this.lower_fn_decl(decl),
1119 this.lower_block(body),
1120 fn_decl_span)
1121 })
54a0048b 1122 }
a7813a04
XL
1123 ExprKind::Block(ref blk) => hir::ExprBlock(self.lower_block(blk)),
1124 ExprKind::Assign(ref el, ref er) => {
1125 hir::ExprAssign(self.lower_expr(el), self.lower_expr(er))
1126 }
1127 ExprKind::AssignOp(op, ref el, ref er) => {
1128 hir::ExprAssignOp(self.lower_binop(op),
1129 self.lower_expr(el),
1130 self.lower_expr(er))
1131 }
1132 ExprKind::Field(ref el, ident) => {
1133 hir::ExprField(self.lower_expr(el), respan(ident.span, ident.node.name))
1134 }
1135 ExprKind::TupField(ref el, ident) => {
1136 hir::ExprTupField(self.lower_expr(el), ident)
1137 }
1138 ExprKind::Index(ref el, ref er) => {
1139 hir::ExprIndex(self.lower_expr(el), self.lower_expr(er))
1140 }
1141 ExprKind::Range(ref e1, ref e2, lims) => {
1142 fn make_struct(this: &mut LoweringContext,
1143 ast_expr: &Expr,
1144 path: &[&str],
1145 fields: &[(&str, &P<Expr>)]) -> P<hir::Expr> {
9e0c209e
SL
1146 let struct_path = this.std_path(ast_expr.span,
1147 &iter::once(&"ops").chain(path)
1148 .map(|s| *s)
1149 .collect::<Vec<_>>());
a7813a04
XL
1150
1151 let hir_expr = if fields.len() == 0 {
9e0c209e 1152 this.expr_path(struct_path, ast_expr.attrs.clone())
a7813a04
XL
1153 } else {
1154 let fields = fields.into_iter().map(|&(s, e)| {
1155 let expr = this.lower_expr(&e);
1156 let signal_block = this.signal_block_expr(hir_vec![],
1157 expr,
1158 e.span,
1159 hir::PopUnstableBlock,
3157f602 1160 ThinVec::new());
a7813a04
XL
1161 this.field(token::intern(s), signal_block, ast_expr.span)
1162 }).collect();
1163 let attrs = ast_expr.attrs.clone();
1164
9e0c209e 1165 this.expr_struct(ast_expr.span, struct_path, fields, None, attrs)
a7813a04
XL
1166 };
1167
1168 this.signal_block_expr(hir_vec![],
1169 hir_expr,
1170 ast_expr.span,
1171 hir::PushUnstableBlock,
3157f602 1172 ThinVec::new())
a7813a04 1173 }
54a0048b 1174
54a0048b
SL
1175 use syntax::ast::RangeLimits::*;
1176
a7813a04 1177 return match (e1, e2, lims) {
54a0048b 1178 (&None, &None, HalfOpen) =>
a7813a04 1179 make_struct(self, e, &["RangeFull"], &[]),
54a0048b
SL
1180
1181 (&Some(ref e1), &None, HalfOpen) =>
a7813a04 1182 make_struct(self, e, &["RangeFrom"],
54a0048b
SL
1183 &[("start", e1)]),
1184
1185 (&None, &Some(ref e2), HalfOpen) =>
a7813a04 1186 make_struct(self, e, &["RangeTo"],
54a0048b
SL
1187 &[("end", e2)]),
1188
1189 (&Some(ref e1), &Some(ref e2), HalfOpen) =>
a7813a04 1190 make_struct(self, e, &["Range"],
54a0048b
SL
1191 &[("start", e1), ("end", e2)]),
1192
1193 (&None, &Some(ref e2), Closed) =>
a7813a04 1194 make_struct(self, e, &["RangeToInclusive"],
54a0048b
SL
1195 &[("end", e2)]),
1196
1197 (&Some(ref e1), &Some(ref e2), Closed) =>
a7813a04 1198 make_struct(self, e, &["RangeInclusive", "NonEmpty"],
54a0048b
SL
1199 &[("start", e1), ("end", e2)]),
1200
3157f602 1201 _ => panic!(self.diagnostic()
a7813a04
XL
1202 .span_fatal(e.span, "inclusive range with no end")),
1203 };
1204 }
1205 ExprKind::Path(ref qself, ref path) => {
1206 let hir_qself = qself.as_ref().map(|&QSelf { ref ty, position }| {
1207 hir::QSelf {
1208 ty: self.lower_ty(ty),
1209 position: position,
1210 }
92a42be0 1211 });
3157f602 1212 hir::ExprPath(hir_qself, self.lower_path(path))
a7813a04 1213 }
3157f602
XL
1214 ExprKind::Break(opt_ident) => hir::ExprBreak(self.lower_opt_sp_ident(opt_ident)),
1215 ExprKind::Continue(opt_ident) => hir::ExprAgain(self.lower_opt_sp_ident(opt_ident)),
a7813a04
XL
1216 ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| self.lower_expr(x))),
1217 ExprKind::InlineAsm(InlineAsm {
1218 ref inputs,
1219 ref outputs,
1220 ref asm,
1221 asm_str_style,
1222 ref clobbers,
1223 volatile,
1224 alignstack,
1225 dialect,
1226 expn_id,
1227 }) => hir::ExprInlineAsm(hir::InlineAsm {
1228 inputs: inputs.iter().map(|&(ref c, _)| c.clone()).collect(),
1229 outputs: outputs.iter()
1230 .map(|out| {
1231 hir::InlineAsmOutput {
1232 constraint: out.constraint.clone(),
1233 is_rw: out.is_rw,
1234 is_indirect: out.is_indirect,
1235 }
1236 })
1237 .collect(),
1238 asm: asm.clone(),
1239 asm_str_style: asm_str_style,
1240 clobbers: clobbers.clone().into(),
1241 volatile: volatile,
1242 alignstack: alignstack,
1243 dialect: dialect,
1244 expn_id: expn_id,
1245 }, outputs.iter().map(|out| self.lower_expr(&out.expr)).collect(),
1246 inputs.iter().map(|&(_, ref input)| self.lower_expr(input)).collect()),
1247 ExprKind::Struct(ref path, ref fields, ref maybe_expr) => {
1248 hir::ExprStruct(self.lower_path(path),
1249 fields.iter().map(|x| self.lower_field(x)).collect(),
1250 maybe_expr.as_ref().map(|x| self.lower_expr(x)))
1251 }
1252 ExprKind::Paren(ref ex) => {
1253 return self.lower_expr(ex).map(|mut ex| {
1254 // include parens in span, but only if it is a super-span.
1255 if e.span.contains(ex.span) {
1256 ex.span = e.span;
1257 }
1258 // merge attributes into the inner expression.
3157f602
XL
1259 let mut attrs = e.attrs.clone();
1260 attrs.extend::<Vec<_>>(ex.attrs.into());
1261 ex.attrs = attrs;
a7813a04
XL
1262 ex
1263 });
1264 }
b039eaaf 1265
a7813a04
XL
1266 // Desugar ExprIfLet
1267 // From: `if let <pat> = <sub_expr> <body> [<else_opt>]`
1268 ExprKind::IfLet(ref pat, ref sub_expr, ref body, ref else_opt) => {
1269 // to:
1270 //
1271 // match <sub_expr> {
1272 // <pat> => <body>,
1273 // [_ if <else_opt_if_cond> => <else_opt_if_body>,]
1274 // _ => [<else_opt> | ()]
1275 // }
b039eaaf 1276
92a42be0
SL
1277 // `<pat> => <body>`
1278 let pat_arm = {
a7813a04 1279 let body = self.lower_block(body);
3157f602 1280 let body_expr = self.expr_block(body, ThinVec::new());
a7813a04
XL
1281 let pat = self.lower_pat(pat);
1282 self.arm(hir_vec![pat], body_expr)
92a42be0 1283 };
b039eaaf 1284
92a42be0 1285 // `[_ if <else_opt_if_cond> => <else_opt_if_body>,]`
a7813a04 1286 let mut else_opt = else_opt.as_ref().map(|e| self.lower_expr(e));
92a42be0
SL
1287 let else_if_arms = {
1288 let mut arms = vec![];
1289 loop {
1290 let else_opt_continue = else_opt.and_then(|els| {
1291 els.and_then(|els| {
1292 match els.node {
1293 // else if
1294 hir::ExprIf(cond, then, else_opt) => {
a7813a04 1295 let pat_under = self.pat_wild(e.span);
92a42be0 1296 arms.push(hir::Arm {
9cc50fc6
SL
1297 attrs: hir_vec![],
1298 pats: hir_vec![pat_under],
92a42be0 1299 guard: Some(cond),
3157f602 1300 body: self.expr_block(then, ThinVec::new()),
92a42be0
SL
1301 });
1302 else_opt.map(|else_opt| (else_opt, true))
1303 }
1304 _ => Some((P(els), false)),
b039eaaf 1305 }
92a42be0
SL
1306 })
1307 });
1308 match else_opt_continue {
1309 Some((e, true)) => {
1310 else_opt = Some(e);
1311 }
1312 Some((e, false)) => {
1313 else_opt = Some(e);
1314 break;
1315 }
1316 None => {
1317 else_opt = None;
1318 break;
b039eaaf 1319 }
b039eaaf
SL
1320 }
1321 }
92a42be0
SL
1322 arms
1323 };
b039eaaf 1324
92a42be0 1325 let contains_else_clause = else_opt.is_some();
b039eaaf 1326
92a42be0
SL
1327 // `_ => [<else_opt> | ()]`
1328 let else_arm = {
a7813a04 1329 let pat_under = self.pat_wild(e.span);
92a42be0 1330 let else_expr =
3157f602 1331 else_opt.unwrap_or_else(|| self.expr_tuple(e.span, hir_vec![]));
a7813a04 1332 self.arm(hir_vec![pat_under], else_expr)
92a42be0 1333 };
b039eaaf 1334
92a42be0
SL
1335 let mut arms = Vec::with_capacity(else_if_arms.len() + 2);
1336 arms.push(pat_arm);
1337 arms.extend(else_if_arms);
1338 arms.push(else_arm);
b039eaaf 1339
a7813a04 1340 let sub_expr = self.lower_expr(sub_expr);
92a42be0 1341 // add attributes to the outer returned expr node
a7813a04
XL
1342 return self.expr(e.span,
1343 hir::ExprMatch(sub_expr,
1344 arms.into(),
1345 hir::MatchSource::IfLetDesugar {
1346 contains_else_clause: contains_else_clause,
1347 }),
1348 e.attrs.clone());
1349 }
1350
1351 // Desugar ExprWhileLet
1352 // From: `[opt_ident]: while let <pat> = <sub_expr> <body>`
1353 ExprKind::WhileLet(ref pat, ref sub_expr, ref body, opt_ident) => {
1354 // to:
1355 //
1356 // [opt_ident]: loop {
1357 // match <sub_expr> {
1358 // <pat> => <body>,
1359 // _ => break
1360 // }
1361 // }
b039eaaf 1362
92a42be0
SL
1363 // `<pat> => <body>`
1364 let pat_arm = {
a7813a04 1365 let body = self.lower_block(body);
3157f602 1366 let body_expr = self.expr_block(body, ThinVec::new());
a7813a04
XL
1367 let pat = self.lower_pat(pat);
1368 self.arm(hir_vec![pat], body_expr)
92a42be0 1369 };
b039eaaf 1370
92a42be0
SL
1371 // `_ => break`
1372 let break_arm = {
a7813a04 1373 let pat_under = self.pat_wild(e.span);
3157f602 1374 let break_expr = self.expr_break(e.span, ThinVec::new());
a7813a04 1375 self.arm(hir_vec![pat_under], break_expr)
92a42be0 1376 };
b039eaaf 1377
92a42be0 1378 // `match <sub_expr> { ... }`
9cc50fc6 1379 let arms = hir_vec![pat_arm, break_arm];
a7813a04
XL
1380 let sub_expr = self.lower_expr(sub_expr);
1381 let match_expr = self.expr(e.span,
1382 hir::ExprMatch(sub_expr,
1383 arms,
1384 hir::MatchSource::WhileLetDesugar),
3157f602 1385 ThinVec::new());
92a42be0
SL
1386
1387 // `[opt_ident]: loop { ... }`
a7813a04 1388 let loop_block = self.block_expr(match_expr);
3157f602 1389 let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident));
92a42be0 1390 // add attributes to the outer returned expr node
a7813a04
XL
1391 let attrs = e.attrs.clone();
1392 return P(hir::Expr { id: e.id, node: loop_expr, span: e.span, attrs: attrs });
1393 }
1394
1395 // Desugar ExprForLoop
1396 // From: `[opt_ident]: for <pat> in <head> <body>`
1397 ExprKind::ForLoop(ref pat, ref head, ref body, opt_ident) => {
1398 // to:
1399 //
1400 // {
1401 // let result = match ::std::iter::IntoIterator::into_iter(<head>) {
1402 // mut iter => {
1403 // [opt_ident]: loop {
1404 // match ::std::iter::Iterator::next(&mut iter) {
1405 // ::std::option::Option::Some(<pat>) => <body>,
1406 // ::std::option::Option::None => break
1407 // }
1408 // }
1409 // }
1410 // };
1411 // result
1412 // }
b039eaaf 1413
92a42be0 1414 // expand <head>
a7813a04 1415 let head = self.lower_expr(head);
92a42be0 1416
a7813a04 1417 let iter = self.str_to_ident("iter");
92a42be0
SL
1418
1419 // `::std::option::Option::Some(<pat>) => <body>`
1420 let pat_arm = {
a7813a04 1421 let body_block = self.lower_block(body);
92a42be0
SL
1422 let body_span = body_block.span;
1423 let body_expr = P(hir::Expr {
a7813a04 1424 id: self.next_id(),
92a42be0
SL
1425 node: hir::ExprBlock(body_block),
1426 span: body_span,
3157f602 1427 attrs: ThinVec::new(),
92a42be0 1428 });
a7813a04
XL
1429 let pat = self.lower_pat(pat);
1430 let some_pat = self.pat_some(e.span, pat);
b039eaaf 1431
a7813a04 1432 self.arm(hir_vec![some_pat], body_expr)
92a42be0 1433 };
b039eaaf 1434
92a42be0
SL
1435 // `::std::option::Option::None => break`
1436 let break_arm = {
3157f602 1437 let break_expr = self.expr_break(e.span, ThinVec::new());
a7813a04
XL
1438 let pat = self.pat_none(e.span);
1439 self.arm(hir_vec![pat], break_expr)
92a42be0 1440 };
b039eaaf 1441
a7813a04
XL
1442 // `mut iter`
1443 let iter_pat = self.pat_ident_binding_mode(e.span, iter,
1444 hir::BindByValue(hir::MutMutable));
1445
92a42be0
SL
1446 // `match ::std::iter::Iterator::next(&mut iter) { ... }`
1447 let match_expr = {
9e0c209e 1448 let next_path = self.std_path(e.span, &["iter", "Iterator", "next"]);
3157f602
XL
1449 let iter = self.expr_ident(e.span, iter, iter_pat.id);
1450 let ref_mut_iter = self.expr_mut_addr_of(e.span, iter);
1451 let next_path = self.expr_path(next_path, ThinVec::new());
1452 let next_expr = self.expr_call(e.span, next_path, hir_vec![ref_mut_iter]);
9cc50fc6 1453 let arms = hir_vec![pat_arm, break_arm];
92a42be0 1454
a7813a04
XL
1455 self.expr(e.span,
1456 hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar),
3157f602 1457 ThinVec::new())
b039eaaf 1458 };
b039eaaf 1459
92a42be0 1460 // `[opt_ident]: loop { ... }`
a7813a04 1461 let loop_block = self.block_expr(match_expr);
3157f602
XL
1462 let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident));
1463 let loop_expr = P(hir::Expr {
1464 id: e.id,
1465 node: loop_expr,
1466 span: e.span,
1467 attrs: ThinVec::new(),
1468 });
92a42be0
SL
1469
1470 // `mut iter => { ... }`
a7813a04 1471 let iter_arm = self.arm(hir_vec![iter_pat], loop_expr);
b039eaaf 1472
92a42be0
SL
1473 // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
1474 let into_iter_expr = {
9e0c209e
SL
1475 let into_iter_path = self.std_path(e.span,
1476 &["iter", "IntoIterator", "into_iter"]);
b039eaaf 1477
3157f602
XL
1478 let into_iter = self.expr_path(into_iter_path, ThinVec::new());
1479 self.expr_call(e.span, into_iter, hir_vec![head])
b039eaaf
SL
1480 };
1481
a7813a04
XL
1482 let match_expr = self.expr_match(e.span,
1483 into_iter_expr,
1484 hir_vec![iter_arm],
3157f602 1485 hir::MatchSource::ForLoopDesugar);
92a42be0 1486
9cc50fc6
SL
1487 // `{ let _result = ...; _result }`
1488 // underscore prevents an unused_variables lint if the head diverges
a7813a04
XL
1489 let result_ident = self.str_to_ident("_result");
1490 let (let_stmt, let_stmt_binding) =
3157f602 1491 self.stmt_let(e.span, false, result_ident, match_expr);
a7813a04 1492
3157f602 1493 let result = self.expr_ident(e.span, result_ident, let_stmt_binding);
a7813a04 1494 let block = self.block_all(e.span, hir_vec![let_stmt], Some(result));
92a42be0 1495 // add the attributes to the outer returned expr node
a7813a04
XL
1496 return self.expr_block(block, e.attrs.clone());
1497 }
b039eaaf 1498
a7813a04
XL
1499 // Desugar ExprKind::Try
1500 // From: `<expr>?`
1501 ExprKind::Try(ref sub_expr) => {
1502 // to:
1503 //
1504 // {
9e0c209e 1505 // match { Carrier::translate( { <expr> } ) } {
a7813a04 1506 // Ok(val) => val,
9e0c209e 1507 // Err(err) => { return Carrier::from_error(From::from(err)); }
a7813a04
XL
1508 // }
1509 // }
54a0048b 1510
9e0c209e
SL
1511 // { Carrier::translate( { <expr> } ) }
1512 let discr = {
1513 // expand <expr>
1514 let sub_expr = self.lower_expr(sub_expr);
1515 let sub_expr = self.signal_block_expr(hir_vec![],
1516 sub_expr,
1517 e.span,
1518 hir::PopUnstableBlock,
1519 ThinVec::new());
1520
1521 let path = self.std_path(e.span, &["ops", "Carrier", "translate"]);
1522 let path = self.expr_path(path, ThinVec::new());
1523 let call = self.expr_call(e.span, path, hir_vec![sub_expr]);
1524
1525 self.signal_block_expr(hir_vec![],
1526 call,
1527 e.span,
1528 hir::PushUnstableBlock,
1529 ThinVec::new())
1530 };
54a0048b
SL
1531
1532 // Ok(val) => val
1533 let ok_arm = {
a7813a04
XL
1534 let val_ident = self.str_to_ident("val");
1535 let val_pat = self.pat_ident(e.span, val_ident);
3157f602 1536 let val_expr = self.expr_ident(e.span, val_ident, val_pat.id);
a7813a04 1537 let ok_pat = self.pat_ok(e.span, val_pat);
54a0048b 1538
a7813a04 1539 self.arm(hir_vec![ok_pat], val_expr)
54a0048b
SL
1540 };
1541
9e0c209e 1542 // Err(err) => { return Carrier::from_error(From::from(err)); }
54a0048b 1543 let err_arm = {
a7813a04
XL
1544 let err_ident = self.str_to_ident("err");
1545 let err_local = self.pat_ident(e.span, err_ident);
54a0048b 1546 let from_expr = {
9e0c209e 1547 let path = self.std_path(e.span, &["convert", "From", "from"]);
3157f602
XL
1548 let from = self.expr_path(path, ThinVec::new());
1549 let err_expr = self.expr_ident(e.span, err_ident, err_local.id);
54a0048b 1550
3157f602 1551 self.expr_call(e.span, from, hir_vec![err_expr])
54a0048b 1552 };
9e0c209e
SL
1553 let from_err_expr = {
1554 let path = self.std_path(e.span, &["ops", "Carrier", "from_error"]);
1555 let from_err = self.expr_path(path, ThinVec::new());
1556 self.expr_call(e.span, from_err, hir_vec![from_expr])
54a0048b 1557 };
9e0c209e 1558
a7813a04 1559 let ret_expr = self.expr(e.span,
9e0c209e
SL
1560 hir::Expr_::ExprRet(Some(from_err_expr)),
1561 ThinVec::new());
1562 let ret_stmt = self.stmt_expr(ret_expr);
1563 let block = self.signal_block_stmt(ret_stmt, e.span,
1564 hir::PushUnstableBlock, ThinVec::new());
1565
1566 let err_pat = self.pat_err(e.span, err_local);
1567 self.arm(hir_vec![err_pat], block)
54a0048b
SL
1568 };
1569
9e0c209e 1570 return self.expr_match(e.span, discr, hir_vec![err_arm, ok_arm],
3157f602 1571 hir::MatchSource::TryDesugar);
a7813a04 1572 }
54a0048b 1573
a7813a04
XL
1574 ExprKind::Mac(_) => panic!("Shouldn't exist here"),
1575 },
1576 span: e.span,
1577 attrs: e.attrs.clone(),
1578 })
1579 }
b039eaaf 1580
a7813a04
XL
1581 fn lower_stmt(&mut self, s: &Stmt) -> hir::Stmt {
1582 match s.node {
3157f602
XL
1583 StmtKind::Local(ref l) => Spanned {
1584 node: hir::StmtDecl(P(Spanned {
1585 node: hir::DeclLocal(self.lower_local(l)),
a7813a04 1586 span: s.span,
3157f602
XL
1587 }), s.id),
1588 span: s.span,
1589 },
1590 StmtKind::Item(ref it) => Spanned {
1591 node: hir::StmtDecl(P(Spanned {
1592 node: hir::DeclItem(self.lower_item_id(it)),
1593 span: s.span,
1594 }), s.id),
1595 span: s.span,
1596 },
1597 StmtKind::Expr(ref e) => {
a7813a04 1598 Spanned {
3157f602 1599 node: hir::StmtExpr(self.lower_expr(e), s.id),
a7813a04
XL
1600 span: s.span,
1601 }
92a42be0 1602 }
3157f602 1603 StmtKind::Semi(ref e) => {
a7813a04 1604 Spanned {
3157f602 1605 node: hir::StmtSemi(self.lower_expr(e), s.id),
a7813a04
XL
1606 span: s.span,
1607 }
92a42be0 1608 }
a7813a04 1609 StmtKind::Mac(..) => panic!("Shouldn't exist here"),
e9174d1e 1610 }
e9174d1e 1611 }
e9174d1e 1612
a7813a04
XL
1613 fn lower_capture_clause(&mut self, c: CaptureBy) -> hir::CaptureClause {
1614 match c {
1615 CaptureBy::Value => hir::CaptureByValue,
1616 CaptureBy::Ref => hir::CaptureByRef,
1617 }
e9174d1e 1618 }
e9174d1e 1619
a7813a04
XL
1620 fn lower_visibility(&mut self, v: &Visibility) -> hir::Visibility {
1621 match *v {
1622 Visibility::Public => hir::Public,
1623 Visibility::Crate(_) => hir::Visibility::Crate,
1624 Visibility::Restricted { ref path, id } =>
1625 hir::Visibility::Restricted { path: P(self.lower_path(path)), id: id },
1626 Visibility::Inherited => hir::Inherited,
1627 }
54a0048b 1628 }
54a0048b 1629
a7813a04
XL
1630 fn lower_defaultness(&mut self, d: Defaultness) -> hir::Defaultness {
1631 match d {
1632 Defaultness::Default => hir::Defaultness::Default,
1633 Defaultness::Final => hir::Defaultness::Final,
1634 }
e9174d1e 1635 }
e9174d1e 1636
a7813a04
XL
1637 fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode {
1638 match *b {
1639 BlockCheckMode::Default => hir::DefaultBlock,
1640 BlockCheckMode::Unsafe(u) => hir::UnsafeBlock(self.lower_unsafe_source(u)),
1641 }
e9174d1e 1642 }
e9174d1e 1643
a7813a04
XL
1644 fn lower_binding_mode(&mut self, b: &BindingMode) -> hir::BindingMode {
1645 match *b {
1646 BindingMode::ByRef(m) => hir::BindByRef(self.lower_mutability(m)),
1647 BindingMode::ByValue(m) => hir::BindByValue(self.lower_mutability(m)),
1648 }
e9174d1e 1649 }
e9174d1e 1650
a7813a04
XL
1651 fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
1652 match u {
1653 CompilerGenerated => hir::CompilerGenerated,
1654 UserProvided => hir::UserProvided,
1655 }
e9174d1e 1656 }
e9174d1e 1657
a7813a04
XL
1658 fn lower_impl_polarity(&mut self, i: ImplPolarity) -> hir::ImplPolarity {
1659 match i {
1660 ImplPolarity::Positive => hir::ImplPolarity::Positive,
1661 ImplPolarity::Negative => hir::ImplPolarity::Negative,
1662 }
e9174d1e 1663 }
e9174d1e 1664
a7813a04
XL
1665 fn lower_trait_bound_modifier(&mut self, f: TraitBoundModifier) -> hir::TraitBoundModifier {
1666 match f {
1667 TraitBoundModifier::None => hir::TraitBoundModifier::None,
1668 TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe,
1669 }
e9174d1e 1670 }
e9174d1e 1671
a7813a04 1672 // Helper methods for building HIR.
b039eaaf 1673
a7813a04
XL
1674 fn arm(&mut self, pats: hir::HirVec<P<hir::Pat>>, expr: P<hir::Expr>) -> hir::Arm {
1675 hir::Arm {
1676 attrs: hir_vec![],
1677 pats: pats,
1678 guard: None,
1679 body: expr,
1680 }
e9174d1e 1681 }
e9174d1e 1682
a7813a04
XL
1683 fn field(&mut self, name: Name, expr: P<hir::Expr>, span: Span) -> hir::Field {
1684 hir::Field {
1685 name: Spanned {
1686 node: name,
1687 span: span,
1688 },
54a0048b 1689 span: span,
a7813a04
XL
1690 expr: expr,
1691 }
54a0048b 1692 }
54a0048b 1693
3157f602 1694 fn expr_break(&mut self, span: Span, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
a7813a04
XL
1695 self.expr(span, hir::ExprBreak(None), attrs)
1696 }
e9174d1e 1697
3157f602 1698 fn expr_call(&mut self, span: Span, e: P<hir::Expr>, args: hir::HirVec<P<hir::Expr>>)
a7813a04 1699 -> P<hir::Expr> {
3157f602 1700 self.expr(span, hir::ExprCall(e, args), ThinVec::new())
a7813a04 1701 }
54a0048b 1702
3157f602 1703 fn expr_ident(&mut self, span: Span, id: Name, binding: NodeId) -> P<hir::Expr> {
a7813a04 1704 let expr_path = hir::ExprPath(None, self.path_ident(span, id));
3157f602 1705 let expr = self.expr(span, expr_path, ThinVec::new());
b039eaaf 1706
9e0c209e
SL
1707 let def = {
1708 let defs = self.resolver.definitions();
1709 Def::Local(defs.local_def_id(binding))
1710 };
a7813a04 1711 self.resolver.record_resolution(expr.id, def);
b039eaaf 1712
a7813a04
XL
1713 expr
1714 }
b039eaaf 1715
3157f602
XL
1716 fn expr_mut_addr_of(&mut self, span: Span, e: P<hir::Expr>) -> P<hir::Expr> {
1717 self.expr(span, hir::ExprAddrOf(hir::MutMutable, e), ThinVec::new())
a7813a04 1718 }
b039eaaf 1719
3157f602 1720 fn expr_path(&mut self, path: hir::Path, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
a7813a04
XL
1721 let def = self.resolver.resolve_generated_global_path(&path, true);
1722 let expr = self.expr(path.span, hir::ExprPath(None, path), attrs);
1723 self.resolver.record_resolution(expr.id, def);
1724 expr
1725 }
54a0048b 1726
a7813a04
XL
1727 fn expr_match(&mut self,
1728 span: Span,
1729 arg: P<hir::Expr>,
1730 arms: hir::HirVec<hir::Arm>,
3157f602 1731 source: hir::MatchSource)
a7813a04 1732 -> P<hir::Expr> {
3157f602 1733 self.expr(span, hir::ExprMatch(arg, arms, source), ThinVec::new())
a7813a04 1734 }
54a0048b 1735
3157f602 1736 fn expr_block(&mut self, b: P<hir::Block>, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
a7813a04
XL
1737 self.expr(b.span, hir::ExprBlock(b), attrs)
1738 }
b039eaaf 1739
3157f602
XL
1740 fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec<P<hir::Expr>>) -> P<hir::Expr> {
1741 self.expr(sp, hir::ExprTup(exprs), ThinVec::new())
a7813a04 1742 }
b039eaaf 1743
a7813a04
XL
1744 fn expr_struct(&mut self,
1745 sp: Span,
1746 path: hir::Path,
1747 fields: hir::HirVec<hir::Field>,
1748 e: Option<P<hir::Expr>>,
3157f602 1749 attrs: ThinVec<Attribute>) -> P<hir::Expr> {
a7813a04
XL
1750 let def = self.resolver.resolve_generated_global_path(&path, false);
1751 let expr = self.expr(sp, hir::ExprStruct(path, fields, e), attrs);
1752 self.resolver.record_resolution(expr.id, def);
1753 expr
1754 }
b039eaaf 1755
3157f602 1756 fn expr(&mut self, span: Span, node: hir::Expr_, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
a7813a04
XL
1757 P(hir::Expr {
1758 id: self.next_id(),
1759 node: node,
1760 span: span,
1761 attrs: attrs,
1762 })
1763 }
1764
3157f602 1765 fn stmt_let(&mut self, sp: Span, mutbl: bool, ident: Name, ex: P<hir::Expr>)
a7813a04
XL
1766 -> (hir::Stmt, NodeId) {
1767 let pat = if mutbl {
1768 self.pat_ident_binding_mode(sp, ident, hir::BindByValue(hir::MutMutable))
1769 } else {
1770 self.pat_ident(sp, ident)
1771 };
1772 let pat_id = pat.id;
1773 let local = P(hir::Local {
1774 pat: pat,
1775 ty: None,
1776 init: Some(ex),
1777 id: self.next_id(),
1778 span: sp,
3157f602 1779 attrs: ThinVec::new(),
a7813a04
XL
1780 });
1781 let decl = respan(sp, hir::DeclLocal(local));
1782 (respan(sp, hir::StmtDecl(P(decl), self.next_id())), pat_id)
1783 }
b039eaaf 1784
9e0c209e
SL
1785 // Turns `<expr>` into `<expr>;`, note that this produces a StmtSemi, not a
1786 // StmtExpr.
1787 fn stmt_expr(&self, expr: P<hir::Expr>) -> hir::Stmt {
1788 hir::Stmt {
1789 span: expr.span,
1790 node: hir::StmtSemi(expr, self.next_id()),
1791 }
1792 }
1793
a7813a04
XL
1794 fn block_expr(&mut self, expr: P<hir::Expr>) -> P<hir::Block> {
1795 self.block_all(expr.span, hir::HirVec::new(), Some(expr))
1796 }
b039eaaf 1797
a7813a04
XL
1798 fn block_all(&mut self, span: Span, stmts: hir::HirVec<hir::Stmt>, expr: Option<P<hir::Expr>>)
1799 -> P<hir::Block> {
1800 P(hir::Block {
1801 stmts: stmts,
1802 expr: expr,
1803 id: self.next_id(),
1804 rules: hir::DefaultBlock,
1805 span: span,
1806 })
1807 }
b039eaaf 1808
a7813a04 1809 fn pat_ok(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
9e0c209e 1810 let path = self.std_path(span, &["result", "Result", "Ok"]);
a7813a04
XL
1811 self.pat_enum(span, path, hir_vec![pat])
1812 }
b039eaaf 1813
a7813a04 1814 fn pat_err(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
9e0c209e 1815 let path = self.std_path(span, &["result", "Result", "Err"]);
a7813a04
XL
1816 self.pat_enum(span, path, hir_vec![pat])
1817 }
b039eaaf 1818
a7813a04 1819 fn pat_some(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
9e0c209e 1820 let path = self.std_path(span, &["option", "Option", "Some"]);
a7813a04
XL
1821 self.pat_enum(span, path, hir_vec![pat])
1822 }
b039eaaf 1823
a7813a04 1824 fn pat_none(&mut self, span: Span) -> P<hir::Pat> {
9e0c209e 1825 let path = self.std_path(span, &["option", "Option", "None"]);
a7813a04
XL
1826 self.pat_enum(span, path, hir_vec![])
1827 }
b039eaaf 1828
a7813a04
XL
1829 fn pat_enum(&mut self, span: Span, path: hir::Path, subpats: hir::HirVec<P<hir::Pat>>)
1830 -> P<hir::Pat> {
1831 let def = self.resolver.resolve_generated_global_path(&path, true);
1832 let pt = if subpats.is_empty() {
5bcae85e 1833 hir::PatKind::Path(None, path)
a7813a04 1834 } else {
3157f602 1835 hir::PatKind::TupleStruct(path, subpats, None)
a7813a04
XL
1836 };
1837 let pat = self.pat(span, pt);
1838 self.resolver.record_resolution(pat.id, def);
1839 pat
e9174d1e 1840 }
e9174d1e 1841
a7813a04
XL
1842 fn pat_ident(&mut self, span: Span, name: Name) -> P<hir::Pat> {
1843 self.pat_ident_binding_mode(span, name, hir::BindByValue(hir::MutImmutable))
e9174d1e 1844 }
e9174d1e 1845
a7813a04
XL
1846 fn pat_ident_binding_mode(&mut self, span: Span, name: Name, bm: hir::BindingMode)
1847 -> P<hir::Pat> {
3157f602 1848 let pat_ident = hir::PatKind::Binding(bm,
a7813a04
XL
1849 Spanned {
1850 span: span,
1851 node: name,
1852 },
1853 None);
b039eaaf 1854
a7813a04 1855 let pat = self.pat(span, pat_ident);
b039eaaf 1856
a7813a04 1857 let parent_def = self.parent_def;
9e0c209e
SL
1858 let def = {
1859 let defs = self.resolver.definitions();
5bcae85e 1860 let def_path_data = DefPathData::Binding(name.as_str());
a7813a04 1861 let def_index = defs.create_def_with_parent(parent_def, pat.id, def_path_data);
9e0c209e
SL
1862 Def::Local(DefId::local(def_index))
1863 };
a7813a04 1864 self.resolver.record_resolution(pat.id, def);
b039eaaf 1865
a7813a04
XL
1866 pat
1867 }
b039eaaf 1868
a7813a04
XL
1869 fn pat_wild(&mut self, span: Span) -> P<hir::Pat> {
1870 self.pat(span, hir::PatKind::Wild)
1871 }
b039eaaf 1872
a7813a04
XL
1873 fn pat(&mut self, span: Span, pat: hir::PatKind) -> P<hir::Pat> {
1874 P(hir::Pat {
1875 id: self.next_id(),
1876 node: pat,
1877 span: span,
1878 })
b039eaaf
SL
1879 }
1880
a7813a04
XL
1881 fn path_ident(&mut self, span: Span, id: Name) -> hir::Path {
1882 self.path(span, vec![id])
b039eaaf
SL
1883 }
1884
a7813a04
XL
1885 fn path(&mut self, span: Span, strs: Vec<Name>) -> hir::Path {
1886 self.path_all(span, false, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new())
b039eaaf
SL
1887 }
1888
a7813a04
XL
1889 fn path_global(&mut self, span: Span, strs: Vec<Name>) -> hir::Path {
1890 self.path_all(span, true, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new())
b039eaaf
SL
1891 }
1892
a7813a04
XL
1893 fn path_all(&mut self,
1894 sp: Span,
1895 global: bool,
1896 mut names: Vec<Name>,
1897 lifetimes: hir::HirVec<hir::Lifetime>,
1898 types: hir::HirVec<P<hir::Ty>>,
1899 bindings: hir::HirVec<hir::TypeBinding>)
1900 -> hir::Path {
1901 let last_identifier = names.pop().unwrap();
1902 let mut segments: Vec<hir::PathSegment> = names.into_iter().map(|name| {
1903 hir::PathSegment {
1904 name: name,
1905 parameters: hir::PathParameters::none(),
1906 }
1907 }).collect();
b039eaaf 1908
a7813a04
XL
1909 segments.push(hir::PathSegment {
1910 name: last_identifier,
1911 parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData {
1912 lifetimes: lifetimes,
1913 types: types,
1914 bindings: bindings,
1915 }),
1916 });
1917 hir::Path {
1918 span: sp,
1919 global: global,
1920 segments: segments.into(),
b039eaaf
SL
1921 }
1922 }
1923
9e0c209e 1924 fn std_path_components(&mut self, components: &[&str]) -> Vec<Name> {
a7813a04
XL
1925 let mut v = Vec::new();
1926 if let Some(s) = self.crate_root {
1927 v.push(token::intern(s));
b039eaaf 1928 }
a7813a04
XL
1929 v.extend(components.iter().map(|s| token::intern(s)));
1930 return v;
1931 }
1932
1933 // Given suffix ["b","c","d"], returns path `::std::b::c::d` when
1934 // `fld.cx.use_std`, and `::core::b::c::d` otherwise.
9e0c209e
SL
1935 fn std_path(&mut self, span: Span, components: &[&str]) -> hir::Path {
1936 let idents = self.std_path_components(components);
a7813a04
XL
1937 self.path_global(span, idents)
1938 }
1939
1940 fn signal_block_expr(&mut self,
1941 stmts: hir::HirVec<hir::Stmt>,
1942 expr: P<hir::Expr>,
1943 span: Span,
1944 rule: hir::BlockCheckMode,
3157f602 1945 attrs: ThinVec<Attribute>)
a7813a04
XL
1946 -> P<hir::Expr> {
1947 let id = self.next_id();
1948 let block = P(hir::Block {
1949 rules: rule,
1950 span: span,
1951 id: id,
1952 stmts: stmts,
1953 expr: Some(expr),
1954 });
1955 self.expr_block(block, attrs)
e9174d1e 1956 }
9e0c209e
SL
1957
1958 fn signal_block_stmt(&mut self,
1959 stmt: hir::Stmt,
1960 span: Span,
1961 rule: hir::BlockCheckMode,
1962 attrs: ThinVec<Attribute>)
1963 -> P<hir::Expr> {
1964 let id = self.next_id();
1965 let block = P(hir::Block {
1966 rules: rule,
1967 span: span,
1968 id: id,
1969 stmts: hir_vec![stmt],
1970 expr: None,
1971 });
1972 self.expr_block(block, attrs)
1973 }
e9174d1e 1974}