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