]> git.lizzy.rs Git - rust.git/blob - src/librustc/hir/lowering.rs
Rollup merge of #44562 - eddyb:ugh-rustdoc, r=nikomatsakis
[rust.git] / src / librustc / hir / 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 //! 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 //!
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.
42
43 use dep_graph::DepGraph;
44 use hir;
45 use hir::map::{Definitions, DefKey};
46 use hir::def_id::{DefIndex, DefId, CRATE_DEF_INDEX};
47 use hir::def::{Def, PathResolution};
48 use lint::builtin::PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES;
49 use middle::cstore::CrateStore;
50 use rustc_data_structures::indexed_vec::IndexVec;
51 use session::Session;
52 use util::common::FN_OUTPUT_NAME;
53 use util::nodemap::{DefIdMap, FxHashMap, NodeMap};
54
55 use std::collections::BTreeMap;
56 use std::fmt::Debug;
57 use std::iter;
58 use std::mem;
59 use syntax::attr;
60 use syntax::ast::*;
61 use syntax::errors;
62 use syntax::ext::hygiene::{Mark, SyntaxContext};
63 use syntax::ptr::P;
64 use syntax::codemap::{self, respan, Spanned, CompilerDesugaringKind};
65 use syntax::std_inject;
66 use syntax::symbol::{Symbol, keywords};
67 use syntax::util::small_vector::SmallVector;
68 use syntax::visit::{self, Visitor};
69 use syntax_pos::Span;
70
71 const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF;
72
73 pub struct LoweringContext<'a> {
74     crate_root: Option<&'static str>,
75
76     // Use to assign ids to hir nodes that do not directly correspond to an ast node
77     sess: &'a Session,
78
79     cstore: &'a CrateStore,
80
81     // As we walk the AST we must keep track of the current 'parent' def id (in
82     // the form of a DefIndex) so that if we create a new node which introduces
83     // a definition, then we can properly create the def id.
84     parent_def: Option<DefIndex>,
85     resolver: &'a mut Resolver,
86     name_map: FxHashMap<Ident, Name>,
87
88     /// The items being lowered are collected here.
89     items: BTreeMap<NodeId, hir::Item>,
90
91     trait_items: BTreeMap<hir::TraitItemId, hir::TraitItem>,
92     impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>,
93     bodies: BTreeMap<hir::BodyId, hir::Body>,
94     exported_macros: Vec<hir::MacroDef>,
95
96     trait_impls: BTreeMap<DefId, Vec<NodeId>>,
97     trait_default_impl: BTreeMap<DefId, NodeId>,
98
99     is_generator: bool,
100
101     catch_scopes: Vec<NodeId>,
102     loop_scopes: Vec<NodeId>,
103     is_in_loop_condition: bool,
104
105     type_def_lifetime_params: DefIdMap<usize>,
106
107     current_hir_id_owner: Vec<(DefIndex, u32)>,
108     item_local_id_counters: NodeMap<u32>,
109     node_id_to_hir_id: IndexVec<NodeId, hir::HirId>,
110 }
111
112 pub trait Resolver {
113     /// Resolve a hir path generated by the lowerer when expanding `for`, `if let`, etc.
114     fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool);
115
116     /// Obtain the resolution for a node id
117     fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution>;
118
119     /// We must keep the set of definitions up to date as we add nodes that weren't in the AST.
120     /// This should only return `None` during testing.
121     fn definitions(&mut self) -> &mut Definitions;
122 }
123
124 pub fn lower_crate(sess: &Session,
125                    cstore: &CrateStore,
126                    dep_graph: &DepGraph,
127                    krate: &Crate,
128                    resolver: &mut Resolver)
129                    -> hir::Crate {
130     // We're constructing the HIR here; we don't care what we will
131     // read, since we haven't even constructed the *input* to
132     // incr. comp. yet.
133     let _ignore = dep_graph.in_ignore();
134
135     LoweringContext {
136         crate_root: std_inject::injected_crate_name(krate),
137         sess,
138         cstore,
139         parent_def: None,
140         resolver,
141         name_map: FxHashMap(),
142         items: BTreeMap::new(),
143         trait_items: BTreeMap::new(),
144         impl_items: BTreeMap::new(),
145         bodies: BTreeMap::new(),
146         trait_impls: BTreeMap::new(),
147         trait_default_impl: BTreeMap::new(),
148         exported_macros: Vec::new(),
149         catch_scopes: Vec::new(),
150         loop_scopes: Vec::new(),
151         is_in_loop_condition: false,
152         type_def_lifetime_params: DefIdMap(),
153         current_hir_id_owner: vec![(CRATE_DEF_INDEX, 0)],
154         item_local_id_counters: NodeMap(),
155         node_id_to_hir_id: IndexVec::new(),
156         is_generator: false,
157     }.lower_crate(krate)
158 }
159
160 #[derive(Copy, Clone, PartialEq, Eq)]
161 enum ParamMode {
162     /// Any path in a type context.
163     Explicit,
164     /// The `module::Type` in `module::Type::method` in an expression.
165     Optional
166 }
167
168 struct LoweredNodeId {
169     node_id: NodeId,
170     hir_id: hir::HirId,
171 }
172
173 enum ParenthesizedGenericArgs {
174     Ok,
175     Warn,
176     Err,
177 }
178
179 impl<'a> LoweringContext<'a> {
180     fn lower_crate(mut self, c: &Crate) -> hir::Crate {
181         /// Full-crate AST visitor that inserts into a fresh
182         /// `LoweringContext` any information that may be
183         /// needed from arbitrary locations in the crate.
184         /// E.g. The number of lifetime generic parameters
185         /// declared for every type and trait definition.
186         struct MiscCollector<'lcx, 'interner: 'lcx> {
187             lctx: &'lcx mut LoweringContext<'interner>,
188         }
189
190         impl<'lcx, 'interner> Visitor<'lcx> for MiscCollector<'lcx, 'interner> {
191             fn visit_item(&mut self, item: &'lcx Item) {
192                 self.lctx.allocate_hir_id_counter(item.id, item);
193
194                 match item.node {
195                     ItemKind::Struct(_, ref generics) |
196                     ItemKind::Union(_, ref generics) |
197                     ItemKind::Enum(_, ref generics) |
198                     ItemKind::Ty(_, ref generics) |
199                     ItemKind::Trait(_, ref generics, ..) => {
200                         let def_id = self.lctx.resolver.definitions().local_def_id(item.id);
201                         let count = generics.lifetimes.len();
202                         self.lctx.type_def_lifetime_params.insert(def_id, count);
203                     }
204                     _ => {}
205                 }
206                 visit::walk_item(self, item);
207             }
208
209             fn visit_trait_item(&mut self, item: &'lcx TraitItem) {
210                 self.lctx.allocate_hir_id_counter(item.id, item);
211                 visit::walk_trait_item(self, item);
212             }
213
214             fn visit_impl_item(&mut self, item: &'lcx ImplItem) {
215                 self.lctx.allocate_hir_id_counter(item.id, item);
216                 visit::walk_impl_item(self, item);
217             }
218         }
219
220         struct ItemLowerer<'lcx, 'interner: 'lcx> {
221             lctx: &'lcx mut LoweringContext<'interner>,
222         }
223
224         impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> {
225             fn visit_item(&mut self, item: &'lcx Item) {
226                 let mut item_lowered = true;
227                 self.lctx.with_hir_id_owner(item.id, |lctx| {
228                     if let Some(hir_item) = lctx.lower_item(item) {
229                         lctx.items.insert(item.id, hir_item);
230                     } else {
231                         item_lowered = false;
232                     }
233                 });
234
235                 if item_lowered {
236                     visit::walk_item(self, item);
237                 }
238             }
239
240             fn visit_trait_item(&mut self, item: &'lcx TraitItem) {
241                 self.lctx.with_hir_id_owner(item.id, |lctx| {
242                     let id = hir::TraitItemId { node_id: item.id };
243                     let hir_item = lctx.lower_trait_item(item);
244                     lctx.trait_items.insert(id, hir_item);
245                 });
246
247                 visit::walk_trait_item(self, item);
248             }
249
250             fn visit_impl_item(&mut self, item: &'lcx ImplItem) {
251                 self.lctx.with_hir_id_owner(item.id, |lctx| {
252                     let id = hir::ImplItemId { node_id: item.id };
253                     let hir_item = lctx.lower_impl_item(item);
254                     lctx.impl_items.insert(id, hir_item);
255                 });
256                 visit::walk_impl_item(self, item);
257             }
258         }
259
260         self.lower_node_id(CRATE_NODE_ID);
261         debug_assert!(self.node_id_to_hir_id[CRATE_NODE_ID] == hir::CRATE_HIR_ID);
262
263         visit::walk_crate(&mut MiscCollector { lctx: &mut self }, c);
264         visit::walk_crate(&mut ItemLowerer { lctx: &mut self }, c);
265
266         let module = self.lower_mod(&c.module);
267         let attrs = self.lower_attrs(&c.attrs);
268         let body_ids = body_ids(&self.bodies);
269
270         self.resolver
271             .definitions()
272             .init_node_id_to_hir_id_mapping(self.node_id_to_hir_id);
273
274         hir::Crate {
275             module,
276             attrs,
277             span: c.span,
278             exported_macros: hir::HirVec::from(self.exported_macros),
279             items: self.items,
280             trait_items: self.trait_items,
281             impl_items: self.impl_items,
282             bodies: self.bodies,
283             body_ids,
284             trait_impls: self.trait_impls,
285             trait_default_impl: self.trait_default_impl,
286         }
287     }
288
289     fn allocate_hir_id_counter<T: Debug>(&mut self,
290                                          owner: NodeId,
291                                          debug: &T) {
292         if self.item_local_id_counters.insert(owner, 0).is_some() {
293             bug!("Tried to allocate item_local_id_counter for {:?} twice", debug);
294         }
295         // Always allocate the first HirId for the owner itself
296         self.lower_node_id_with_owner(owner, owner);
297     }
298
299     fn lower_node_id_generic<F>(&mut self,
300                                 ast_node_id: NodeId,
301                                 alloc_hir_id: F)
302                                 -> LoweredNodeId
303         where F: FnOnce(&mut Self) -> hir::HirId
304     {
305         if ast_node_id == DUMMY_NODE_ID {
306             return LoweredNodeId {
307                 node_id: DUMMY_NODE_ID,
308                 hir_id: hir::DUMMY_HIR_ID,
309             }
310         }
311
312         let min_size = ast_node_id.as_usize() + 1;
313
314         if min_size > self.node_id_to_hir_id.len() {
315             self.node_id_to_hir_id.resize(min_size, hir::DUMMY_HIR_ID);
316         }
317
318         let existing_hir_id = self.node_id_to_hir_id[ast_node_id];
319
320         if existing_hir_id == hir::DUMMY_HIR_ID {
321             // Generate a new HirId
322             let hir_id = alloc_hir_id(self);
323             self.node_id_to_hir_id[ast_node_id] = hir_id;
324             LoweredNodeId {
325                 node_id: ast_node_id,
326                 hir_id,
327             }
328         } else {
329             LoweredNodeId {
330                 node_id: ast_node_id,
331                 hir_id: existing_hir_id,
332             }
333         }
334     }
335
336     fn with_hir_id_owner<F>(&mut self, owner: NodeId, f: F)
337         where F: FnOnce(&mut Self)
338     {
339         let counter = self.item_local_id_counters
340                           .insert(owner, HIR_ID_COUNTER_LOCKED)
341                           .unwrap();
342         let def_index = self.resolver.definitions().opt_def_index(owner).unwrap();
343         self.current_hir_id_owner.push((def_index, counter));
344         f(self);
345         let (new_def_index, new_counter) = self.current_hir_id_owner.pop().unwrap();
346
347         debug_assert!(def_index == new_def_index);
348         debug_assert!(new_counter >= counter);
349
350         let prev = self.item_local_id_counters.insert(owner, new_counter).unwrap();
351         debug_assert!(prev == HIR_ID_COUNTER_LOCKED);
352     }
353
354     /// This method allocates a new HirId for the given NodeId and stores it in
355     /// the LoweringContext's NodeId => HirId map.
356     /// Take care not to call this method if the resulting HirId is then not
357     /// actually used in the HIR, as that would trigger an assertion in the
358     /// HirIdValidator later on, which makes sure that all NodeIds got mapped
359     /// properly. Calling the method twice with the same NodeId is fine though.
360     fn lower_node_id(&mut self, ast_node_id: NodeId) -> LoweredNodeId {
361         self.lower_node_id_generic(ast_node_id, |this| {
362             let &mut (def_index, ref mut local_id_counter) = this.current_hir_id_owner
363                                                                  .last_mut()
364                                                                  .unwrap();
365             let local_id = *local_id_counter;
366             *local_id_counter += 1;
367             hir::HirId {
368                 owner: def_index,
369                 local_id: hir::ItemLocalId(local_id),
370             }
371         })
372     }
373
374     fn lower_node_id_with_owner(&mut self,
375                                 ast_node_id: NodeId,
376                                 owner: NodeId)
377                                 -> LoweredNodeId {
378         self.lower_node_id_generic(ast_node_id, |this| {
379             let local_id_counter = this.item_local_id_counters
380                                        .get_mut(&owner)
381                                        .unwrap();
382             let local_id = *local_id_counter;
383
384             // We want to be sure not to modify the counter in the map while it
385             // is also on the stack. Otherwise we'll get lost updates when writing
386             // back from the stack to the map.
387             debug_assert!(local_id != HIR_ID_COUNTER_LOCKED);
388
389             *local_id_counter += 1;
390             let def_index = this.resolver.definitions().opt_def_index(owner).unwrap();
391
392             hir::HirId {
393                 owner: def_index,
394                 local_id: hir::ItemLocalId(local_id),
395             }
396         })
397     }
398
399     fn record_body(&mut self, value: hir::Expr, decl: Option<&FnDecl>)
400                    -> hir::BodyId {
401         let body = hir::Body {
402             arguments: decl.map_or(hir_vec![], |decl| {
403                 decl.inputs.iter().map(|x| self.lower_arg(x)).collect()
404             }),
405             is_generator: self.is_generator,
406             value,
407         };
408         let id = body.id();
409         self.bodies.insert(id, body);
410         id
411     }
412
413     fn next_id(&mut self) -> LoweredNodeId {
414         self.lower_node_id(self.sess.next_node_id())
415     }
416
417     fn expect_full_def(&mut self, id: NodeId) -> Def {
418         self.resolver.get_resolution(id).map_or(Def::Err, |pr| {
419             if pr.unresolved_segments() != 0 {
420                 bug!("path not fully resolved: {:?}", pr);
421             }
422             pr.base_def()
423         })
424     }
425
426     fn diagnostic(&self) -> &errors::Handler {
427         self.sess.diagnostic()
428     }
429
430     fn str_to_ident(&self, s: &'static str) -> Name {
431         Symbol::gensym(s)
432     }
433
434     fn allow_internal_unstable(&self, reason: CompilerDesugaringKind, span: Span) -> Span
435     {
436         let mark = Mark::fresh(Mark::root());
437         mark.set_expn_info(codemap::ExpnInfo {
438             call_site: span,
439             callee: codemap::NameAndSpan {
440                 format: codemap::CompilerDesugaring(reason),
441                 span: Some(span),
442                 allow_internal_unstable: true,
443                 allow_internal_unsafe: false,
444             },
445         });
446         span.with_ctxt(SyntaxContext::empty().apply_mark(mark))
447     }
448
449     fn with_catch_scope<T, F>(&mut self, catch_id: NodeId, f: F) -> T
450         where F: FnOnce(&mut LoweringContext) -> T
451     {
452         let len = self.catch_scopes.len();
453         self.catch_scopes.push(catch_id);
454
455         let result = f(self);
456         assert_eq!(len + 1, self.catch_scopes.len(),
457             "catch scopes should be added and removed in stack order");
458
459         self.catch_scopes.pop().unwrap();
460
461         result
462     }
463
464     fn lower_body<F>(&mut self, decl: Option<&FnDecl>, f: F) -> hir::BodyId
465         where F: FnOnce(&mut LoweringContext) -> hir::Expr
466     {
467         let prev = mem::replace(&mut self.is_generator, false);
468         let result = f(self);
469         let r = self.record_body(result, decl);
470         self.is_generator = prev;
471         return r
472     }
473
474     fn with_loop_scope<T, F>(&mut self, loop_id: NodeId, f: F) -> T
475         where F: FnOnce(&mut LoweringContext) -> T
476     {
477         // We're no longer in the base loop's condition; we're in another loop.
478         let was_in_loop_condition = self.is_in_loop_condition;
479         self.is_in_loop_condition = false;
480
481         let len = self.loop_scopes.len();
482         self.loop_scopes.push(loop_id);
483
484         let result = f(self);
485         assert_eq!(len + 1, self.loop_scopes.len(),
486             "Loop scopes should be added and removed in stack order");
487
488         self.loop_scopes.pop().unwrap();
489
490         self.is_in_loop_condition = was_in_loop_condition;
491
492         result
493     }
494
495     fn with_loop_condition_scope<T, F>(&mut self, f: F) -> T
496         where F: FnOnce(&mut LoweringContext) -> T
497     {
498         let was_in_loop_condition = self.is_in_loop_condition;
499         self.is_in_loop_condition = true;
500
501         let result = f(self);
502
503         self.is_in_loop_condition = was_in_loop_condition;
504
505         result
506     }
507
508     fn with_new_scopes<T, F>(&mut self, f: F) -> T
509         where F: FnOnce(&mut LoweringContext) -> T
510     {
511         let was_in_loop_condition = self.is_in_loop_condition;
512         self.is_in_loop_condition = false;
513
514         let catch_scopes = mem::replace(&mut self.catch_scopes, Vec::new());
515         let loop_scopes = mem::replace(&mut self.loop_scopes, Vec::new());
516         let result = f(self);
517         self.catch_scopes = catch_scopes;
518         self.loop_scopes = loop_scopes;
519
520         self.is_in_loop_condition = was_in_loop_condition;
521
522         result
523     }
524
525     fn with_parent_def<T, F>(&mut self, parent_id: NodeId, f: F) -> T
526         where F: FnOnce(&mut LoweringContext) -> T
527     {
528         let old_def = self.parent_def;
529         self.parent_def = {
530             let defs = self.resolver.definitions();
531             Some(defs.opt_def_index(parent_id).unwrap())
532         };
533
534         let result = f(self);
535
536         self.parent_def = old_def;
537         result
538     }
539
540     fn def_key(&mut self, id: DefId) -> DefKey {
541         if id.is_local() {
542             self.resolver.definitions().def_key(id.index)
543         } else {
544             self.cstore.def_key(id)
545         }
546     }
547
548     fn lower_ident(&mut self, ident: Ident) -> Name {
549         let ident = ident.modern();
550         if ident.ctxt == SyntaxContext::empty() {
551             return ident.name;
552         }
553         *self.name_map.entry(ident).or_insert_with(|| Symbol::from_ident(ident))
554     }
555
556     fn lower_opt_sp_ident(&mut self, o_id: Option<Spanned<Ident>>) -> Option<Spanned<Name>> {
557         o_id.map(|sp_ident| respan(sp_ident.span, sp_ident.node.name))
558     }
559
560     fn lower_loop_destination(&mut self, destination: Option<(NodeId, Spanned<Ident>)>)
561         -> hir::Destination
562     {
563         match destination {
564             Some((id, label_ident)) => {
565                 let target = if let Def::Label(loop_id) = self.expect_full_def(id) {
566                     hir::LoopIdResult::Ok(self.lower_node_id(loop_id).node_id)
567                 } else {
568                     hir::LoopIdResult::Err(hir::LoopIdError::UnresolvedLabel)
569                 };
570                 hir::Destination {
571                     ident: Some(label_ident),
572                     target_id: hir::ScopeTarget::Loop(target),
573                 }
574             },
575             None => {
576                 let loop_id = self.loop_scopes
577                                   .last()
578                                   .map(|innermost_loop_id| *innermost_loop_id);
579
580                 hir::Destination {
581                     ident: None,
582                     target_id: hir::ScopeTarget::Loop(
583                         loop_id.map(|id| Ok(self.lower_node_id(id).node_id))
584                                .unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
585                                .into())
586                 }
587             }
588         }
589     }
590
591     fn lower_attrs(&mut self, attrs: &Vec<Attribute>) -> hir::HirVec<Attribute> {
592         attrs.clone().into()
593     }
594
595     fn lower_arm(&mut self, arm: &Arm) -> hir::Arm {
596         hir::Arm {
597             attrs: self.lower_attrs(&arm.attrs),
598             pats: arm.pats.iter().map(|x| self.lower_pat(x)).collect(),
599             guard: arm.guard.as_ref().map(|ref x| P(self.lower_expr(x))),
600             body: P(self.lower_expr(&arm.body)),
601         }
602     }
603
604     fn lower_ty_binding(&mut self, b: &TypeBinding) -> hir::TypeBinding {
605         hir::TypeBinding {
606             id: self.lower_node_id(b.id).node_id,
607             name: self.lower_ident(b.ident),
608             ty: self.lower_ty(&b.ty),
609             span: b.span,
610         }
611     }
612
613     fn lower_ty(&mut self, t: &Ty) -> P<hir::Ty> {
614         let kind = match t.node {
615             TyKind::Infer => hir::TyInfer,
616             TyKind::Err => hir::TyErr,
617             TyKind::Slice(ref ty) => hir::TySlice(self.lower_ty(ty)),
618             TyKind::Ptr(ref mt) => hir::TyPtr(self.lower_mt(mt)),
619             TyKind::Rptr(ref region, ref mt) => {
620                 let span = t.span.with_hi(t.span.lo());
621                 let lifetime = match *region {
622                     Some(ref lt) => self.lower_lifetime(lt),
623                     None => self.elided_lifetime(span)
624                 };
625                 hir::TyRptr(lifetime, self.lower_mt(mt))
626             }
627             TyKind::BareFn(ref f) => {
628                 hir::TyBareFn(P(hir::BareFnTy {
629                     lifetimes: self.lower_lifetime_defs(&f.lifetimes),
630                     unsafety: self.lower_unsafety(f.unsafety),
631                     abi: f.abi,
632                     decl: self.lower_fn_decl(&f.decl),
633                 }))
634             }
635             TyKind::Never => hir::TyNever,
636             TyKind::Tup(ref tys) => {
637                 hir::TyTup(tys.iter().map(|ty| self.lower_ty(ty)).collect())
638             }
639             TyKind::Paren(ref ty) => {
640                 return self.lower_ty(ty);
641             }
642             TyKind::Path(ref qself, ref path) => {
643                 let id = self.lower_node_id(t.id).node_id;
644                 let qpath = self.lower_qpath(t.id, qself, path, ParamMode::Explicit);
645                 return self.ty_path(id, t.span, qpath);
646             }
647             TyKind::ImplicitSelf => {
648                 hir::TyPath(hir::QPath::Resolved(None, P(hir::Path {
649                     def: self.expect_full_def(t.id),
650                     segments: hir_vec![hir::PathSegment {
651                         name: keywords::SelfType.name(),
652                         parameters: hir::PathParameters::none()
653                     }],
654                     span: t.span,
655                 })))
656             }
657             TyKind::Array(ref ty, ref length) => {
658                 let length = self.lower_body(None, |this| this.lower_expr(length));
659                 hir::TyArray(self.lower_ty(ty), length)
660             }
661             TyKind::Typeof(ref expr) => {
662                 let expr = self.lower_body(None, |this| this.lower_expr(expr));
663                 hir::TyTypeof(expr)
664             }
665             TyKind::TraitObject(ref bounds) => {
666                 let mut lifetime_bound = None;
667                 let bounds = bounds.iter().filter_map(|bound| {
668                     match *bound {
669                         TraitTyParamBound(ref ty, TraitBoundModifier::None) => {
670                             Some(self.lower_poly_trait_ref(ty))
671                         }
672                         TraitTyParamBound(_, TraitBoundModifier::Maybe) => None,
673                         RegionTyParamBound(ref lifetime) => {
674                             if lifetime_bound.is_none() {
675                                 lifetime_bound = Some(self.lower_lifetime(lifetime));
676                             }
677                             None
678                         }
679                     }
680                 }).collect();
681                 let lifetime_bound = lifetime_bound.unwrap_or_else(|| {
682                     self.elided_lifetime(t.span)
683                 });
684                 hir::TyTraitObject(bounds, lifetime_bound)
685             }
686             TyKind::ImplTrait(ref bounds) => {
687                 hir::TyImplTrait(self.lower_bounds(bounds))
688             }
689             TyKind::Mac(_) => panic!("TyMac should have been expanded by now."),
690         };
691
692         P(hir::Ty {
693             id: self.lower_node_id(t.id).node_id,
694             node: kind,
695             span: t.span,
696         })
697     }
698
699     fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod {
700         hir::ForeignMod {
701             abi: fm.abi,
702             items: fm.items.iter().map(|x| self.lower_foreign_item(x)).collect(),
703         }
704     }
705
706     fn lower_global_asm(&mut self, ga: &GlobalAsm) -> P<hir::GlobalAsm> {
707         P(hir::GlobalAsm {
708             asm: ga.asm,
709             ctxt: ga.ctxt,
710         })
711     }
712
713     fn lower_variant(&mut self, v: &Variant) -> hir::Variant {
714         Spanned {
715             node: hir::Variant_ {
716                 name: v.node.name.name,
717                 attrs: self.lower_attrs(&v.node.attrs),
718                 data: self.lower_variant_data(&v.node.data),
719                 disr_expr: v.node.disr_expr.as_ref().map(|e| {
720                     self.lower_body(None, |this| this.lower_expr(e))
721                 }),
722             },
723             span: v.span,
724         }
725     }
726
727     fn lower_qpath(&mut self,
728                    id: NodeId,
729                    qself: &Option<QSelf>,
730                    p: &Path,
731                    param_mode: ParamMode)
732                    -> hir::QPath {
733         let qself_position = qself.as_ref().map(|q| q.position);
734         let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty));
735
736         let resolution = self.resolver.get_resolution(id)
737                                       .unwrap_or(PathResolution::new(Def::Err));
738
739         let proj_start = p.segments.len() - resolution.unresolved_segments();
740         let path = P(hir::Path {
741             def: resolution.base_def(),
742             segments: p.segments[..proj_start].iter().enumerate().map(|(i, segment)| {
743                 let param_mode = match (qself_position, param_mode) {
744                     (Some(j), ParamMode::Optional) if i < j => {
745                         // This segment is part of the trait path in a
746                         // qualified path - one of `a`, `b` or `Trait`
747                         // in `<X as a::b::Trait>::T::U::method`.
748                         ParamMode::Explicit
749                     }
750                     _ => param_mode
751                 };
752
753                 // Figure out if this is a type/trait segment,
754                 // which may need lifetime elision performed.
755                 let parent_def_id = |this: &mut Self, def_id: DefId| {
756                     DefId {
757                         krate: def_id.krate,
758                         index: this.def_key(def_id).parent.expect("missing parent")
759                     }
760                 };
761                 let type_def_id = match resolution.base_def() {
762                     Def::AssociatedTy(def_id) if i + 2 == proj_start => {
763                         Some(parent_def_id(self, def_id))
764                     }
765                     Def::Variant(def_id) if i + 1 == proj_start => {
766                         Some(parent_def_id(self, def_id))
767                     }
768                     Def::Struct(def_id) |
769                     Def::Union(def_id) |
770                     Def::Enum(def_id) |
771                     Def::TyAlias(def_id) |
772                     Def::Trait(def_id) if i + 1 == proj_start => Some(def_id),
773                     _ => None
774                 };
775                 let parenthesized_generic_args = match resolution.base_def() {
776                     // `a::b::Trait(Args)`
777                     Def::Trait(..) if i + 1 == proj_start => ParenthesizedGenericArgs::Ok,
778                     // `a::b::Trait(Args)::TraitItem`
779                     Def::Method(..) |
780                     Def::AssociatedConst(..) |
781                     Def::AssociatedTy(..) if i + 2 == proj_start => ParenthesizedGenericArgs::Ok,
782                     // Avoid duplicated errors
783                     Def::Err => ParenthesizedGenericArgs::Ok,
784                     // An error
785                     Def::Struct(..) | Def::Enum(..) | Def::Union(..) | Def::TyAlias(..) |
786                     Def::Variant(..) if i + 1 == proj_start => ParenthesizedGenericArgs::Err,
787                     // A warning for now, for compatibility reasons
788                     _ => ParenthesizedGenericArgs::Warn,
789                 };
790
791                 let num_lifetimes = type_def_id.map_or(0, |def_id| {
792                     if let Some(&n) = self.type_def_lifetime_params.get(&def_id) {
793                         return n;
794                     }
795                     assert!(!def_id.is_local());
796                     let n = self.cstore.item_generics_cloned_untracked(def_id).regions.len();
797                     self.type_def_lifetime_params.insert(def_id, n);
798                     n
799                 });
800                 self.lower_path_segment(p.span, segment, param_mode, num_lifetimes,
801                                         parenthesized_generic_args)
802             }).collect(),
803             span: p.span,
804         });
805
806         // Simple case, either no projections, or only fully-qualified.
807         // E.g. `std::mem::size_of` or `<I as Iterator>::Item`.
808         if resolution.unresolved_segments() == 0 {
809             return hir::QPath::Resolved(qself, path);
810         }
811
812         // Create the innermost type that we're projecting from.
813         let mut ty = if path.segments.is_empty() {
814             // If the base path is empty that means there exists a
815             // syntactical `Self`, e.g. `&i32` in `<&i32>::clone`.
816             qself.expect("missing QSelf for <T>::...")
817         } else {
818             // Otherwise, the base path is an implicit `Self` type path,
819             // e.g. `Vec` in `Vec::new` or `<I as Iterator>::Item` in
820             // `<I as Iterator>::Item::default`.
821             let new_id = self.next_id().node_id;
822             self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path))
823         };
824
825         // Anything after the base path are associated "extensions",
826         // out of which all but the last one are associated types,
827         // e.g. for `std::vec::Vec::<T>::IntoIter::Item::clone`:
828         // * base path is `std::vec::Vec<T>`
829         // * "extensions" are `IntoIter`, `Item` and `clone`
830         // * type nodes are:
831         //   1. `std::vec::Vec<T>` (created above)
832         //   2. `<std::vec::Vec<T>>::IntoIter`
833         //   3. `<<std::vec::Vec<T>>::IntoIter>::Item`
834         // * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
835         for (i, segment) in p.segments.iter().enumerate().skip(proj_start) {
836             let segment = P(self.lower_path_segment(p.span, segment, param_mode, 0,
837                                                     ParenthesizedGenericArgs::Warn));
838             let qpath = hir::QPath::TypeRelative(ty, segment);
839
840             // It's finished, return the extension of the right node type.
841             if i == p.segments.len() - 1 {
842                 return qpath;
843             }
844
845             // Wrap the associated extension in another type node.
846             let new_id = self.next_id().node_id;
847             ty = self.ty_path(new_id, p.span, qpath);
848         }
849
850         // Should've returned in the for loop above.
851         span_bug!(p.span, "lower_qpath: no final extension segment in {}..{}",
852                   proj_start, p.segments.len())
853     }
854
855     fn lower_path_extra(&mut self,
856                         id: NodeId,
857                         p: &Path,
858                         name: Option<Name>,
859                         param_mode: ParamMode,
860                         defaults_to_global: bool)
861                         -> hir::Path {
862         let mut segments = p.segments.iter();
863         if defaults_to_global && p.is_global() {
864             segments.next();
865         }
866
867         hir::Path {
868             def: self.expect_full_def(id),
869             segments: segments.map(|segment| {
870                 self.lower_path_segment(p.span, segment, param_mode, 0,
871                                         ParenthesizedGenericArgs::Err)
872             }).chain(name.map(|name| {
873                 hir::PathSegment {
874                     name,
875                     parameters: hir::PathParameters::none()
876                 }
877             })).collect(),
878             span: p.span,
879         }
880     }
881
882     fn lower_path(&mut self,
883                   id: NodeId,
884                   p: &Path,
885                   param_mode: ParamMode,
886                   defaults_to_global: bool)
887                   -> hir::Path {
888         self.lower_path_extra(id, p, None, param_mode, defaults_to_global)
889     }
890
891     fn lower_path_segment(&mut self,
892                           path_span: Span,
893                           segment: &PathSegment,
894                           param_mode: ParamMode,
895                           expected_lifetimes: usize,
896                           parenthesized_generic_args: ParenthesizedGenericArgs)
897                           -> hir::PathSegment {
898         let mut parameters = if let Some(ref parameters) = segment.parameters {
899             let msg = "parenthesized parameters may only be used with a trait";
900             match **parameters {
901                 PathParameters::AngleBracketed(ref data) => {
902                     self.lower_angle_bracketed_parameter_data(data, param_mode)
903                 }
904                 PathParameters::Parenthesized(ref data) => match parenthesized_generic_args {
905                     ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data),
906                     ParenthesizedGenericArgs::Warn => {
907                         self.sess.buffer_lint(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
908                                               CRATE_NODE_ID, data.span, msg.into());
909                         hir::PathParameters::none()
910                     }
911                     ParenthesizedGenericArgs::Err => {
912                         struct_span_err!(self.sess, data.span, E0214, "{}", msg)
913                             .span_label(data.span, "only traits may use parentheses").emit();
914                         hir::PathParameters::none()
915                     }
916                 }
917             }
918         } else {
919             self.lower_angle_bracketed_parameter_data(&Default::default(), param_mode)
920         };
921
922         if !parameters.parenthesized && parameters.lifetimes.is_empty() {
923             parameters.lifetimes = (0..expected_lifetimes).map(|_| {
924                 self.elided_lifetime(path_span)
925             }).collect();
926         }
927
928         hir::PathSegment {
929             name: self.lower_ident(segment.identifier),
930             parameters,
931         }
932     }
933
934     fn lower_angle_bracketed_parameter_data(&mut self,
935                                             data: &AngleBracketedParameterData,
936                                             param_mode: ParamMode)
937                                             -> hir::PathParameters {
938         let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings, .. } = data;
939         hir::PathParameters {
940             lifetimes: self.lower_lifetimes(lifetimes),
941             types: types.iter().map(|ty| self.lower_ty(ty)).collect(),
942             infer_types: types.is_empty() && param_mode == ParamMode::Optional,
943             bindings: bindings.iter().map(|b| self.lower_ty_binding(b)).collect(),
944             parenthesized: false,
945         }
946     }
947
948     fn lower_parenthesized_parameter_data(&mut self,
949                                           data: &ParenthesizedParameterData)
950                                           -> hir::PathParameters {
951         let &ParenthesizedParameterData { ref inputs, ref output, span } = data;
952         let inputs = inputs.iter().map(|ty| self.lower_ty(ty)).collect();
953         let mk_tup = |this: &mut Self, tys, span| {
954             P(hir::Ty { node: hir::TyTup(tys), id: this.next_id().node_id, span })
955         };
956
957         hir::PathParameters {
958             lifetimes: hir::HirVec::new(),
959             types: hir_vec![mk_tup(self, inputs, span)],
960             infer_types: false,
961             bindings: hir_vec![hir::TypeBinding {
962                 id: self.next_id().node_id,
963                 name: Symbol::intern(FN_OUTPUT_NAME),
964                 ty: output.as_ref().map(|ty| self.lower_ty(&ty))
965                                    .unwrap_or_else(|| mk_tup(self, hir::HirVec::new(), span)),
966                 span: output.as_ref().map_or(span, |ty| ty.span),
967             }],
968             parenthesized: true,
969         }
970     }
971
972     fn lower_local(&mut self, l: &Local) -> P<hir::Local> {
973         let LoweredNodeId { node_id, hir_id } = self.lower_node_id(l.id);
974         P(hir::Local {
975             id: node_id,
976             hir_id,
977             ty: l.ty.as_ref().map(|t| self.lower_ty(t)),
978             pat: self.lower_pat(&l.pat),
979             init: l.init.as_ref().map(|e| P(self.lower_expr(e))),
980             span: l.span,
981             attrs: l.attrs.clone(),
982             source: hir::LocalSource::Normal,
983         })
984     }
985
986     fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability {
987         match m {
988             Mutability::Mutable => hir::MutMutable,
989             Mutability::Immutable => hir::MutImmutable,
990         }
991     }
992
993     fn lower_arg(&mut self, arg: &Arg) -> hir::Arg {
994         let LoweredNodeId { node_id, hir_id } = self.lower_node_id(arg.id);
995         hir::Arg {
996             id: node_id,
997             hir_id,
998             pat: self.lower_pat(&arg.pat),
999         }
1000     }
1001
1002     fn lower_fn_args_to_names(&mut self, decl: &FnDecl)
1003                               -> hir::HirVec<Spanned<Name>> {
1004         decl.inputs.iter().map(|arg| {
1005             match arg.pat.node {
1006                 PatKind::Ident(_, ident, None) => {
1007                     respan(ident.span, ident.node.name)
1008                 }
1009                 _ => respan(arg.pat.span, keywords::Invalid.name()),
1010             }
1011         }).collect()
1012     }
1013
1014     fn lower_fn_decl(&mut self, decl: &FnDecl) -> P<hir::FnDecl> {
1015         P(hir::FnDecl {
1016             inputs: decl.inputs.iter().map(|arg| self.lower_ty(&arg.ty)).collect(),
1017             output: match decl.output {
1018                 FunctionRetTy::Ty(ref ty) => hir::Return(self.lower_ty(ty)),
1019                 FunctionRetTy::Default(span) => hir::DefaultReturn(span),
1020             },
1021             variadic: decl.variadic,
1022             has_implicit_self: decl.inputs.get(0).map_or(false, |arg| {
1023                 match arg.ty.node {
1024                     TyKind::ImplicitSelf => true,
1025                     TyKind::Rptr(_, ref mt) => mt.ty.node == TyKind::ImplicitSelf,
1026                     _ => false
1027                 }
1028             })
1029         })
1030     }
1031
1032     fn lower_ty_param_bound(&mut self, tpb: &TyParamBound) -> hir::TyParamBound {
1033         match *tpb {
1034             TraitTyParamBound(ref ty, modifier) => {
1035                 hir::TraitTyParamBound(self.lower_poly_trait_ref(ty),
1036                                        self.lower_trait_bound_modifier(modifier))
1037             }
1038             RegionTyParamBound(ref lifetime) => {
1039                 hir::RegionTyParamBound(self.lower_lifetime(lifetime))
1040             }
1041         }
1042     }
1043
1044     fn lower_ty_param(&mut self, tp: &TyParam, add_bounds: &[TyParamBound]) -> hir::TyParam {
1045         let mut name = self.lower_ident(tp.ident);
1046
1047         // Don't expose `Self` (recovered "keyword used as ident" parse error).
1048         // `rustc::ty` expects `Self` to be only used for a trait's `Self`.
1049         // Instead, use gensym("Self") to create a distinct name that looks the same.
1050         if name == keywords::SelfType.name() {
1051             name = Symbol::gensym("Self");
1052         }
1053
1054         let mut bounds = self.lower_bounds(&tp.bounds);
1055         if !add_bounds.is_empty() {
1056             bounds = bounds.into_iter().chain(self.lower_bounds(add_bounds).into_iter()).collect();
1057         }
1058
1059         hir::TyParam {
1060             id: self.lower_node_id(tp.id).node_id,
1061             name,
1062             bounds,
1063             default: tp.default.as_ref().map(|x| self.lower_ty(x)),
1064             span: tp.span,
1065             pure_wrt_drop: tp.attrs.iter().any(|attr| attr.check_name("may_dangle")),
1066         }
1067     }
1068
1069     fn lower_ty_params(&mut self, tps: &Vec<TyParam>, add_bounds: &NodeMap<Vec<TyParamBound>>)
1070                        -> hir::HirVec<hir::TyParam> {
1071         tps.iter().map(|tp| {
1072             self.lower_ty_param(tp, add_bounds.get(&tp.id).map_or(&[][..], |x| &x))
1073         }).collect()
1074     }
1075
1076     fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
1077         hir::Lifetime {
1078             id: self.lower_node_id(l.id).node_id,
1079             name: self.lower_ident(l.ident),
1080             span: l.span,
1081         }
1082     }
1083
1084     fn lower_lifetime_def(&mut self, l: &LifetimeDef) -> hir::LifetimeDef {
1085         hir::LifetimeDef {
1086             lifetime: self.lower_lifetime(&l.lifetime),
1087             bounds: self.lower_lifetimes(&l.bounds),
1088             pure_wrt_drop: l.attrs.iter().any(|attr| attr.check_name("may_dangle")),
1089         }
1090     }
1091
1092     fn lower_lifetimes(&mut self, lts: &Vec<Lifetime>) -> hir::HirVec<hir::Lifetime> {
1093         lts.iter().map(|l| self.lower_lifetime(l)).collect()
1094     }
1095
1096     fn lower_lifetime_defs(&mut self, lts: &Vec<LifetimeDef>) -> hir::HirVec<hir::LifetimeDef> {
1097         lts.iter().map(|l| self.lower_lifetime_def(l)).collect()
1098     }
1099
1100     fn lower_generics(&mut self, g: &Generics) -> hir::Generics {
1101         // Collect `?Trait` bounds in where clause and move them to parameter definitions.
1102         let mut add_bounds = NodeMap();
1103         for pred in &g.where_clause.predicates {
1104             if let WherePredicate::BoundPredicate(ref bound_pred) = *pred {
1105                 'next_bound: for bound in &bound_pred.bounds {
1106                     if let TraitTyParamBound(_, TraitBoundModifier::Maybe) = *bound {
1107                         let report_error = |this: &mut Self| {
1108                             this.diagnostic().span_err(bound_pred.bounded_ty.span,
1109                                                        "`?Trait` bounds are only permitted at the \
1110                                                         point where a type parameter is declared");
1111                         };
1112                         // Check if the where clause type is a plain type parameter.
1113                         match bound_pred.bounded_ty.node {
1114                             TyKind::Path(None, ref path)
1115                                     if path.segments.len() == 1 &&
1116                                        bound_pred.bound_lifetimes.is_empty() => {
1117                                 if let Some(Def::TyParam(def_id)) =
1118                                         self.resolver.get_resolution(bound_pred.bounded_ty.id)
1119                                                      .map(|d| d.base_def()) {
1120                                     if let Some(node_id) =
1121                                             self.resolver.definitions().as_local_node_id(def_id) {
1122                                         for ty_param in &g.ty_params {
1123                                             if node_id == ty_param.id {
1124                                                 add_bounds.entry(ty_param.id).or_insert(Vec::new())
1125                                                                             .push(bound.clone());
1126                                                 continue 'next_bound;
1127                                             }
1128                                         }
1129                                     }
1130                                 }
1131                                 report_error(self)
1132                             }
1133                             _ => report_error(self)
1134                         }
1135                     }
1136                 }
1137             }
1138         }
1139
1140         hir::Generics {
1141             ty_params: self.lower_ty_params(&g.ty_params, &add_bounds),
1142             lifetimes: self.lower_lifetime_defs(&g.lifetimes),
1143             where_clause: self.lower_where_clause(&g.where_clause),
1144             span: g.span,
1145         }
1146     }
1147
1148     fn lower_where_clause(&mut self, wc: &WhereClause) -> hir::WhereClause {
1149         hir::WhereClause {
1150             id: self.lower_node_id(wc.id).node_id,
1151             predicates: wc.predicates
1152                           .iter()
1153                           .map(|predicate| self.lower_where_predicate(predicate))
1154                           .collect(),
1155         }
1156     }
1157
1158     fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate {
1159         match *pred {
1160             WherePredicate::BoundPredicate(WhereBoundPredicate{ ref bound_lifetimes,
1161                                                                 ref bounded_ty,
1162                                                                 ref bounds,
1163                                                                 span}) => {
1164                 hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
1165                     bound_lifetimes: self.lower_lifetime_defs(bound_lifetimes),
1166                     bounded_ty: self.lower_ty(bounded_ty),
1167                     bounds: bounds.iter().filter_map(|bound| match *bound {
1168                         // Ignore `?Trait` bounds, they were copied into type parameters already.
1169                         TraitTyParamBound(_, TraitBoundModifier::Maybe) => None,
1170                         _ => Some(self.lower_ty_param_bound(bound))
1171                     }).collect(),
1172                     span,
1173                 })
1174             }
1175             WherePredicate::RegionPredicate(WhereRegionPredicate{ ref lifetime,
1176                                                                   ref bounds,
1177                                                                   span}) => {
1178                 hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
1179                     span,
1180                     lifetime: self.lower_lifetime(lifetime),
1181                     bounds: bounds.iter().map(|bound| self.lower_lifetime(bound)).collect(),
1182                 })
1183             }
1184             WherePredicate::EqPredicate(WhereEqPredicate{ id,
1185                                                           ref lhs_ty,
1186                                                           ref rhs_ty,
1187                                                           span}) => {
1188                 hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
1189                     id: self.lower_node_id(id).node_id,
1190                     lhs_ty: self.lower_ty(lhs_ty),
1191                     rhs_ty: self.lower_ty(rhs_ty),
1192                     span,
1193                 })
1194             }
1195         }
1196     }
1197
1198     fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData {
1199         match *vdata {
1200             VariantData::Struct(ref fields, id) => {
1201                 hir::VariantData::Struct(fields.iter()
1202                                                .enumerate()
1203                                                .map(|f| self.lower_struct_field(f))
1204                                                .collect(),
1205                                          self.lower_node_id(id).node_id)
1206             }
1207             VariantData::Tuple(ref fields, id) => {
1208                 hir::VariantData::Tuple(fields.iter()
1209                                               .enumerate()
1210                                               .map(|f| self.lower_struct_field(f))
1211                                               .collect(),
1212                                         self.lower_node_id(id).node_id)
1213             }
1214             VariantData::Unit(id) => hir::VariantData::Unit(self.lower_node_id(id).node_id),
1215         }
1216     }
1217
1218     fn lower_trait_ref(&mut self, p: &TraitRef) -> hir::TraitRef {
1219         let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit) {
1220             hir::QPath::Resolved(None, path) => path.and_then(|path| path),
1221             qpath => bug!("lower_trait_ref: unexpected QPath `{:?}`", qpath)
1222         };
1223         hir::TraitRef {
1224             path,
1225             ref_id: self.lower_node_id(p.ref_id).node_id,
1226         }
1227     }
1228
1229     fn lower_poly_trait_ref(&mut self, p: &PolyTraitRef) -> hir::PolyTraitRef {
1230         hir::PolyTraitRef {
1231             bound_lifetimes: self.lower_lifetime_defs(&p.bound_lifetimes),
1232             trait_ref: self.lower_trait_ref(&p.trait_ref),
1233             span: p.span,
1234         }
1235     }
1236
1237     fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::StructField {
1238         hir::StructField {
1239             span: f.span,
1240             id: self.lower_node_id(f.id).node_id,
1241             name: self.lower_ident(match f.ident {
1242                 Some(ident) => ident,
1243                 // FIXME(jseyfried) positional field hygiene
1244                 None => Ident { name: Symbol::intern(&index.to_string()), ctxt: f.span.ctxt() },
1245             }),
1246             vis: self.lower_visibility(&f.vis, None),
1247             ty: self.lower_ty(&f.ty),
1248             attrs: self.lower_attrs(&f.attrs),
1249         }
1250     }
1251
1252     fn lower_field(&mut self, f: &Field) -> hir::Field {
1253         hir::Field {
1254             name: respan(f.ident.span, self.lower_ident(f.ident.node)),
1255             expr: P(self.lower_expr(&f.expr)),
1256             span: f.span,
1257             is_shorthand: f.is_shorthand,
1258         }
1259     }
1260
1261     fn lower_mt(&mut self, mt: &MutTy) -> hir::MutTy {
1262         hir::MutTy {
1263             ty: self.lower_ty(&mt.ty),
1264             mutbl: self.lower_mutability(mt.mutbl),
1265         }
1266     }
1267
1268     fn lower_bounds(&mut self, bounds: &[TyParamBound]) -> hir::TyParamBounds {
1269         bounds.iter().map(|bound| self.lower_ty_param_bound(bound)).collect()
1270     }
1271
1272     fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> P<hir::Block> {
1273         let mut expr = None;
1274
1275         let mut stmts = vec![];
1276
1277         for (index, stmt) in b.stmts.iter().enumerate() {
1278             if index == b.stmts.len() - 1 {
1279                 if let StmtKind::Expr(ref e) = stmt.node {
1280                     expr = Some(P(self.lower_expr(e)));
1281                 } else {
1282                     stmts.extend(self.lower_stmt(stmt));
1283                 }
1284             } else {
1285                 stmts.extend(self.lower_stmt(stmt));
1286             }
1287         }
1288
1289         let LoweredNodeId { node_id, hir_id } = self.lower_node_id(b.id);
1290
1291         P(hir::Block {
1292             id: node_id,
1293             hir_id,
1294             stmts: stmts.into(),
1295             expr,
1296             rules: self.lower_block_check_mode(&b.rules),
1297             span: b.span,
1298             targeted_by_break,
1299         })
1300     }
1301
1302     fn lower_item_kind(&mut self,
1303                        id: NodeId,
1304                        name: &mut Name,
1305                        attrs: &hir::HirVec<Attribute>,
1306                        vis: &mut hir::Visibility,
1307                        i: &ItemKind)
1308                        -> hir::Item_ {
1309         match *i {
1310             ItemKind::ExternCrate(string) => hir::ItemExternCrate(string),
1311             ItemKind::Use(ref view_path) => {
1312                 let path = match view_path.node {
1313                     ViewPathSimple(_, ref path) => path,
1314                     ViewPathGlob(ref path) => path,
1315                     ViewPathList(ref path, ref path_list_idents) => {
1316                         for &Spanned { node: ref import, span } in path_list_idents {
1317                             // `use a::{self as x, b as y};` lowers to
1318                             // `use a as x; use a::b as y;`
1319                             let mut ident = import.name;
1320                             let suffix = if ident.name == keywords::SelfValue.name() {
1321                                 if let Some(last) = path.segments.last() {
1322                                     ident = last.identifier;
1323                                 }
1324                                 None
1325                             } else {
1326                                 Some(ident.name)
1327                             };
1328
1329                             let mut path = self.lower_path_extra(import.id, path, suffix,
1330                                                                  ParamMode::Explicit, true);
1331                             path.span = span;
1332
1333                             self.allocate_hir_id_counter(import.id, import);
1334                             let LoweredNodeId {
1335                                 node_id: import_node_id,
1336                                 hir_id: import_hir_id,
1337                             } = self.lower_node_id(import.id);
1338
1339                             self.with_hir_id_owner(import_node_id, |this| {
1340                                 let vis = match *vis {
1341                                     hir::Visibility::Public => hir::Visibility::Public,
1342                                     hir::Visibility::Crate => hir::Visibility::Crate,
1343                                     hir::Visibility::Inherited => hir::Visibility::Inherited,
1344                                     hir::Visibility::Restricted { ref path, id: _ } => {
1345                                         hir::Visibility::Restricted {
1346                                             path: path.clone(),
1347                                             // We are allocating a new NodeId here
1348                                             id: this.next_id().node_id,
1349                                         }
1350                                     }
1351                                 };
1352
1353                                 this.items.insert(import_node_id, hir::Item {
1354                                     id: import_node_id,
1355                                     hir_id: import_hir_id,
1356                                     name: import.rename.unwrap_or(ident).name,
1357                                     attrs: attrs.clone(),
1358                                     node: hir::ItemUse(P(path), hir::UseKind::Single),
1359                                     vis,
1360                                     span,
1361                                 });
1362                             });
1363                         }
1364                         path
1365                     }
1366                 };
1367                 let path = P(self.lower_path(id, path, ParamMode::Explicit, true));
1368                 let kind = match view_path.node {
1369                     ViewPathSimple(ident, _) => {
1370                         *name = ident.name;
1371                         hir::UseKind::Single
1372                     }
1373                     ViewPathGlob(_) => {
1374                         hir::UseKind::Glob
1375                     }
1376                     ViewPathList(..) => {
1377                         // Privatize the degenerate import base, used only to check
1378                         // the stability of `use a::{};`, to avoid it showing up as
1379                         // a reexport by accident when `pub`, e.g. in documentation.
1380                         *vis = hir::Inherited;
1381                         hir::UseKind::ListStem
1382                     }
1383                 };
1384                 hir::ItemUse(path, kind)
1385             }
1386             ItemKind::Static(ref t, m, ref e) => {
1387                 let value = self.lower_body(None, |this| this.lower_expr(e));
1388                 hir::ItemStatic(self.lower_ty(t),
1389                                 self.lower_mutability(m),
1390                                 value)
1391             }
1392             ItemKind::Const(ref t, ref e) => {
1393                 let value = self.lower_body(None, |this| this.lower_expr(e));
1394                 hir::ItemConst(self.lower_ty(t), value)
1395             }
1396             ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
1397                 self.with_new_scopes(|this| {
1398                     let body_id = this.lower_body(Some(decl), |this| {
1399                         let body = this.lower_block(body, false);
1400                         this.expr_block(body, ThinVec::new())
1401                     });
1402                     hir::ItemFn(this.lower_fn_decl(decl),
1403                                               this.lower_unsafety(unsafety),
1404                                               this.lower_constness(constness),
1405                                               abi,
1406                                               this.lower_generics(generics),
1407                                               body_id)
1408                 })
1409             }
1410             ItemKind::Mod(ref m) => hir::ItemMod(self.lower_mod(m)),
1411             ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(self.lower_foreign_mod(nm)),
1412             ItemKind::GlobalAsm(ref ga) => hir::ItemGlobalAsm(self.lower_global_asm(ga)),
1413             ItemKind::Ty(ref t, ref generics) => {
1414                 hir::ItemTy(self.lower_ty(t), self.lower_generics(generics))
1415             }
1416             ItemKind::Enum(ref enum_definition, ref generics) => {
1417                 hir::ItemEnum(hir::EnumDef {
1418                                   variants: enum_definition.variants
1419                                                            .iter()
1420                                                            .map(|x| self.lower_variant(x))
1421                                                            .collect(),
1422                               },
1423                               self.lower_generics(generics))
1424             }
1425             ItemKind::Struct(ref struct_def, ref generics) => {
1426                 let struct_def = self.lower_variant_data(struct_def);
1427                 hir::ItemStruct(struct_def, self.lower_generics(generics))
1428             }
1429             ItemKind::Union(ref vdata, ref generics) => {
1430                 let vdata = self.lower_variant_data(vdata);
1431                 hir::ItemUnion(vdata, self.lower_generics(generics))
1432             }
1433             ItemKind::DefaultImpl(unsafety, ref trait_ref) => {
1434                 let trait_ref = self.lower_trait_ref(trait_ref);
1435
1436                 if let Def::Trait(def_id) = trait_ref.path.def {
1437                     self.trait_default_impl.insert(def_id, id);
1438                 }
1439
1440                 hir::ItemDefaultImpl(self.lower_unsafety(unsafety),
1441                                      trait_ref)
1442             }
1443             ItemKind::Impl(unsafety,
1444                            polarity,
1445                            defaultness,
1446                            ref generics,
1447                            ref ifce,
1448                            ref ty,
1449                            ref impl_items) => {
1450                 let new_impl_items = impl_items.iter()
1451                                                .map(|item| self.lower_impl_item_ref(item))
1452                                                .collect();
1453                 let ifce = ifce.as_ref().map(|trait_ref| self.lower_trait_ref(trait_ref));
1454
1455                 if let Some(ref trait_ref) = ifce {
1456                     if let Def::Trait(def_id) = trait_ref.path.def {
1457                         self.trait_impls.entry(def_id).or_insert(vec![]).push(id);
1458                     }
1459                 }
1460
1461                 hir::ItemImpl(self.lower_unsafety(unsafety),
1462                               self.lower_impl_polarity(polarity),
1463                               self.lower_defaultness(defaultness, true /* [1] */),
1464                               self.lower_generics(generics),
1465                               ifce,
1466                               self.lower_ty(ty),
1467                               new_impl_items)
1468             }
1469             ItemKind::Trait(unsafety, ref generics, ref bounds, ref items) => {
1470                 let bounds = self.lower_bounds(bounds);
1471                 let items = items.iter().map(|item| self.lower_trait_item_ref(item)).collect();
1472                 hir::ItemTrait(self.lower_unsafety(unsafety),
1473                                self.lower_generics(generics),
1474                                bounds,
1475                                items)
1476             }
1477             ItemKind::MacroDef(..) | ItemKind::Mac(..) => panic!("Shouldn't still be around"),
1478         }
1479
1480         // [1] `defaultness.has_value()` is never called for an `impl`, always `true` in order to
1481         //     not cause an assertion failure inside the `lower_defaultness` function
1482     }
1483
1484     fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
1485         self.with_parent_def(i.id, |this| {
1486             let LoweredNodeId { node_id, hir_id } = this.lower_node_id(i.id);
1487
1488             hir::TraitItem {
1489                 id: node_id,
1490                 hir_id,
1491                 name: this.lower_ident(i.ident),
1492                 attrs: this.lower_attrs(&i.attrs),
1493                 node: match i.node {
1494                     TraitItemKind::Const(ref ty, ref default) => {
1495                         hir::TraitItemKind::Const(this.lower_ty(ty),
1496                                                   default.as_ref().map(|x| {
1497                             this.lower_body(None, |this| this.lower_expr(x))
1498                         }))
1499                     }
1500                     TraitItemKind::Method(ref sig, None) => {
1501                         let names = this.lower_fn_args_to_names(&sig.decl);
1502                         hir::TraitItemKind::Method(this.lower_method_sig(sig),
1503                                                    hir::TraitMethod::Required(names))
1504                     }
1505                     TraitItemKind::Method(ref sig, Some(ref body)) => {
1506                         let body_id = this.lower_body(Some(&sig.decl), |this| {
1507                             let body = this.lower_block(body, false);
1508                             this.expr_block(body, ThinVec::new())
1509                         });
1510                         hir::TraitItemKind::Method(this.lower_method_sig(sig),
1511                                                    hir::TraitMethod::Provided(body_id))
1512                     }
1513                     TraitItemKind::Type(ref bounds, ref default) => {
1514                         hir::TraitItemKind::Type(this.lower_bounds(bounds),
1515                                                  default.as_ref().map(|x| this.lower_ty(x)))
1516                     }
1517                     TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"),
1518                 },
1519                 span: i.span,
1520             }
1521         })
1522     }
1523
1524     fn lower_trait_item_ref(&mut self, i: &TraitItem) -> hir::TraitItemRef {
1525         let (kind, has_default) = match i.node {
1526             TraitItemKind::Const(_, ref default) => {
1527                 (hir::AssociatedItemKind::Const, default.is_some())
1528             }
1529             TraitItemKind::Type(_, ref default) => {
1530                 (hir::AssociatedItemKind::Type, default.is_some())
1531             }
1532             TraitItemKind::Method(ref sig, ref default) => {
1533                 (hir::AssociatedItemKind::Method {
1534                     has_self: sig.decl.has_self(),
1535                  }, default.is_some())
1536             }
1537             TraitItemKind::Macro(..) => unimplemented!(),
1538         };
1539         hir::TraitItemRef {
1540             id: hir::TraitItemId { node_id: i.id },
1541             name: self.lower_ident(i.ident),
1542             span: i.span,
1543             defaultness: self.lower_defaultness(Defaultness::Default, has_default),
1544             kind,
1545         }
1546     }
1547
1548     fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
1549         self.with_parent_def(i.id, |this| {
1550             let LoweredNodeId { node_id, hir_id } = this.lower_node_id(i.id);
1551
1552             hir::ImplItem {
1553                 id: node_id,
1554                 hir_id,
1555                 name: this.lower_ident(i.ident),
1556                 attrs: this.lower_attrs(&i.attrs),
1557                 vis: this.lower_visibility(&i.vis, None),
1558                 defaultness: this.lower_defaultness(i.defaultness, true /* [1] */),
1559                 node: match i.node {
1560                     ImplItemKind::Const(ref ty, ref expr) => {
1561                         let body_id = this.lower_body(None, |this| this.lower_expr(expr));
1562                         hir::ImplItemKind::Const(this.lower_ty(ty), body_id)
1563                     }
1564                     ImplItemKind::Method(ref sig, ref body) => {
1565                         let body_id = this.lower_body(Some(&sig.decl), |this| {
1566                             let body = this.lower_block(body, false);
1567                             this.expr_block(body, ThinVec::new())
1568                         });
1569                         hir::ImplItemKind::Method(this.lower_method_sig(sig), body_id)
1570                     }
1571                     ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(this.lower_ty(ty)),
1572                     ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
1573                 },
1574                 span: i.span,
1575             }
1576         })
1577
1578         // [1] since `default impl` is not yet implemented, this is always true in impls
1579     }
1580
1581     fn lower_impl_item_ref(&mut self, i: &ImplItem) -> hir::ImplItemRef {
1582         hir::ImplItemRef {
1583             id: hir::ImplItemId { node_id: i.id },
1584             name: self.lower_ident(i.ident),
1585             span: i.span,
1586             vis: self.lower_visibility(&i.vis, Some(i.id)),
1587             defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
1588             kind: match i.node {
1589                 ImplItemKind::Const(..) => hir::AssociatedItemKind::Const,
1590                 ImplItemKind::Type(..) => hir::AssociatedItemKind::Type,
1591                 ImplItemKind::Method(ref sig, _) => hir::AssociatedItemKind::Method {
1592                     has_self: sig.decl.has_self(),
1593                 },
1594                 ImplItemKind::Macro(..) => unimplemented!(),
1595             },
1596         }
1597
1598         // [1] since `default impl` is not yet implemented, this is always true in impls
1599     }
1600
1601     fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
1602         hir::Mod {
1603             inner: m.inner,
1604             item_ids: m.items.iter().flat_map(|x| self.lower_item_id(x)).collect(),
1605         }
1606     }
1607
1608     fn lower_item_id(&mut self, i: &Item) -> SmallVector<hir::ItemId> {
1609         match i.node {
1610             ItemKind::Use(ref view_path) => {
1611                 if let ViewPathList(_, ref imports) = view_path.node {
1612                     return iter::once(i.id).chain(imports.iter().map(|import| import.node.id))
1613                         .map(|id| hir::ItemId { id: id }).collect();
1614                 }
1615             }
1616             ItemKind::MacroDef(..) => return SmallVector::new(),
1617             _ => {}
1618         }
1619         SmallVector::one(hir::ItemId { id: i.id })
1620     }
1621
1622     pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item> {
1623         let mut name = i.ident.name;
1624         let mut vis = self.lower_visibility(&i.vis, None);
1625         let attrs = self.lower_attrs(&i.attrs);
1626         if let ItemKind::MacroDef(ref def) = i.node {
1627             if !def.legacy || i.attrs.iter().any(|attr| attr.path == "macro_export") {
1628                 self.exported_macros.push(hir::MacroDef {
1629                     name,
1630                     vis,
1631                     attrs,
1632                     id: i.id,
1633                     span: i.span,
1634                     body: def.stream(),
1635                     legacy: def.legacy,
1636                 });
1637             }
1638             return None;
1639         }
1640
1641         let node = self.with_parent_def(i.id, |this| {
1642             this.lower_item_kind(i.id, &mut name, &attrs, &mut vis, &i.node)
1643         });
1644
1645         let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id);
1646
1647         Some(hir::Item {
1648             id: node_id,
1649             hir_id,
1650             name,
1651             attrs,
1652             node,
1653             vis,
1654             span: i.span,
1655         })
1656     }
1657
1658     fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
1659         self.with_parent_def(i.id, |this| {
1660             hir::ForeignItem {
1661                 id: this.lower_node_id(i.id).node_id,
1662                 name: i.ident.name,
1663                 attrs: this.lower_attrs(&i.attrs),
1664                 node: match i.node {
1665                     ForeignItemKind::Fn(ref fdec, ref generics) => {
1666                         hir::ForeignItemFn(this.lower_fn_decl(fdec),
1667                                            this.lower_fn_args_to_names(fdec),
1668                                            this.lower_generics(generics))
1669                     }
1670                     ForeignItemKind::Static(ref t, m) => {
1671                         hir::ForeignItemStatic(this.lower_ty(t), m)
1672                     }
1673                 },
1674                 vis: this.lower_visibility(&i.vis, None),
1675                 span: i.span,
1676             }
1677         })
1678     }
1679
1680     fn lower_method_sig(&mut self, sig: &MethodSig) -> hir::MethodSig {
1681         hir::MethodSig {
1682             generics: self.lower_generics(&sig.generics),
1683             abi: sig.abi,
1684             unsafety: self.lower_unsafety(sig.unsafety),
1685             constness: self.lower_constness(sig.constness),
1686             decl: self.lower_fn_decl(&sig.decl),
1687         }
1688     }
1689
1690     fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
1691         match u {
1692             Unsafety::Unsafe => hir::Unsafety::Unsafe,
1693             Unsafety::Normal => hir::Unsafety::Normal,
1694         }
1695     }
1696
1697     fn lower_constness(&mut self, c: Spanned<Constness>) -> hir::Constness {
1698         match c.node {
1699             Constness::Const => hir::Constness::Const,
1700             Constness::NotConst => hir::Constness::NotConst,
1701         }
1702     }
1703
1704     fn lower_unop(&mut self, u: UnOp) -> hir::UnOp {
1705         match u {
1706             UnOp::Deref => hir::UnDeref,
1707             UnOp::Not => hir::UnNot,
1708             UnOp::Neg => hir::UnNeg,
1709         }
1710     }
1711
1712     fn lower_binop(&mut self, b: BinOp) -> hir::BinOp {
1713         Spanned {
1714             node: match b.node {
1715                 BinOpKind::Add => hir::BiAdd,
1716                 BinOpKind::Sub => hir::BiSub,
1717                 BinOpKind::Mul => hir::BiMul,
1718                 BinOpKind::Div => hir::BiDiv,
1719                 BinOpKind::Rem => hir::BiRem,
1720                 BinOpKind::And => hir::BiAnd,
1721                 BinOpKind::Or => hir::BiOr,
1722                 BinOpKind::BitXor => hir::BiBitXor,
1723                 BinOpKind::BitAnd => hir::BiBitAnd,
1724                 BinOpKind::BitOr => hir::BiBitOr,
1725                 BinOpKind::Shl => hir::BiShl,
1726                 BinOpKind::Shr => hir::BiShr,
1727                 BinOpKind::Eq => hir::BiEq,
1728                 BinOpKind::Lt => hir::BiLt,
1729                 BinOpKind::Le => hir::BiLe,
1730                 BinOpKind::Ne => hir::BiNe,
1731                 BinOpKind::Ge => hir::BiGe,
1732                 BinOpKind::Gt => hir::BiGt,
1733             },
1734             span: b.span,
1735         }
1736     }
1737
1738     fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
1739         let LoweredNodeId { node_id, hir_id } = self.lower_node_id(p.id);
1740
1741         P(hir::Pat {
1742             id: node_id,
1743             hir_id,
1744             node: match p.node {
1745                 PatKind::Wild => hir::PatKind::Wild,
1746                 PatKind::Ident(ref binding_mode, pth1, ref sub) => {
1747                     match self.resolver.get_resolution(p.id).map(|d| d.base_def()) {
1748                         // `None` can occur in body-less function signatures
1749                         def @ None | def @ Some(Def::Local(_)) => {
1750                             let canonical_id = match def {
1751                                 Some(Def::Local(id)) => id,
1752                                 _ => p.id
1753                             };
1754                             hir::PatKind::Binding(self.lower_binding_mode(binding_mode),
1755                                                   canonical_id,
1756                                                   respan(pth1.span, pth1.node.name),
1757                                                   sub.as_ref().map(|x| self.lower_pat(x)))
1758                         }
1759                         Some(def) => {
1760                             hir::PatKind::Path(hir::QPath::Resolved(None, P(hir::Path {
1761                                 span: pth1.span,
1762                                 def,
1763                                 segments: hir_vec![
1764                                     hir::PathSegment::from_name(pth1.node.name)
1765                                 ],
1766                             })))
1767                         }
1768                     }
1769                 }
1770                 PatKind::Lit(ref e) => hir::PatKind::Lit(P(self.lower_expr(e))),
1771                 PatKind::TupleStruct(ref path, ref pats, ddpos) => {
1772                     let qpath = self.lower_qpath(p.id, &None, path, ParamMode::Optional);
1773                     hir::PatKind::TupleStruct(qpath,
1774                                               pats.iter().map(|x| self.lower_pat(x)).collect(),
1775                                               ddpos)
1776                 }
1777                 PatKind::Path(ref qself, ref path) => {
1778                     hir::PatKind::Path(self.lower_qpath(p.id, qself, path, ParamMode::Optional))
1779                 }
1780                 PatKind::Struct(ref path, ref fields, etc) => {
1781                     let qpath = self.lower_qpath(p.id, &None, path, ParamMode::Optional);
1782
1783                     let fs = fields.iter()
1784                                    .map(|f| {
1785                                        Spanned {
1786                                            span: f.span,
1787                                            node: hir::FieldPat {
1788                                                name: self.lower_ident(f.node.ident),
1789                                                pat: self.lower_pat(&f.node.pat),
1790                                                is_shorthand: f.node.is_shorthand,
1791                                            },
1792                                        }
1793                                    })
1794                                    .collect();
1795                     hir::PatKind::Struct(qpath, fs, etc)
1796                 }
1797                 PatKind::Tuple(ref elts, ddpos) => {
1798                     hir::PatKind::Tuple(elts.iter().map(|x| self.lower_pat(x)).collect(), ddpos)
1799                 }
1800                 PatKind::Box(ref inner) => hir::PatKind::Box(self.lower_pat(inner)),
1801                 PatKind::Ref(ref inner, mutbl) => {
1802                     hir::PatKind::Ref(self.lower_pat(inner), self.lower_mutability(mutbl))
1803                 }
1804                 PatKind::Range(ref e1, ref e2, ref end) => {
1805                     hir::PatKind::Range(P(self.lower_expr(e1)),
1806                                         P(self.lower_expr(e2)),
1807                                         self.lower_range_end(end))
1808                 }
1809                 PatKind::Slice(ref before, ref slice, ref after) => {
1810                     hir::PatKind::Slice(before.iter().map(|x| self.lower_pat(x)).collect(),
1811                                 slice.as_ref().map(|x| self.lower_pat(x)),
1812                                 after.iter().map(|x| self.lower_pat(x)).collect())
1813                 }
1814                 PatKind::Mac(_) => panic!("Shouldn't exist here"),
1815             },
1816             span: p.span,
1817         })
1818     }
1819
1820     fn lower_range_end(&mut self, e: &RangeEnd) -> hir::RangeEnd {
1821         match *e {
1822             RangeEnd::Included => hir::RangeEnd::Included,
1823             RangeEnd::Excluded => hir::RangeEnd::Excluded,
1824         }
1825     }
1826
1827     fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
1828         let kind = match e.node {
1829             // Issue #22181:
1830             // Eventually a desugaring for `box EXPR`
1831             // (similar to the desugaring above for `in PLACE BLOCK`)
1832             // should go here, desugaring
1833             //
1834             // to:
1835             //
1836             // let mut place = BoxPlace::make_place();
1837             // let raw_place = Place::pointer(&mut place);
1838             // let value = $value;
1839             // unsafe {
1840             //     ::std::ptr::write(raw_place, value);
1841             //     Boxed::finalize(place)
1842             // }
1843             //
1844             // But for now there are type-inference issues doing that.
1845             ExprKind::Box(ref inner) => {
1846                 hir::ExprBox(P(self.lower_expr(inner)))
1847             }
1848
1849             // Desugar ExprBox: `in (PLACE) EXPR`
1850             ExprKind::InPlace(ref placer, ref value_expr) => {
1851                 // to:
1852                 //
1853                 // let p = PLACE;
1854                 // let mut place = Placer::make_place(p);
1855                 // let raw_place = Place::pointer(&mut place);
1856                 // push_unsafe!({
1857                 //     std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR ));
1858                 //     InPlace::finalize(place)
1859                 // })
1860                 let placer_expr = P(self.lower_expr(placer));
1861                 let value_expr = P(self.lower_expr(value_expr));
1862
1863                 let placer_ident = self.str_to_ident("placer");
1864                 let place_ident = self.str_to_ident("place");
1865                 let p_ptr_ident = self.str_to_ident("p_ptr");
1866
1867                 let make_place = ["ops", "Placer", "make_place"];
1868                 let place_pointer = ["ops", "Place", "pointer"];
1869                 let move_val_init = ["intrinsics", "move_val_init"];
1870                 let inplace_finalize = ["ops", "InPlace", "finalize"];
1871
1872                 let unstable_span =
1873                     self.allow_internal_unstable(CompilerDesugaringKind::BackArrow, e.span);
1874                 let make_call = |this: &mut LoweringContext, p, args| {
1875                     let path = P(this.expr_std_path(unstable_span, p, ThinVec::new()));
1876                     P(this.expr_call(e.span, path, args))
1877                 };
1878
1879                 let mk_stmt_let = |this: &mut LoweringContext, bind, expr| {
1880                     this.stmt_let(e.span, false, bind, expr)
1881                 };
1882
1883                 let mk_stmt_let_mut = |this: &mut LoweringContext, bind, expr| {
1884                     this.stmt_let(e.span, true, bind, expr)
1885                 };
1886
1887                 // let placer = <placer_expr> ;
1888                 let (s1, placer_binding) = {
1889                     mk_stmt_let(self, placer_ident, placer_expr)
1890                 };
1891
1892                 // let mut place = Placer::make_place(placer);
1893                 let (s2, place_binding) = {
1894                     let placer = self.expr_ident(e.span, placer_ident, placer_binding);
1895                     let call = make_call(self, &make_place, hir_vec![placer]);
1896                     mk_stmt_let_mut(self, place_ident, call)
1897                 };
1898
1899                 // let p_ptr = Place::pointer(&mut place);
1900                 let (s3, p_ptr_binding) = {
1901                     let agent = P(self.expr_ident(e.span, place_ident, place_binding));
1902                     let args = hir_vec![self.expr_mut_addr_of(e.span, agent)];
1903                     let call = make_call(self, &place_pointer, args);
1904                     mk_stmt_let(self, p_ptr_ident, call)
1905                 };
1906
1907                 // pop_unsafe!(EXPR));
1908                 let pop_unsafe_expr = {
1909                     self.signal_block_expr(hir_vec![],
1910                                            value_expr,
1911                                            e.span,
1912                                            hir::PopUnsafeBlock(hir::CompilerGenerated),
1913                                            ThinVec::new())
1914                 };
1915
1916                 // push_unsafe!({
1917                 //     std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR ));
1918                 //     InPlace::finalize(place)
1919                 // })
1920                 let expr = {
1921                     let ptr = self.expr_ident(e.span, p_ptr_ident, p_ptr_binding);
1922                     let call_move_val_init =
1923                         hir::StmtSemi(
1924                             make_call(self, &move_val_init, hir_vec![ptr, pop_unsafe_expr]),
1925                             self.next_id().node_id);
1926                     let call_move_val_init = respan(e.span, call_move_val_init);
1927
1928                     let place = self.expr_ident(e.span, place_ident, place_binding);
1929                     let call = make_call(self, &inplace_finalize, hir_vec![place]);
1930                     P(self.signal_block_expr(hir_vec![call_move_val_init],
1931                                              call,
1932                                              e.span,
1933                                              hir::PushUnsafeBlock(hir::CompilerGenerated),
1934                                              ThinVec::new()))
1935                 };
1936
1937                 let block = self.block_all(e.span, hir_vec![s1, s2, s3], Some(expr));
1938                 hir::ExprBlock(P(block))
1939             }
1940
1941             ExprKind::Array(ref exprs) => {
1942                 hir::ExprArray(exprs.iter().map(|x| self.lower_expr(x)).collect())
1943             }
1944             ExprKind::Repeat(ref expr, ref count) => {
1945                 let expr = P(self.lower_expr(expr));
1946                 let count = self.lower_body(None, |this| this.lower_expr(count));
1947                 hir::ExprRepeat(expr, count)
1948             }
1949             ExprKind::Tup(ref elts) => {
1950                 hir::ExprTup(elts.iter().map(|x| self.lower_expr(x)).collect())
1951             }
1952             ExprKind::Call(ref f, ref args) => {
1953                 let f = P(self.lower_expr(f));
1954                 hir::ExprCall(f, args.iter().map(|x| self.lower_expr(x)).collect())
1955             }
1956             ExprKind::MethodCall(ref seg, ref args) => {
1957                 let hir_seg = self.lower_path_segment(e.span, seg, ParamMode::Optional, 0,
1958                                                       ParenthesizedGenericArgs::Err);
1959                 let args = args.iter().map(|x| self.lower_expr(x)).collect();
1960                 hir::ExprMethodCall(hir_seg, seg.span, args)
1961             }
1962             ExprKind::Binary(binop, ref lhs, ref rhs) => {
1963                 let binop = self.lower_binop(binop);
1964                 let lhs = P(self.lower_expr(lhs));
1965                 let rhs = P(self.lower_expr(rhs));
1966                 hir::ExprBinary(binop, lhs, rhs)
1967             }
1968             ExprKind::Unary(op, ref ohs) => {
1969                 let op = self.lower_unop(op);
1970                 let ohs = P(self.lower_expr(ohs));
1971                 hir::ExprUnary(op, ohs)
1972             }
1973             ExprKind::Lit(ref l) => hir::ExprLit(P((**l).clone())),
1974             ExprKind::Cast(ref expr, ref ty) => {
1975                 let expr = P(self.lower_expr(expr));
1976                 hir::ExprCast(expr, self.lower_ty(ty))
1977             }
1978             ExprKind::Type(ref expr, ref ty) => {
1979                 let expr = P(self.lower_expr(expr));
1980                 hir::ExprType(expr, self.lower_ty(ty))
1981             }
1982             ExprKind::AddrOf(m, ref ohs) => {
1983                 let m = self.lower_mutability(m);
1984                 let ohs = P(self.lower_expr(ohs));
1985                 hir::ExprAddrOf(m, ohs)
1986             }
1987             // More complicated than you might expect because the else branch
1988             // might be `if let`.
1989             ExprKind::If(ref cond, ref blk, ref else_opt) => {
1990                 let else_opt = else_opt.as_ref().map(|els| {
1991                     match els.node {
1992                         ExprKind::IfLet(..) => {
1993                             // wrap the if-let expr in a block
1994                             let span = els.span;
1995                             let els = P(self.lower_expr(els));
1996                             let LoweredNodeId {
1997                                 node_id,
1998                                 hir_id,
1999                             } = self.next_id();
2000                             let blk = P(hir::Block {
2001                                 stmts: hir_vec![],
2002                                 expr: Some(els),
2003                                 id: node_id,
2004                                 hir_id,
2005                                 rules: hir::DefaultBlock,
2006                                 span,
2007                                 targeted_by_break: false,
2008                             });
2009                             P(self.expr_block(blk, ThinVec::new()))
2010                         }
2011                         _ => P(self.lower_expr(els)),
2012                     }
2013                 });
2014
2015                 let then_blk = self.lower_block(blk, false);
2016                 let then_expr = self.expr_block(then_blk, ThinVec::new());
2017
2018                 hir::ExprIf(P(self.lower_expr(cond)), P(then_expr), else_opt)
2019             }
2020             ExprKind::While(ref cond, ref body, opt_ident) => {
2021                 self.with_loop_scope(e.id, |this|
2022                     hir::ExprWhile(
2023                         this.with_loop_condition_scope(|this| P(this.lower_expr(cond))),
2024                         this.lower_block(body, false),
2025                         this.lower_opt_sp_ident(opt_ident)))
2026             }
2027             ExprKind::Loop(ref body, opt_ident) => {
2028                 self.with_loop_scope(e.id, |this|
2029                     hir::ExprLoop(this.lower_block(body, false),
2030                                   this.lower_opt_sp_ident(opt_ident),
2031                                   hir::LoopSource::Loop))
2032             }
2033             ExprKind::Catch(ref body) => {
2034                 self.with_catch_scope(body.id, |this|
2035                     hir::ExprBlock(this.lower_block(body, true)))
2036             }
2037             ExprKind::Match(ref expr, ref arms) => {
2038                 hir::ExprMatch(P(self.lower_expr(expr)),
2039                                arms.iter().map(|x| self.lower_arm(x)).collect(),
2040                                hir::MatchSource::Normal)
2041             }
2042             ExprKind::Closure(capture_clause, ref decl, ref body, fn_decl_span) => {
2043                 self.with_new_scopes(|this| {
2044                     this.with_parent_def(e.id, |this| {
2045                         let mut is_generator = false;
2046                         let body_id = this.lower_body(Some(decl), |this| {
2047                             let e = this.lower_expr(body);
2048                             is_generator = this.is_generator;
2049                             e
2050                         });
2051                         if is_generator && !decl.inputs.is_empty() {
2052                             span_err!(this.sess, fn_decl_span, E0628,
2053                                       "generators cannot have explicit arguments");
2054                             this.sess.abort_if_errors();
2055                         }
2056                         hir::ExprClosure(this.lower_capture_clause(capture_clause),
2057                                          this.lower_fn_decl(decl),
2058                                          body_id,
2059                                          fn_decl_span,
2060                                          is_generator)
2061                     })
2062                 })
2063             }
2064             ExprKind::Block(ref blk) => hir::ExprBlock(self.lower_block(blk, false)),
2065             ExprKind::Assign(ref el, ref er) => {
2066                 hir::ExprAssign(P(self.lower_expr(el)), P(self.lower_expr(er)))
2067             }
2068             ExprKind::AssignOp(op, ref el, ref er) => {
2069                 hir::ExprAssignOp(self.lower_binop(op),
2070                                   P(self.lower_expr(el)),
2071                                   P(self.lower_expr(er)))
2072             }
2073             ExprKind::Field(ref el, ident) => {
2074                 hir::ExprField(P(self.lower_expr(el)),
2075                                respan(ident.span, self.lower_ident(ident.node)))
2076             }
2077             ExprKind::TupField(ref el, ident) => {
2078                 hir::ExprTupField(P(self.lower_expr(el)), ident)
2079             }
2080             ExprKind::Index(ref el, ref er) => {
2081                 hir::ExprIndex(P(self.lower_expr(el)), P(self.lower_expr(er)))
2082             }
2083             ExprKind::Range(ref e1, ref e2, lims) => {
2084                 use syntax::ast::RangeLimits::*;
2085
2086                 let path = match (e1, e2, lims) {
2087                     (&None, &None, HalfOpen) => "RangeFull",
2088                     (&Some(..), &None, HalfOpen) => "RangeFrom",
2089                     (&None, &Some(..), HalfOpen) => "RangeTo",
2090                     (&Some(..), &Some(..), HalfOpen) => "Range",
2091                     (&None, &Some(..), Closed) => "RangeToInclusive",
2092                     (&Some(..), &Some(..), Closed) => "RangeInclusive",
2093                     (_, &None, Closed) =>
2094                         panic!(self.diagnostic().span_fatal(
2095                             e.span, "inclusive range with no end")),
2096                 };
2097
2098                 let fields =
2099                     e1.iter().map(|e| ("start", e)).chain(e2.iter().map(|e| ("end", e)))
2100                     .map(|(s, e)| {
2101                         let expr = P(self.lower_expr(&e));
2102                         let unstable_span =
2103                             self.allow_internal_unstable(CompilerDesugaringKind::DotFill, e.span);
2104                         self.field(Symbol::intern(s), expr, unstable_span)
2105                     }).collect::<P<[hir::Field]>>();
2106
2107                 let is_unit = fields.is_empty();
2108                 let unstable_span =
2109                     self.allow_internal_unstable(CompilerDesugaringKind::DotFill, e.span);
2110                 let struct_path =
2111                     iter::once("ops").chain(iter::once(path))
2112                     .collect::<Vec<_>>();
2113                 let struct_path = self.std_path(unstable_span, &struct_path, is_unit);
2114                 let struct_path = hir::QPath::Resolved(None, P(struct_path));
2115
2116                 let LoweredNodeId { node_id, hir_id } = self.lower_node_id(e.id);
2117
2118                 return hir::Expr {
2119                     id: node_id,
2120                     hir_id,
2121                     node: if is_unit {
2122                         hir::ExprPath(struct_path)
2123                     } else {
2124                         hir::ExprStruct(struct_path, fields, None)
2125                     },
2126                     span: unstable_span,
2127                     attrs: e.attrs.clone(),
2128                 };
2129             }
2130             ExprKind::Path(ref qself, ref path) => {
2131                 hir::ExprPath(self.lower_qpath(e.id, qself, path, ParamMode::Optional))
2132             }
2133             ExprKind::Break(opt_ident, ref opt_expr) => {
2134                 let label_result = if self.is_in_loop_condition && opt_ident.is_none() {
2135                     hir::Destination {
2136                         ident: opt_ident,
2137                         target_id: hir::ScopeTarget::Loop(
2138                                 Err(hir::LoopIdError::UnlabeledCfInWhileCondition).into()),
2139                     }
2140                 } else {
2141                     self.lower_loop_destination(opt_ident.map(|ident| (e.id, ident)))
2142                 };
2143                 hir::ExprBreak(
2144                         label_result,
2145                         opt_expr.as_ref().map(|x| P(self.lower_expr(x))))
2146             }
2147             ExprKind::Continue(opt_ident) =>
2148                 hir::ExprAgain(
2149                     if self.is_in_loop_condition && opt_ident.is_none() {
2150                         hir::Destination {
2151                             ident: opt_ident,
2152                             target_id: hir::ScopeTarget::Loop(Err(
2153                                 hir::LoopIdError::UnlabeledCfInWhileCondition).into()),
2154                         }
2155                     } else {
2156                         self.lower_loop_destination(opt_ident.map( |ident| (e.id, ident)))
2157                     }),
2158             ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| P(self.lower_expr(x)))),
2159             ExprKind::InlineAsm(ref asm) => {
2160                 let hir_asm = hir::InlineAsm {
2161                     inputs: asm.inputs.iter().map(|&(ref c, _)| c.clone()).collect(),
2162                     outputs: asm.outputs.iter().map(|out| {
2163                         hir::InlineAsmOutput {
2164                             constraint: out.constraint.clone(),
2165                             is_rw: out.is_rw,
2166                             is_indirect: out.is_indirect,
2167                         }
2168                     }).collect(),
2169                     asm: asm.asm.clone(),
2170                     asm_str_style: asm.asm_str_style,
2171                     clobbers: asm.clobbers.clone().into(),
2172                     volatile: asm.volatile,
2173                     alignstack: asm.alignstack,
2174                     dialect: asm.dialect,
2175                     ctxt: asm.ctxt,
2176                 };
2177                 let outputs =
2178                     asm.outputs.iter().map(|out| self.lower_expr(&out.expr)).collect();
2179                 let inputs =
2180                     asm.inputs.iter().map(|&(_, ref input)| self.lower_expr(input)).collect();
2181                 hir::ExprInlineAsm(P(hir_asm), outputs, inputs)
2182             }
2183             ExprKind::Struct(ref path, ref fields, ref maybe_expr) => {
2184                 hir::ExprStruct(self.lower_qpath(e.id, &None, path, ParamMode::Optional),
2185                                 fields.iter().map(|x| self.lower_field(x)).collect(),
2186                                 maybe_expr.as_ref().map(|x| P(self.lower_expr(x))))
2187             }
2188             ExprKind::Paren(ref ex) => {
2189                 let mut ex = self.lower_expr(ex);
2190                 // include parens in span, but only if it is a super-span.
2191                 if e.span.contains(ex.span) {
2192                     ex.span = e.span;
2193                 }
2194                 // merge attributes into the inner expression.
2195                 let mut attrs = e.attrs.clone();
2196                 attrs.extend::<Vec<_>>(ex.attrs.into());
2197                 ex.attrs = attrs;
2198                 return ex;
2199             }
2200
2201             ExprKind::Yield(ref opt_expr) => {
2202                 self.is_generator = true;
2203                 let expr = opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| {
2204                     self.expr(e.span, hir::ExprTup(hir_vec![]), ThinVec::new())
2205                 });
2206                 hir::ExprYield(P(expr))
2207             }
2208
2209             // Desugar ExprIfLet
2210             // From: `if let <pat> = <sub_expr> <body> [<else_opt>]`
2211             ExprKind::IfLet(ref pat, ref sub_expr, ref body, ref else_opt) => {
2212                 // to:
2213                 //
2214                 //   match <sub_expr> {
2215                 //     <pat> => <body>,
2216                 //     _ => [<else_opt> | ()]
2217                 //   }
2218
2219                 let mut arms = vec![];
2220
2221                 // `<pat> => <body>`
2222                 {
2223                     let body = self.lower_block(body, false);
2224                     let body_expr = P(self.expr_block(body, ThinVec::new()));
2225                     let pat = self.lower_pat(pat);
2226                     arms.push(self.arm(hir_vec![pat], body_expr));
2227                 }
2228
2229                 // _ => [<else_opt>|()]
2230                 {
2231                     let wildcard_arm: Option<&Expr> = else_opt.as_ref().map(|p| &**p);
2232                     let wildcard_pattern = self.pat_wild(e.span);
2233                     let body = if let Some(else_expr) = wildcard_arm {
2234                         P(self.lower_expr(else_expr))
2235                     } else {
2236                         self.expr_tuple(e.span, hir_vec![])
2237                     };
2238                     arms.push(self.arm(hir_vec![wildcard_pattern], body));
2239                 }
2240
2241                 let contains_else_clause = else_opt.is_some();
2242
2243                 let sub_expr = P(self.lower_expr(sub_expr));
2244
2245                 hir::ExprMatch(
2246                     sub_expr,
2247                     arms.into(),
2248                     hir::MatchSource::IfLetDesugar {
2249                         contains_else_clause,
2250                     })
2251             }
2252
2253             // Desugar ExprWhileLet
2254             // From: `[opt_ident]: while let <pat> = <sub_expr> <body>`
2255             ExprKind::WhileLet(ref pat, ref sub_expr, ref body, opt_ident) => {
2256                 // to:
2257                 //
2258                 //   [opt_ident]: loop {
2259                 //     match <sub_expr> {
2260                 //       <pat> => <body>,
2261                 //       _ => break
2262                 //     }
2263                 //   }
2264
2265                 // Note that the block AND the condition are evaluated in the loop scope.
2266                 // This is done to allow `break` from inside the condition of the loop.
2267                 let (body, break_expr, sub_expr) = self.with_loop_scope(e.id, |this| (
2268                     this.lower_block(body, false),
2269                     this.expr_break(e.span, ThinVec::new()),
2270                     this.with_loop_condition_scope(|this| P(this.lower_expr(sub_expr))),
2271                 ));
2272
2273                 // `<pat> => <body>`
2274                 let pat_arm = {
2275                     let body_expr = P(self.expr_block(body, ThinVec::new()));
2276                     let pat = self.lower_pat(pat);
2277                     self.arm(hir_vec![pat], body_expr)
2278                 };
2279
2280                 // `_ => break`
2281                 let break_arm = {
2282                     let pat_under = self.pat_wild(e.span);
2283                     self.arm(hir_vec![pat_under], break_expr)
2284                 };
2285
2286                 // `match <sub_expr> { ... }`
2287                 let arms = hir_vec![pat_arm, break_arm];
2288                 let match_expr = self.expr(e.span,
2289                                            hir::ExprMatch(sub_expr,
2290                                                           arms,
2291                                                           hir::MatchSource::WhileLetDesugar),
2292                                            ThinVec::new());
2293
2294                 // `[opt_ident]: loop { ... }`
2295                 let loop_block = P(self.block_expr(P(match_expr)));
2296                 let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident),
2297                                               hir::LoopSource::WhileLet);
2298                 // add attributes to the outer returned expr node
2299                 loop_expr
2300             }
2301
2302             // Desugar ExprForLoop
2303             // From: `[opt_ident]: for <pat> in <head> <body>`
2304             ExprKind::ForLoop(ref pat, ref head, ref body, opt_ident) => {
2305                 // to:
2306                 //
2307                 //   {
2308                 //     let result = match ::std::iter::IntoIterator::into_iter(<head>) {
2309                 //       mut iter => {
2310                 //         [opt_ident]: loop {
2311                 //           let mut __next;
2312                 //           match ::std::iter::Iterator::next(&mut iter) {
2313                 //             ::std::option::Option::Some(val) => __next = val,
2314                 //             ::std::option::Option::None => break
2315                 //           };
2316                 //           let <pat> = __next;
2317                 //           StmtExpr(<body>);
2318                 //         }
2319                 //       }
2320                 //     };
2321                 //     result
2322                 //   }
2323
2324                 // expand <head>
2325                 let head = self.lower_expr(head);
2326
2327                 let iter = self.str_to_ident("iter");
2328
2329                 let next_ident = self.str_to_ident("__next");
2330                 let next_pat = self.pat_ident_binding_mode(e.span,
2331                                                            next_ident,
2332                                                            hir::BindingAnnotation::Mutable);
2333
2334                 // `::std::option::Option::Some(val) => next = val`
2335                 let pat_arm = {
2336                     let val_ident = self.str_to_ident("val");
2337                     let val_pat = self.pat_ident(e.span, val_ident);
2338                     let val_expr = P(self.expr_ident(e.span, val_ident, val_pat.id));
2339                     let next_expr = P(self.expr_ident(e.span, next_ident, next_pat.id));
2340                     let assign = P(self.expr(e.span,
2341                                              hir::ExprAssign(next_expr, val_expr),
2342                                              ThinVec::new()));
2343                     let some_pat = self.pat_some(e.span, val_pat);
2344                     self.arm(hir_vec![some_pat], assign)
2345                 };
2346
2347                 // `::std::option::Option::None => break`
2348                 let break_arm = {
2349                     let break_expr = self.with_loop_scope(e.id, |this|
2350                         this.expr_break(e.span, ThinVec::new()));
2351                     let pat = self.pat_none(e.span);
2352                     self.arm(hir_vec![pat], break_expr)
2353                 };
2354
2355                 // `mut iter`
2356                 let iter_pat = self.pat_ident_binding_mode(e.span,
2357                                                            iter,
2358                                                            hir::BindingAnnotation::Mutable);
2359
2360                 // `match ::std::iter::Iterator::next(&mut iter) { ... }`
2361                 let match_expr = {
2362                     let iter = P(self.expr_ident(e.span, iter, iter_pat.id));
2363                     let ref_mut_iter = self.expr_mut_addr_of(e.span, iter);
2364                     let next_path = &["iter", "Iterator", "next"];
2365                     let next_path = P(self.expr_std_path(e.span, next_path, ThinVec::new()));
2366                     let next_expr = P(self.expr_call(e.span, next_path,
2367                                       hir_vec![ref_mut_iter]));
2368                     let arms = hir_vec![pat_arm, break_arm];
2369
2370                     P(self.expr(e.span,
2371                                 hir::ExprMatch(next_expr, arms,
2372                                                hir::MatchSource::ForLoopDesugar),
2373                                 ThinVec::new()))
2374                 };
2375                 let match_stmt = respan(e.span, hir::StmtExpr(match_expr, self.next_id().node_id));
2376
2377                 let next_expr = P(self.expr_ident(e.span, next_ident, next_pat.id));
2378
2379                 // `let mut __next`
2380                 let next_let = self.stmt_let_pat(e.span,
2381                     None,
2382                     next_pat,
2383                     hir::LocalSource::ForLoopDesugar);
2384
2385                 // `let <pat> = __next`
2386                 let pat = self.lower_pat(pat);
2387                 let pat_let = self.stmt_let_pat(e.span,
2388                     Some(next_expr),
2389                     pat,
2390                     hir::LocalSource::ForLoopDesugar);
2391
2392                 let body_block = self.with_loop_scope(e.id,
2393                                                         |this| this.lower_block(body, false));
2394                 let body_expr = P(self.expr_block(body_block, ThinVec::new()));
2395                 let body_stmt = respan(e.span, hir::StmtExpr(body_expr, self.next_id().node_id));
2396
2397                 let loop_block = P(self.block_all(e.span,
2398                                                   hir_vec![next_let,
2399                                                            match_stmt,
2400                                                            pat_let,
2401                                                            body_stmt],
2402                                                   None));
2403
2404                 // `[opt_ident]: loop { ... }`
2405                 let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident),
2406                                               hir::LoopSource::ForLoop);
2407                 let LoweredNodeId { node_id, hir_id } = self.lower_node_id(e.id);
2408                 let loop_expr = P(hir::Expr {
2409                     id: node_id,
2410                     hir_id,
2411                     node: loop_expr,
2412                     span: e.span,
2413                     attrs: ThinVec::new(),
2414                 });
2415
2416                 // `mut iter => { ... }`
2417                 let iter_arm = self.arm(hir_vec![iter_pat], loop_expr);
2418
2419                 // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
2420                 let into_iter_expr = {
2421                     let into_iter_path = &["iter", "IntoIterator", "into_iter"];
2422                     let into_iter = P(self.expr_std_path(e.span, into_iter_path,
2423                                                          ThinVec::new()));
2424                     P(self.expr_call(e.span, into_iter, hir_vec![head]))
2425                 };
2426
2427                 let match_expr = P(self.expr_match(e.span,
2428                                                    into_iter_expr,
2429                                                    hir_vec![iter_arm],
2430                                                    hir::MatchSource::ForLoopDesugar));
2431
2432                 // `{ let _result = ...; _result }`
2433                 // underscore prevents an unused_variables lint if the head diverges
2434                 let result_ident = self.str_to_ident("_result");
2435                 let (let_stmt, let_stmt_binding) =
2436                     self.stmt_let(e.span, false, result_ident, match_expr);
2437
2438                 let result = P(self.expr_ident(e.span, result_ident, let_stmt_binding));
2439                 let block = P(self.block_all(e.span, hir_vec![let_stmt], Some(result)));
2440                 // add the attributes to the outer returned expr node
2441                 return self.expr_block(block, e.attrs.clone());
2442             }
2443
2444             // Desugar ExprKind::Try
2445             // From: `<expr>?`
2446             ExprKind::Try(ref sub_expr) => {
2447                 // to:
2448                 //
2449                 // match Try::into_result(<expr>) {
2450                 //     Ok(val) => #[allow(unreachable_code)] val,
2451                 //     Err(err) => #[allow(unreachable_code)]
2452                 //                 // If there is an enclosing `catch {...}`
2453                 //                 break 'catch_target Try::from_error(From::from(err)),
2454                 //                 // Otherwise
2455                 //                 return Try::from_error(From::from(err)),
2456                 // }
2457
2458                 let unstable_span =
2459                     self.allow_internal_unstable(CompilerDesugaringKind::QuestionMark, e.span);
2460
2461                 // Try::into_result(<expr>)
2462                 let discr = {
2463                     // expand <expr>
2464                     let sub_expr = self.lower_expr(sub_expr);
2465
2466                     let path = &["ops", "Try", "into_result"];
2467                     let path = P(self.expr_std_path(unstable_span, path, ThinVec::new()));
2468                     P(self.expr_call(e.span, path, hir_vec![sub_expr]))
2469                 };
2470
2471                 // #[allow(unreachable_code)]
2472                 let attr = {
2473                     // allow(unreachable_code)
2474                     let allow = {
2475                         let allow_ident = self.str_to_ident("allow");
2476                         let uc_ident = self.str_to_ident("unreachable_code");
2477                         let uc_meta_item = attr::mk_spanned_word_item(e.span, uc_ident);
2478                         let uc_nested = NestedMetaItemKind::MetaItem(uc_meta_item);
2479                         let uc_spanned = respan(e.span, uc_nested);
2480                         attr::mk_spanned_list_item(e.span, allow_ident, vec![uc_spanned])
2481                     };
2482                     attr::mk_spanned_attr_outer(e.span, attr::mk_attr_id(), allow)
2483                 };
2484                 let attrs = vec![attr];
2485
2486                 // Ok(val) => #[allow(unreachable_code)] val,
2487                 let ok_arm = {
2488                     let val_ident = self.str_to_ident("val");
2489                     let val_pat = self.pat_ident(e.span, val_ident);
2490                     let val_expr = P(self.expr_ident_with_attrs(e.span,
2491                                                                 val_ident,
2492                                                                 val_pat.id,
2493                                                                 ThinVec::from(attrs.clone())));
2494                     let ok_pat = self.pat_ok(e.span, val_pat);
2495
2496                     self.arm(hir_vec![ok_pat], val_expr)
2497                 };
2498
2499                 // Err(err) => #[allow(unreachable_code)]
2500                 //             return Carrier::from_error(From::from(err)),
2501                 let err_arm = {
2502                     let err_ident = self.str_to_ident("err");
2503                     let err_local = self.pat_ident(e.span, err_ident);
2504                     let from_expr = {
2505                         let path = &["convert", "From", "from"];
2506                         let from = P(self.expr_std_path(e.span, path, ThinVec::new()));
2507                         let err_expr = self.expr_ident(e.span, err_ident, err_local.id);
2508
2509                         self.expr_call(e.span, from, hir_vec![err_expr])
2510                     };
2511                     let from_err_expr = {
2512                         let path = &["ops", "Try", "from_error"];
2513                         let from_err = P(self.expr_std_path(unstable_span, path,
2514                                                             ThinVec::new()));
2515                         P(self.expr_call(e.span, from_err, hir_vec![from_expr]))
2516                     };
2517
2518                     let thin_attrs = ThinVec::from(attrs);
2519                     let catch_scope = self.catch_scopes.last().map(|x| *x);
2520                     let ret_expr = if let Some(catch_node) = catch_scope {
2521                         P(self.expr(
2522                             e.span,
2523                             hir::ExprBreak(
2524                                 hir::Destination {
2525                                     ident: None,
2526                                     target_id: hir::ScopeTarget::Block(catch_node),
2527                                 },
2528                                 Some(from_err_expr)
2529                             ),
2530                             thin_attrs))
2531                     } else {
2532                         P(self.expr(e.span,
2533                                     hir::Expr_::ExprRet(Some(from_err_expr)),
2534                                     thin_attrs))
2535                     };
2536
2537
2538                     let err_pat = self.pat_err(e.span, err_local);
2539                     self.arm(hir_vec![err_pat], ret_expr)
2540                 };
2541
2542                 hir::ExprMatch(discr,
2543                                hir_vec![err_arm, ok_arm],
2544                                hir::MatchSource::TryDesugar)
2545             }
2546
2547             ExprKind::Mac(_) => panic!("Shouldn't exist here"),
2548         };
2549
2550         let LoweredNodeId { node_id, hir_id } = self.lower_node_id(e.id);
2551
2552         hir::Expr {
2553             id: node_id,
2554             hir_id,
2555             node: kind,
2556             span: e.span,
2557             attrs: e.attrs.clone(),
2558         }
2559     }
2560
2561     fn lower_stmt(&mut self, s: &Stmt) -> SmallVector<hir::Stmt> {
2562         SmallVector::one(match s.node {
2563             StmtKind::Local(ref l) => Spanned {
2564                 node: hir::StmtDecl(P(Spanned {
2565                     node: hir::DeclLocal(self.lower_local(l)),
2566                     span: s.span,
2567                 }), self.lower_node_id(s.id).node_id),
2568                 span: s.span,
2569             },
2570             StmtKind::Item(ref it) => {
2571                 // Can only use the ID once.
2572                 let mut id = Some(s.id);
2573                 return self.lower_item_id(it).into_iter().map(|item_id| Spanned {
2574                     node: hir::StmtDecl(P(Spanned {
2575                         node: hir::DeclItem(item_id),
2576                         span: s.span,
2577                     }), id.take()
2578                           .map(|id| self.lower_node_id(id).node_id)
2579                           .unwrap_or_else(|| self.next_id().node_id)),
2580                     span: s.span,
2581                 }).collect();
2582             }
2583             StmtKind::Expr(ref e) => {
2584                 Spanned {
2585                     node: hir::StmtExpr(P(self.lower_expr(e)),
2586                                           self.lower_node_id(s.id).node_id),
2587                     span: s.span,
2588                 }
2589             }
2590             StmtKind::Semi(ref e) => {
2591                 Spanned {
2592                     node: hir::StmtSemi(P(self.lower_expr(e)),
2593                                           self.lower_node_id(s.id).node_id),
2594                     span: s.span,
2595                 }
2596             }
2597             StmtKind::Mac(..) => panic!("Shouldn't exist here"),
2598         })
2599     }
2600
2601     fn lower_capture_clause(&mut self, c: CaptureBy) -> hir::CaptureClause {
2602         match c {
2603             CaptureBy::Value => hir::CaptureByValue,
2604             CaptureBy::Ref => hir::CaptureByRef,
2605         }
2606     }
2607
2608     /// If an `explicit_owner` is given, this method allocates the `HirId` in
2609     /// the address space of that item instead of the item currently being
2610     /// lowered. This can happen during `lower_impl_item_ref()` where we need to
2611     /// lower a `Visibility` value although we haven't lowered the owning
2612     /// `ImplItem` in question yet.
2613     fn lower_visibility(&mut self,
2614                         v: &Visibility,
2615                         explicit_owner: Option<NodeId>)
2616                         -> hir::Visibility {
2617         match *v {
2618             Visibility::Public => hir::Public,
2619             Visibility::Crate(_) => hir::Visibility::Crate,
2620             Visibility::Restricted { ref path, id } => {
2621                 hir::Visibility::Restricted {
2622                     path: P(self.lower_path(id, path, ParamMode::Explicit, true)),
2623                     id: if let Some(owner) = explicit_owner {
2624                         self.lower_node_id_with_owner(id, owner).node_id
2625                     } else {
2626                         self.lower_node_id(id).node_id
2627                     }
2628                 }
2629             }
2630             Visibility::Inherited => hir::Inherited,
2631         }
2632     }
2633
2634     fn lower_defaultness(&mut self, d: Defaultness, has_value: bool) -> hir::Defaultness {
2635         match d {
2636             Defaultness::Default => hir::Defaultness::Default { has_value: has_value },
2637             Defaultness::Final => {
2638                 assert!(has_value);
2639                 hir::Defaultness::Final
2640             }
2641         }
2642     }
2643
2644     fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode {
2645         match *b {
2646             BlockCheckMode::Default => hir::DefaultBlock,
2647             BlockCheckMode::Unsafe(u) => hir::UnsafeBlock(self.lower_unsafe_source(u)),
2648         }
2649     }
2650
2651     fn lower_binding_mode(&mut self, b: &BindingMode) -> hir::BindingAnnotation {
2652         match *b {
2653             BindingMode::ByValue(Mutability::Immutable) =>
2654                 hir::BindingAnnotation::Unannotated,
2655             BindingMode::ByRef(Mutability::Immutable) => hir::BindingAnnotation::Ref,
2656             BindingMode::ByValue(Mutability::Mutable) => hir::BindingAnnotation::Mutable,
2657             BindingMode::ByRef(Mutability::Mutable) => hir::BindingAnnotation::RefMut,
2658         }
2659     }
2660
2661     fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
2662         match u {
2663             CompilerGenerated => hir::CompilerGenerated,
2664             UserProvided => hir::UserProvided,
2665         }
2666     }
2667
2668     fn lower_impl_polarity(&mut self, i: ImplPolarity) -> hir::ImplPolarity {
2669         match i {
2670             ImplPolarity::Positive => hir::ImplPolarity::Positive,
2671             ImplPolarity::Negative => hir::ImplPolarity::Negative,
2672         }
2673     }
2674
2675     fn lower_trait_bound_modifier(&mut self, f: TraitBoundModifier) -> hir::TraitBoundModifier {
2676         match f {
2677             TraitBoundModifier::None => hir::TraitBoundModifier::None,
2678             TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe,
2679         }
2680     }
2681
2682     // Helper methods for building HIR.
2683
2684     fn arm(&mut self, pats: hir::HirVec<P<hir::Pat>>, expr: P<hir::Expr>) -> hir::Arm {
2685         hir::Arm {
2686             attrs: hir_vec![],
2687             pats,
2688             guard: None,
2689             body: expr,
2690         }
2691     }
2692
2693     fn field(&mut self, name: Name, expr: P<hir::Expr>, span: Span) -> hir::Field {
2694         hir::Field {
2695             name: Spanned {
2696                 node: name,
2697                 span,
2698             },
2699             span,
2700             expr,
2701             is_shorthand: false,
2702         }
2703     }
2704
2705     fn expr_break(&mut self, span: Span, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
2706         let expr_break = hir::ExprBreak(self.lower_loop_destination(None), None);
2707         P(self.expr(span, expr_break, attrs))
2708     }
2709
2710     fn expr_call(&mut self, span: Span, e: P<hir::Expr>, args: hir::HirVec<hir::Expr>)
2711                  -> hir::Expr {
2712         self.expr(span, hir::ExprCall(e, args), ThinVec::new())
2713     }
2714
2715     fn expr_ident(&mut self, span: Span, id: Name, binding: NodeId) -> hir::Expr {
2716         self.expr_ident_with_attrs(span, id, binding, ThinVec::new())
2717     }
2718
2719     fn expr_ident_with_attrs(&mut self, span: Span,
2720                                         id: Name,
2721                                         binding: NodeId,
2722                                         attrs: ThinVec<Attribute>) -> hir::Expr {
2723         let expr_path = hir::ExprPath(hir::QPath::Resolved(None, P(hir::Path {
2724             span,
2725             def: Def::Local(binding),
2726             segments: hir_vec![hir::PathSegment::from_name(id)],
2727         })));
2728
2729         self.expr(span, expr_path, attrs)
2730     }
2731
2732     fn expr_mut_addr_of(&mut self, span: Span, e: P<hir::Expr>) -> hir::Expr {
2733         self.expr(span, hir::ExprAddrOf(hir::MutMutable, e), ThinVec::new())
2734     }
2735
2736     fn expr_std_path(&mut self,
2737                      span: Span,
2738                      components: &[&str],
2739                      attrs: ThinVec<Attribute>)
2740                      -> hir::Expr {
2741         let path = self.std_path(span, components, true);
2742         self.expr(span, hir::ExprPath(hir::QPath::Resolved(None, P(path))), attrs)
2743     }
2744
2745     fn expr_match(&mut self,
2746                   span: Span,
2747                   arg: P<hir::Expr>,
2748                   arms: hir::HirVec<hir::Arm>,
2749                   source: hir::MatchSource)
2750                   -> hir::Expr {
2751         self.expr(span, hir::ExprMatch(arg, arms, source), ThinVec::new())
2752     }
2753
2754     fn expr_block(&mut self, b: P<hir::Block>, attrs: ThinVec<Attribute>) -> hir::Expr {
2755         self.expr(b.span, hir::ExprBlock(b), attrs)
2756     }
2757
2758     fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec<hir::Expr>) -> P<hir::Expr> {
2759         P(self.expr(sp, hir::ExprTup(exprs), ThinVec::new()))
2760     }
2761
2762     fn expr(&mut self, span: Span, node: hir::Expr_, attrs: ThinVec<Attribute>) -> hir::Expr {
2763         let LoweredNodeId { node_id, hir_id } = self.next_id();
2764         hir::Expr {
2765             id: node_id,
2766             hir_id,
2767             node,
2768             span,
2769             attrs,
2770         }
2771     }
2772
2773     fn stmt_let_pat(&mut self,
2774                     sp: Span,
2775                     ex: Option<P<hir::Expr>>,
2776                     pat: P<hir::Pat>,
2777                     source: hir::LocalSource)
2778                     -> hir::Stmt {
2779         let LoweredNodeId { node_id, hir_id } = self.next_id();
2780
2781         let local = P(hir::Local {
2782             pat,
2783             ty: None,
2784             init: ex,
2785             id: node_id,
2786             hir_id,
2787             span: sp,
2788             attrs: ThinVec::new(),
2789             source,
2790         });
2791         let decl = respan(sp, hir::DeclLocal(local));
2792         respan(sp, hir::StmtDecl(P(decl), self.next_id().node_id))
2793     }
2794
2795     fn stmt_let(&mut self, sp: Span, mutbl: bool, ident: Name, ex: P<hir::Expr>)
2796                 -> (hir::Stmt, NodeId) {
2797         let pat = if mutbl {
2798             self.pat_ident_binding_mode(sp, ident, hir::BindingAnnotation::Mutable)
2799         } else {
2800             self.pat_ident(sp, ident)
2801         };
2802         let pat_id = pat.id;
2803         (self.stmt_let_pat(sp, Some(ex), pat, hir::LocalSource::Normal), pat_id)
2804     }
2805
2806     fn block_expr(&mut self, expr: P<hir::Expr>) -> hir::Block {
2807         self.block_all(expr.span, hir::HirVec::new(), Some(expr))
2808     }
2809
2810     fn block_all(&mut self, span: Span, stmts: hir::HirVec<hir::Stmt>, expr: Option<P<hir::Expr>>)
2811                  -> hir::Block {
2812         let LoweredNodeId { node_id, hir_id } = self.next_id();
2813
2814         hir::Block {
2815             stmts,
2816             expr,
2817             id: node_id,
2818             hir_id,
2819             rules: hir::DefaultBlock,
2820             span,
2821             targeted_by_break: false,
2822         }
2823     }
2824
2825     fn pat_ok(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
2826         self.pat_std_enum(span, &["result", "Result", "Ok"], hir_vec![pat])
2827     }
2828
2829     fn pat_err(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
2830         self.pat_std_enum(span, &["result", "Result", "Err"], hir_vec![pat])
2831     }
2832
2833     fn pat_some(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
2834         self.pat_std_enum(span, &["option", "Option", "Some"], hir_vec![pat])
2835     }
2836
2837     fn pat_none(&mut self, span: Span) -> P<hir::Pat> {
2838         self.pat_std_enum(span, &["option", "Option", "None"], hir_vec![])
2839     }
2840
2841     fn pat_std_enum(&mut self,
2842                     span: Span,
2843                     components: &[&str],
2844                     subpats: hir::HirVec<P<hir::Pat>>)
2845                     -> P<hir::Pat> {
2846         let path = self.std_path(span, components, true);
2847         let qpath = hir::QPath::Resolved(None, P(path));
2848         let pt = if subpats.is_empty() {
2849             hir::PatKind::Path(qpath)
2850         } else {
2851             hir::PatKind::TupleStruct(qpath, subpats, None)
2852         };
2853         self.pat(span, pt)
2854     }
2855
2856     fn pat_ident(&mut self, span: Span, name: Name) -> P<hir::Pat> {
2857         self.pat_ident_binding_mode(span, name, hir::BindingAnnotation::Unannotated)
2858     }
2859
2860     fn pat_ident_binding_mode(&mut self, span: Span, name: Name, bm: hir::BindingAnnotation)
2861                               -> P<hir::Pat> {
2862         let LoweredNodeId { node_id, hir_id } = self.next_id();
2863
2864         P(hir::Pat {
2865             id: node_id,
2866             hir_id,
2867             node: hir::PatKind::Binding(bm,
2868                                         node_id,
2869                                         Spanned {
2870                                             span,
2871                                             node: name,
2872                                         },
2873                                         None),
2874             span,
2875         })
2876     }
2877
2878     fn pat_wild(&mut self, span: Span) -> P<hir::Pat> {
2879         self.pat(span, hir::PatKind::Wild)
2880     }
2881
2882     fn pat(&mut self, span: Span, pat: hir::PatKind) -> P<hir::Pat> {
2883         let LoweredNodeId { node_id, hir_id } = self.next_id();
2884         P(hir::Pat {
2885             id: node_id,
2886             hir_id,
2887             node: pat,
2888             span,
2889         })
2890     }
2891
2892     /// Given suffix ["b","c","d"], returns path `::std::b::c::d` when
2893     /// `fld.cx.use_std`, and `::core::b::c::d` otherwise.
2894     /// The path is also resolved according to `is_value`.
2895     fn std_path(&mut self, span: Span, components: &[&str], is_value: bool) -> hir::Path {
2896         let mut path = hir::Path {
2897             span,
2898             def: Def::Err,
2899             segments: iter::once(keywords::CrateRoot.name()).chain({
2900                 self.crate_root.into_iter().chain(components.iter().cloned()).map(Symbol::intern)
2901             }).map(hir::PathSegment::from_name).collect(),
2902         };
2903
2904         self.resolver.resolve_hir_path(&mut path, is_value);
2905         path
2906     }
2907
2908     fn signal_block_expr(&mut self,
2909                          stmts: hir::HirVec<hir::Stmt>,
2910                          expr: P<hir::Expr>,
2911                          span: Span,
2912                          rule: hir::BlockCheckMode,
2913                          attrs: ThinVec<Attribute>)
2914                          -> hir::Expr {
2915         let LoweredNodeId { node_id, hir_id } = self.next_id();
2916
2917         let block = P(hir::Block {
2918             rules: rule,
2919             span,
2920             id: node_id,
2921             hir_id,
2922             stmts,
2923             expr: Some(expr),
2924             targeted_by_break: false,
2925         });
2926         self.expr_block(block, attrs)
2927     }
2928
2929     fn ty_path(&mut self, id: NodeId, span: Span, qpath: hir::QPath) -> P<hir::Ty> {
2930         let mut id = id;
2931         let node = match qpath {
2932             hir::QPath::Resolved(None, path) => {
2933                 // Turn trait object paths into `TyTraitObject` instead.
2934                 if let Def::Trait(_) = path.def {
2935                     let principal = hir::PolyTraitRef {
2936                         bound_lifetimes: hir_vec![],
2937                         trait_ref: hir::TraitRef {
2938                             path: path.and_then(|path| path),
2939                             ref_id: id,
2940                         },
2941                         span,
2942                     };
2943
2944                     // The original ID is taken by the `PolyTraitRef`,
2945                     // so the `Ty` itself needs a different one.
2946                     id = self.next_id().node_id;
2947
2948                     hir::TyTraitObject(hir_vec![principal], self.elided_lifetime(span))
2949                 } else {
2950                     hir::TyPath(hir::QPath::Resolved(None, path))
2951                 }
2952             }
2953             _ => hir::TyPath(qpath)
2954         };
2955         P(hir::Ty { id, node, span })
2956     }
2957
2958     fn elided_lifetime(&mut self, span: Span) -> hir::Lifetime {
2959         hir::Lifetime {
2960             id: self.next_id().node_id,
2961             span,
2962             name: keywords::Invalid.name()
2963         }
2964     }
2965 }
2966
2967 fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body>) -> Vec<hir::BodyId> {
2968     // Sorting by span ensures that we get things in order within a
2969     // file, and also puts the files in a sensible order.
2970     let mut body_ids: Vec<_> = bodies.keys().cloned().collect();
2971     body_ids.sort_by_key(|b| bodies[b].value.span);
2972     body_ids
2973 }