]> git.lizzy.rs Git - rust.git/blob - src/librustc/hir/lowering.rs
Auto merge of #51549 - PSeitz:patch-1, r=kennytm
[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::HirVec;
46 use hir::map::{DefKey, DefPathData, Definitions};
47 use hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CRATE_DEF_INDEX};
48 use hir::def::{Def, PathResolution, PerNS};
49 use lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES};
50 use middle::cstore::CrateStore;
51 use rustc_data_structures::indexed_vec::IndexVec;
52 use session::Session;
53 use util::common::FN_OUTPUT_NAME;
54 use util::nodemap::{DefIdMap, FxHashMap, NodeMap};
55
56 use std::collections::{BTreeMap, HashSet};
57 use std::fmt::Debug;
58 use std::iter;
59 use std::mem;
60 use syntax::attr;
61 use syntax::ast::*;
62 use syntax::errors;
63 use syntax::ext::hygiene::{Mark, SyntaxContext};
64 use syntax::print::pprust;
65 use syntax::ptr::P;
66 use syntax::codemap::{self, respan, CompilerDesugaringKind, Spanned};
67 use syntax::std_inject;
68 use syntax::symbol::{keywords, Symbol};
69 use syntax::tokenstream::{Delimited, TokenStream, TokenTree};
70 use syntax::parse::token::Token;
71 use syntax::util::small_vector::SmallVector;
72 use syntax::visit::{self, Visitor};
73 use syntax_pos::Span;
74
75 const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF;
76
77 pub struct LoweringContext<'a> {
78     crate_root: Option<&'static str>,
79
80     // Use to assign ids to hir nodes that do not directly correspond to an ast node
81     sess: &'a Session,
82
83     cstore: &'a CrateStore,
84
85     resolver: &'a mut Resolver,
86     name_map: FxHashMap<Ident, Name>,
87
88     /// The items being lowered are collected here.
89     items: BTreeMap<NodeId, hir::Item>,
90
91     trait_items: BTreeMap<hir::TraitItemId, hir::TraitItem>,
92     impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>,
93     bodies: BTreeMap<hir::BodyId, hir::Body>,
94     exported_macros: Vec<hir::MacroDef>,
95
96     trait_impls: BTreeMap<DefId, Vec<NodeId>>,
97     trait_auto_impl: BTreeMap<DefId, NodeId>,
98
99     is_generator: bool,
100
101     catch_scopes: Vec<NodeId>,
102     loop_scopes: Vec<NodeId>,
103     is_in_loop_condition: bool,
104     is_in_trait_impl: bool,
105
106     /// What to do when we encounter either an "anonymous lifetime
107     /// reference". The term "anonymous" is meant to encompass both
108     /// `'_` lifetimes as well as fully elided cases where nothing is
109     /// written at all (e.g., `&T` or `std::cell::Ref<T>`).
110     anonymous_lifetime_mode: AnonymousLifetimeMode,
111
112     // This is a list of in-band type definitions being generated by
113     // Argument-position `impl Trait`.
114     // When traversing a signature such as `fn foo(x: impl Trait)`,
115     // we record `impl Trait` as a new type parameter, then later
116     // add it on to `foo`s generics.
117     in_band_ty_params: Vec<hir::TyParam>,
118
119     // Used to create lifetime definitions from in-band lifetime usages.
120     // e.g. `fn foo(x: &'x u8) -> &'x u8` to `fn foo<'x>(x: &'x u8) -> &'x u8`
121     // When a named lifetime is encountered in a function or impl header and
122     // has not been defined
123     // (i.e. it doesn't appear in the in_scope_lifetimes list), it is added
124     // to this list. The results of this list are then added to the list of
125     // lifetime definitions in the corresponding impl or function generics.
126     lifetimes_to_define: Vec<(Span, hir::LifetimeName)>,
127
128     // Whether or not in-band lifetimes are being collected. This is used to
129     // indicate whether or not we're in a place where new lifetimes will result
130     // in in-band lifetime definitions, such a function or an impl header.
131     // This will always be false unless the `in_band_lifetimes` feature is
132     // enabled.
133     is_collecting_in_band_lifetimes: bool,
134
135     // Currently in-scope lifetimes defined in impl headers, fn headers, or HRTB.
136     // When `is_collectin_in_band_lifetimes` is true, each lifetime is checked
137     // against this list to see if it is already in-scope, or if a definition
138     // needs to be created for it.
139     in_scope_lifetimes: Vec<Name>,
140
141     type_def_lifetime_params: DefIdMap<usize>,
142
143     current_hir_id_owner: Vec<(DefIndex, u32)>,
144     item_local_id_counters: NodeMap<u32>,
145     node_id_to_hir_id: IndexVec<NodeId, hir::HirId>,
146 }
147
148 pub trait Resolver {
149     /// Resolve a hir path generated by the lowerer when expanding `for`, `if let`, etc.
150     fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool);
151
152     /// Obtain the resolution for a node id
153     fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution>;
154
155     /// Obtain the possible resolutions for the given `use` statement.
156     fn get_import(&mut self, id: NodeId) -> PerNS<Option<PathResolution>>;
157
158     /// We must keep the set of definitions up to date as we add nodes that weren't in the AST.
159     /// This should only return `None` during testing.
160     fn definitions(&mut self) -> &mut Definitions;
161
162     /// Given suffix ["b","c","d"], creates a HIR path for `[::crate_root]::b::c::d` and resolves
163     /// it based on `is_value`.
164     fn resolve_str_path(
165         &mut self,
166         span: Span,
167         crate_root: Option<&str>,
168         components: &[&str],
169         is_value: bool,
170     ) -> hir::Path;
171 }
172
173 #[derive(Clone, Copy, Debug)]
174 enum ImplTraitContext {
175     /// Treat `impl Trait` as shorthand for a new universal generic parameter.
176     /// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually
177     /// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.
178     ///
179     /// We store a DefId here so we can look up necessary information later
180     Universal(DefId),
181
182     /// Treat `impl Trait` as shorthand for a new universal existential parameter.
183     /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
184     /// equivalent to a fresh existential parameter like `abstract type T; fn foo() -> T`.
185     Existential,
186
187     /// `impl Trait` is not accepted in this position.
188     Disallowed,
189 }
190
191 pub fn lower_crate(
192     sess: &Session,
193     cstore: &CrateStore,
194     dep_graph: &DepGraph,
195     krate: &Crate,
196     resolver: &mut Resolver,
197 ) -> hir::Crate {
198     // We're constructing the HIR here; we don't care what we will
199     // read, since we haven't even constructed the *input* to
200     // incr. comp. yet.
201     dep_graph.assert_ignored();
202
203     LoweringContext {
204         crate_root: std_inject::injected_crate_name(),
205         sess,
206         cstore,
207         resolver,
208         name_map: FxHashMap(),
209         items: BTreeMap::new(),
210         trait_items: BTreeMap::new(),
211         impl_items: BTreeMap::new(),
212         bodies: BTreeMap::new(),
213         trait_impls: BTreeMap::new(),
214         trait_auto_impl: BTreeMap::new(),
215         exported_macros: Vec::new(),
216         catch_scopes: Vec::new(),
217         loop_scopes: Vec::new(),
218         is_in_loop_condition: false,
219         anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
220         type_def_lifetime_params: DefIdMap(),
221         current_hir_id_owner: vec![(CRATE_DEF_INDEX, 0)],
222         item_local_id_counters: NodeMap(),
223         node_id_to_hir_id: IndexVec::new(),
224         is_generator: false,
225         is_in_trait_impl: false,
226         in_band_ty_params: Vec::new(),
227         lifetimes_to_define: Vec::new(),
228         is_collecting_in_band_lifetimes: false,
229         in_scope_lifetimes: Vec::new(),
230     }.lower_crate(krate)
231 }
232
233 #[derive(Copy, Clone, PartialEq, Eq)]
234 enum ParamMode {
235     /// Any path in a type context.
236     Explicit,
237     /// The `module::Type` in `module::Type::method` in an expression.
238     Optional,
239 }
240
241 struct LoweredNodeId {
242     node_id: NodeId,
243     hir_id: hir::HirId,
244 }
245
246 enum ParenthesizedGenericArgs {
247     Ok,
248     Warn,
249     Err,
250 }
251
252 /// What to do when we encounter an **anonymous** lifetime
253 /// reference. Anonymous lifetime references come in two flavors.  You
254 /// have implicit, or fully elided, references to lifetimes, like the
255 /// one in `&T` or `Ref<T>`, and you have `'_` lifetimes, like `&'_ T`
256 /// or `Ref<'_, T>`.  These often behave the same, but not always:
257 ///
258 /// - certain usages of implicit references are deprecated, like
259 ///   `Ref<T>`, and we sometimes just give hard errors in those cases
260 ///   as well.
261 /// - for object bounds there is a difference: `Box<dyn Foo>` is not
262 ///   the same as `Box<dyn Foo + '_>`.
263 ///
264 /// We describe the effects of the various modes in terms of three cases:
265 ///
266 /// - **Modern** -- includes all uses of `'_`, but also the lifetime arg
267 ///   of a `&` (e.g., the missing lifetime in something like `&T`)
268 /// - **Dyn Bound** -- if you have something like `Box<dyn Foo>`,
269 ///   there is an elided lifetime bound (`Box<dyn Foo + 'X>`). These
270 ///   elided bounds follow special rules. Note that this only covers
271 ///   cases where *nothing* is written; the `'_` in `Box<dyn Foo +
272 ///   '_>` is a case of "modern" elision.
273 /// - **Deprecated** -- this coverse cases like `Ref<T>`, where the lifetime
274 ///   parameter to ref is completely elided. `Ref<'_, T>` would be the modern,
275 ///   non-deprecated equivalent.
276 ///
277 /// Currently, the handling of lifetime elision is somewhat spread out
278 /// between HIR lowering and -- as described below -- the
279 /// `resolve_lifetime` module. Often we "fallthrough" to that code by generating
280 /// an "elided" or "underscore" lifetime name. In the future, we probably want to move
281 /// everything into HIR lowering.
282 #[derive(Copy, Clone)]
283 enum AnonymousLifetimeMode {
284     /// For **Modern** cases, create a new anonymous region parameter
285     /// and reference that.
286     ///
287     /// For **Dyn Bound** cases, pass responsibility to
288     /// `resolve_lifetime` code.
289     ///
290     /// For **Deprecated** cases, report an error.
291     CreateParameter,
292
293     /// Pass responsibility to `resolve_lifetime` code for all cases.
294     PassThrough,
295 }
296
297 impl<'a> LoweringContext<'a> {
298     fn lower_crate(mut self, c: &Crate) -> hir::Crate {
299         /// Full-crate AST visitor that inserts into a fresh
300         /// `LoweringContext` any information that may be
301         /// needed from arbitrary locations in the crate.
302         /// E.g. The number of lifetime generic parameters
303         /// declared for every type and trait definition.
304         struct MiscCollector<'lcx, 'interner: 'lcx> {
305             lctx: &'lcx mut LoweringContext<'interner>,
306         }
307
308         impl<'lcx, 'interner> Visitor<'lcx> for MiscCollector<'lcx, 'interner> {
309             fn visit_item(&mut self, item: &'lcx Item) {
310                 self.lctx.allocate_hir_id_counter(item.id, item);
311
312                 match item.node {
313                     ItemKind::Struct(_, ref generics)
314                     | ItemKind::Union(_, ref generics)
315                     | ItemKind::Enum(_, ref generics)
316                     | ItemKind::Ty(_, ref generics)
317                     | ItemKind::Trait(_, _, ref generics, ..) => {
318                         let def_id = self.lctx.resolver.definitions().local_def_id(item.id);
319                         let count = generics
320                             .params
321                             .iter()
322                             .filter(|param| param.is_lifetime_param())
323                             .count();
324                         self.lctx.type_def_lifetime_params.insert(def_id, count);
325                     }
326                     _ => {}
327                 }
328                 visit::walk_item(self, item);
329             }
330
331             fn visit_trait_item(&mut self, item: &'lcx TraitItem) {
332                 self.lctx.allocate_hir_id_counter(item.id, item);
333                 visit::walk_trait_item(self, item);
334             }
335
336             fn visit_impl_item(&mut self, item: &'lcx ImplItem) {
337                 self.lctx.allocate_hir_id_counter(item.id, item);
338                 visit::walk_impl_item(self, item);
339             }
340         }
341
342         struct ItemLowerer<'lcx, 'interner: 'lcx> {
343             lctx: &'lcx mut LoweringContext<'interner>,
344         }
345
346         impl<'lcx, 'interner> ItemLowerer<'lcx, 'interner> {
347             fn with_trait_impl_ref<F>(&mut self, trait_impl_ref: &Option<TraitRef>, f: F)
348             where
349                 F: FnOnce(&mut Self),
350             {
351                 let old = self.lctx.is_in_trait_impl;
352                 self.lctx.is_in_trait_impl = if let &None = trait_impl_ref {
353                     false
354                 } else {
355                     true
356                 };
357                 f(self);
358                 self.lctx.is_in_trait_impl = old;
359             }
360         }
361
362         impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> {
363             fn visit_item(&mut self, item: &'lcx Item) {
364                 let mut item_lowered = true;
365                 self.lctx.with_hir_id_owner(item.id, |lctx| {
366                     if let Some(hir_item) = lctx.lower_item(item) {
367                         lctx.items.insert(item.id, hir_item);
368                     } else {
369                         item_lowered = false;
370                     }
371                 });
372
373                 if item_lowered {
374                     let item_lifetimes = match self.lctx.items.get(&item.id).unwrap().node {
375                         hir::Item_::ItemImpl(_, _, _, ref generics, ..)
376                         | hir::Item_::ItemTrait(_, _, ref generics, ..) => {
377                             generics.lifetimes().cloned().collect::<Vec<_>>()
378                         }
379                         _ => Vec::new(),
380                     };
381
382                     self.lctx
383                         .with_parent_impl_lifetime_defs(&item_lifetimes, |this| {
384                             let this = &mut ItemLowerer { lctx: this };
385                             if let ItemKind::Impl(_, _, _, _, ref opt_trait_ref, _, _) = item.node {
386                                 this.with_trait_impl_ref(opt_trait_ref, |this| {
387                                     visit::walk_item(this, item)
388                                 });
389                             } else {
390                                 visit::walk_item(this, item);
391                             }
392                         });
393                 }
394             }
395
396             fn visit_trait_item(&mut self, item: &'lcx TraitItem) {
397                 self.lctx.with_hir_id_owner(item.id, |lctx| {
398                     let id = hir::TraitItemId { node_id: item.id };
399                     let hir_item = lctx.lower_trait_item(item);
400                     lctx.trait_items.insert(id, hir_item);
401                 });
402
403                 visit::walk_trait_item(self, item);
404             }
405
406             fn visit_impl_item(&mut self, item: &'lcx ImplItem) {
407                 self.lctx.with_hir_id_owner(item.id, |lctx| {
408                     let id = hir::ImplItemId { node_id: item.id };
409                     let hir_item = lctx.lower_impl_item(item);
410                     lctx.impl_items.insert(id, hir_item);
411                 });
412                 visit::walk_impl_item(self, item);
413             }
414         }
415
416         self.lower_node_id(CRATE_NODE_ID);
417         debug_assert!(self.node_id_to_hir_id[CRATE_NODE_ID] == hir::CRATE_HIR_ID);
418
419         visit::walk_crate(&mut MiscCollector { lctx: &mut self }, c);
420         visit::walk_crate(&mut ItemLowerer { lctx: &mut self }, c);
421
422         let module = self.lower_mod(&c.module);
423         let attrs = self.lower_attrs(&c.attrs);
424         let body_ids = body_ids(&self.bodies);
425
426         self.resolver
427             .definitions()
428             .init_node_id_to_hir_id_mapping(self.node_id_to_hir_id);
429
430         hir::Crate {
431             module,
432             attrs,
433             span: c.span,
434             exported_macros: hir::HirVec::from(self.exported_macros),
435             items: self.items,
436             trait_items: self.trait_items,
437             impl_items: self.impl_items,
438             bodies: self.bodies,
439             body_ids,
440             trait_impls: self.trait_impls,
441             trait_auto_impl: self.trait_auto_impl,
442         }
443     }
444
445     fn allocate_hir_id_counter<T: Debug>(&mut self, owner: NodeId, debug: &T) {
446         if self.item_local_id_counters.insert(owner, 0).is_some() {
447             bug!(
448                 "Tried to allocate item_local_id_counter for {:?} twice",
449                 debug
450             );
451         }
452         // Always allocate the first HirId for the owner itself
453         self.lower_node_id_with_owner(owner, owner);
454     }
455
456     fn lower_node_id_generic<F>(&mut self, ast_node_id: NodeId, alloc_hir_id: F) -> LoweredNodeId
457     where
458         F: FnOnce(&mut Self) -> hir::HirId,
459     {
460         if ast_node_id == DUMMY_NODE_ID {
461             return LoweredNodeId {
462                 node_id: DUMMY_NODE_ID,
463                 hir_id: hir::DUMMY_HIR_ID,
464             };
465         }
466
467         let min_size = ast_node_id.as_usize() + 1;
468
469         if min_size > self.node_id_to_hir_id.len() {
470             self.node_id_to_hir_id.resize(min_size, hir::DUMMY_HIR_ID);
471         }
472
473         let existing_hir_id = self.node_id_to_hir_id[ast_node_id];
474
475         if existing_hir_id == hir::DUMMY_HIR_ID {
476             // Generate a new HirId
477             let hir_id = alloc_hir_id(self);
478             self.node_id_to_hir_id[ast_node_id] = hir_id;
479             LoweredNodeId {
480                 node_id: ast_node_id,
481                 hir_id,
482             }
483         } else {
484             LoweredNodeId {
485                 node_id: ast_node_id,
486                 hir_id: existing_hir_id,
487             }
488         }
489     }
490
491     fn with_hir_id_owner<F>(&mut self, owner: NodeId, f: F)
492     where
493         F: FnOnce(&mut Self),
494     {
495         let counter = self.item_local_id_counters
496             .insert(owner, HIR_ID_COUNTER_LOCKED)
497             .unwrap();
498         let def_index = self.resolver.definitions().opt_def_index(owner).unwrap();
499         self.current_hir_id_owner.push((def_index, counter));
500         f(self);
501         let (new_def_index, new_counter) = self.current_hir_id_owner.pop().unwrap();
502
503         debug_assert!(def_index == new_def_index);
504         debug_assert!(new_counter >= counter);
505
506         let prev = self.item_local_id_counters
507             .insert(owner, new_counter)
508             .unwrap();
509         debug_assert!(prev == HIR_ID_COUNTER_LOCKED);
510     }
511
512     /// This method allocates a new HirId for the given NodeId and stores it in
513     /// the LoweringContext's NodeId => HirId map.
514     /// Take care not to call this method if the resulting HirId is then not
515     /// actually used in the HIR, as that would trigger an assertion in the
516     /// HirIdValidator later on, which makes sure that all NodeIds got mapped
517     /// properly. Calling the method twice with the same NodeId is fine though.
518     fn lower_node_id(&mut self, ast_node_id: NodeId) -> LoweredNodeId {
519         self.lower_node_id_generic(ast_node_id, |this| {
520             let &mut (def_index, ref mut local_id_counter) =
521                 this.current_hir_id_owner.last_mut().unwrap();
522             let local_id = *local_id_counter;
523             *local_id_counter += 1;
524             hir::HirId {
525                 owner: def_index,
526                 local_id: hir::ItemLocalId(local_id),
527             }
528         })
529     }
530
531     fn lower_node_id_with_owner(&mut self, ast_node_id: NodeId, owner: NodeId) -> LoweredNodeId {
532         self.lower_node_id_generic(ast_node_id, |this| {
533             let local_id_counter = this.item_local_id_counters.get_mut(&owner).unwrap();
534             let local_id = *local_id_counter;
535
536             // We want to be sure not to modify the counter in the map while it
537             // is also on the stack. Otherwise we'll get lost updates when writing
538             // back from the stack to the map.
539             debug_assert!(local_id != HIR_ID_COUNTER_LOCKED);
540
541             *local_id_counter += 1;
542             let def_index = this.resolver.definitions().opt_def_index(owner).unwrap();
543
544             hir::HirId {
545                 owner: def_index,
546                 local_id: hir::ItemLocalId(local_id),
547             }
548         })
549     }
550
551     fn record_body(&mut self, value: hir::Expr, decl: Option<&FnDecl>) -> hir::BodyId {
552         let body = hir::Body {
553             arguments: decl.map_or(hir_vec![], |decl| {
554                 decl.inputs.iter().map(|x| self.lower_arg(x)).collect()
555             }),
556             is_generator: self.is_generator,
557             value,
558         };
559         let id = body.id();
560         self.bodies.insert(id, body);
561         id
562     }
563
564     fn next_id(&mut self) -> LoweredNodeId {
565         self.lower_node_id(self.sess.next_node_id())
566     }
567
568     fn expect_full_def(&mut self, id: NodeId) -> Def {
569         self.resolver.get_resolution(id).map_or(Def::Err, |pr| {
570             if pr.unresolved_segments() != 0 {
571                 bug!("path not fully resolved: {:?}", pr);
572             }
573             pr.base_def()
574         })
575     }
576
577     fn expect_full_def_from_use(&mut self, id: NodeId) -> impl Iterator<Item=Def> {
578         self.resolver.get_import(id).present_items().map(|pr| {
579             if pr.unresolved_segments() != 0 {
580                 bug!("path not fully resolved: {:?}", pr);
581             }
582             pr.base_def()
583         })
584     }
585
586     fn diagnostic(&self) -> &errors::Handler {
587         self.sess.diagnostic()
588     }
589
590     fn str_to_ident(&self, s: &'static str) -> Name {
591         Symbol::gensym(s)
592     }
593
594     fn allow_internal_unstable(&self, reason: CompilerDesugaringKind, span: Span) -> Span {
595         let mark = Mark::fresh(Mark::root());
596         mark.set_expn_info(codemap::ExpnInfo {
597             call_site: span,
598             callee: codemap::NameAndSpan {
599                 format: codemap::CompilerDesugaring(reason),
600                 span: Some(span),
601                 allow_internal_unstable: true,
602                 allow_internal_unsafe: false,
603                 edition: codemap::hygiene::default_edition(),
604             },
605         });
606         span.with_ctxt(SyntaxContext::empty().apply_mark(mark))
607     }
608
609     fn with_anonymous_lifetime_mode<R>(
610         &mut self,
611         anonymous_lifetime_mode: AnonymousLifetimeMode,
612         op: impl FnOnce(&mut Self) -> R,
613     ) -> R {
614         let old_anonymous_lifetime_mode = self.anonymous_lifetime_mode;
615         self.anonymous_lifetime_mode = anonymous_lifetime_mode;
616         let result = op(self);
617         self.anonymous_lifetime_mode = old_anonymous_lifetime_mode;
618         result
619     }
620
621     /// Creates a new hir::GenericParam for every new lifetime and
622     /// type parameter encountered while evaluating `f`. Definitions
623     /// are created with the parent provided. If no `parent_id` is
624     /// provided, no definitions will be returned.
625     ///
626     /// Presuming that in-band lifetimes are enabled, then
627     /// `self.anonymous_lifetime_mode` will be updated to match the
628     /// argument while `f` is running (and restored afterwards).
629     fn collect_in_band_defs<T, F>(
630         &mut self,
631         parent_id: DefId,
632         anonymous_lifetime_mode: AnonymousLifetimeMode,
633         f: F,
634     ) -> (Vec<hir::GenericParam>, T)
635     where
636         F: FnOnce(&mut LoweringContext) -> T,
637     {
638         assert!(!self.is_collecting_in_band_lifetimes);
639         assert!(self.lifetimes_to_define.is_empty());
640         let old_anonymous_lifetime_mode = self.anonymous_lifetime_mode;
641
642         self.is_collecting_in_band_lifetimes = self.sess.features_untracked().in_band_lifetimes;
643         if self.is_collecting_in_band_lifetimes {
644             self.anonymous_lifetime_mode = anonymous_lifetime_mode;
645         }
646
647         assert!(self.in_band_ty_params.is_empty());
648         let res = f(self);
649
650         self.is_collecting_in_band_lifetimes = false;
651         self.anonymous_lifetime_mode = old_anonymous_lifetime_mode;
652
653         let in_band_ty_params = self.in_band_ty_params.split_off(0);
654         let lifetimes_to_define = self.lifetimes_to_define.split_off(0);
655
656         let params = lifetimes_to_define
657             .into_iter()
658             .map(|(span, hir_name)| {
659                 let def_node_id = self.next_id().node_id;
660
661                 // Get the name we'll use to make the def-path. Note
662                 // that collisions are ok here and this shouldn't
663                 // really show up for end-user.
664                 let str_name = match hir_name {
665                     hir::LifetimeName::Name(n) => n.as_str(),
666                     hir::LifetimeName::Fresh(_) => keywords::UnderscoreLifetime.name().as_str(),
667                     hir::LifetimeName::Implicit
668                     | hir::LifetimeName::Underscore
669                     | hir::LifetimeName::Static => {
670                         span_bug!(span, "unexpected in-band lifetime name: {:?}", hir_name)
671                     }
672                 };
673
674                 // Add a definition for the in-band lifetime def
675                 self.resolver.definitions().create_def_with_parent(
676                     parent_id.index,
677                     def_node_id,
678                     DefPathData::LifetimeDef(str_name.as_interned_str()),
679                     DefIndexAddressSpace::High,
680                     Mark::root(),
681                     span,
682                 );
683
684                 hir::GenericParam::Lifetime(hir::LifetimeDef {
685                     lifetime: hir::Lifetime {
686                         id: def_node_id,
687                         span,
688                         name: hir_name,
689                     },
690                     bounds: Vec::new().into(),
691                     pure_wrt_drop: false,
692                     in_band: true,
693                 })
694             })
695             .chain(
696                 in_band_ty_params
697                     .into_iter()
698                     .map(|tp| hir::GenericParam::Type(tp)),
699             )
700             .collect();
701
702         (params, res)
703     }
704
705     /// When there is a reference to some lifetime `'a`, and in-band
706     /// lifetimes are enabled, then we want to push that lifetime into
707     /// the vector of names to define later. In that case, it will get
708     /// added to the appropriate generics.
709     fn maybe_collect_in_band_lifetime(&mut self, span: Span, name: Name) {
710         if !self.is_collecting_in_band_lifetimes {
711             return;
712         }
713
714         if self.in_scope_lifetimes.contains(&name) {
715             return;
716         }
717
718         let hir_name = hir::LifetimeName::Name(name);
719
720         if self.lifetimes_to_define
721             .iter()
722             .any(|(_, lt_name)| *lt_name == hir_name)
723         {
724             return;
725         }
726
727         self.lifetimes_to_define.push((span, hir_name));
728     }
729
730     /// When we have either an elided or `'_` lifetime in an impl
731     /// header, we convert it to
732     fn collect_fresh_in_band_lifetime(&mut self, span: Span) -> hir::LifetimeName {
733         assert!(self.is_collecting_in_band_lifetimes);
734         let index = self.lifetimes_to_define.len();
735         let hir_name = hir::LifetimeName::Fresh(index);
736         self.lifetimes_to_define.push((span, hir_name));
737         hir_name
738     }
739
740     // Evaluates `f` with the lifetimes in `lt_defs` in-scope.
741     // This is used to track which lifetimes have already been defined, and
742     // which are new in-band lifetimes that need to have a definition created
743     // for them.
744     fn with_in_scope_lifetime_defs<'l, T, F>(
745         &mut self,
746         lt_defs: impl Iterator<Item = &'l LifetimeDef>,
747         f: F,
748     ) -> T
749     where
750         F: FnOnce(&mut LoweringContext) -> T,
751     {
752         let old_len = self.in_scope_lifetimes.len();
753         let lt_def_names = lt_defs.map(|lt_def| lt_def.lifetime.ident.name);
754         self.in_scope_lifetimes.extend(lt_def_names);
755
756         let res = f(self);
757
758         self.in_scope_lifetimes.truncate(old_len);
759         res
760     }
761
762     // Same as the method above, but accepts `hir::LifetimeDef`s
763     // instead of `ast::LifetimeDef`s.
764     // This should only be used with generics that have already had their
765     // in-band lifetimes added. In practice, this means that this function is
766     // only used when lowering a child item of a trait or impl.
767     fn with_parent_impl_lifetime_defs<T, F>(&mut self, lt_defs: &[hir::LifetimeDef], f: F) -> T
768     where
769         F: FnOnce(&mut LoweringContext) -> T,
770     {
771         let old_len = self.in_scope_lifetimes.len();
772         let lt_def_names = lt_defs.iter().map(|lt_def| lt_def.lifetime.name.name());
773         self.in_scope_lifetimes.extend(lt_def_names);
774
775         let res = f(self);
776
777         self.in_scope_lifetimes.truncate(old_len);
778         res
779     }
780
781     /// Appends in-band lifetime defs and argument-position `impl
782     /// Trait` defs to the existing set of generics.
783     ///
784     /// Presuming that in-band lifetimes are enabled, then
785     /// `self.anonymous_lifetime_mode` will be updated to match the
786     /// argument while `f` is running (and restored afterwards).
787     fn add_in_band_defs<F, T>(
788         &mut self,
789         generics: &Generics,
790         parent_id: DefId,
791         anonymous_lifetime_mode: AnonymousLifetimeMode,
792         f: F,
793     ) -> (hir::Generics, T)
794     where
795         F: FnOnce(&mut LoweringContext) -> T,
796     {
797         let (in_band_defs, (mut lowered_generics, res)) = self.with_in_scope_lifetime_defs(
798             generics.params.iter().filter_map(|p| match p {
799                 GenericParam::Lifetime(ld) => Some(ld),
800                 _ => None,
801             }),
802             |this| {
803                 let itctx = ImplTraitContext::Universal(parent_id);
804                 this.collect_in_band_defs(parent_id, anonymous_lifetime_mode, |this| {
805                     (this.lower_generics(generics, itctx), f(this))
806                 })
807             },
808         );
809
810         lowered_generics.params = lowered_generics
811             .params
812             .iter()
813             .cloned()
814             .chain(in_band_defs)
815             .collect();
816
817         (lowered_generics, res)
818     }
819
820     fn with_catch_scope<T, F>(&mut self, catch_id: NodeId, f: F) -> T
821     where
822         F: FnOnce(&mut LoweringContext) -> T,
823     {
824         let len = self.catch_scopes.len();
825         self.catch_scopes.push(catch_id);
826
827         let result = f(self);
828         assert_eq!(
829             len + 1,
830             self.catch_scopes.len(),
831             "catch scopes should be added and removed in stack order"
832         );
833
834         self.catch_scopes.pop().unwrap();
835
836         result
837     }
838
839     fn lower_body<F>(&mut self, decl: Option<&FnDecl>, f: F) -> hir::BodyId
840     where
841         F: FnOnce(&mut LoweringContext) -> hir::Expr,
842     {
843         let prev = mem::replace(&mut self.is_generator, false);
844         let result = f(self);
845         let r = self.record_body(result, decl);
846         self.is_generator = prev;
847         return r;
848     }
849
850     fn with_loop_scope<T, F>(&mut self, loop_id: NodeId, f: F) -> T
851     where
852         F: FnOnce(&mut LoweringContext) -> T,
853     {
854         // We're no longer in the base loop's condition; we're in another loop.
855         let was_in_loop_condition = self.is_in_loop_condition;
856         self.is_in_loop_condition = false;
857
858         let len = self.loop_scopes.len();
859         self.loop_scopes.push(loop_id);
860
861         let result = f(self);
862         assert_eq!(
863             len + 1,
864             self.loop_scopes.len(),
865             "Loop scopes should be added and removed in stack order"
866         );
867
868         self.loop_scopes.pop().unwrap();
869
870         self.is_in_loop_condition = was_in_loop_condition;
871
872         result
873     }
874
875     fn with_loop_condition_scope<T, F>(&mut self, f: F) -> T
876     where
877         F: FnOnce(&mut LoweringContext) -> T,
878     {
879         let was_in_loop_condition = self.is_in_loop_condition;
880         self.is_in_loop_condition = true;
881
882         let result = f(self);
883
884         self.is_in_loop_condition = was_in_loop_condition;
885
886         result
887     }
888
889     fn with_new_scopes<T, F>(&mut self, f: F) -> T
890     where
891         F: FnOnce(&mut LoweringContext) -> T,
892     {
893         let was_in_loop_condition = self.is_in_loop_condition;
894         self.is_in_loop_condition = false;
895
896         let catch_scopes = mem::replace(&mut self.catch_scopes, Vec::new());
897         let loop_scopes = mem::replace(&mut self.loop_scopes, Vec::new());
898         let result = f(self);
899         self.catch_scopes = catch_scopes;
900         self.loop_scopes = loop_scopes;
901
902         self.is_in_loop_condition = was_in_loop_condition;
903
904         result
905     }
906
907     fn def_key(&mut self, id: DefId) -> DefKey {
908         if id.is_local() {
909             self.resolver.definitions().def_key(id.index)
910         } else {
911             self.cstore.def_key(id)
912         }
913     }
914
915     fn lower_ident(&mut self, ident: Ident) -> Name {
916         let ident = ident.modern();
917         if ident.span.ctxt() == SyntaxContext::empty() {
918             return ident.name;
919         }
920         *self.name_map
921             .entry(ident)
922             .or_insert_with(|| Symbol::from_ident(ident))
923     }
924
925     fn lower_label(&mut self, label: Option<Label>) -> Option<hir::Label> {
926         label.map(|label| hir::Label {
927             name: label.ident.name,
928             span: label.ident.span,
929         })
930     }
931
932     fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hir::Destination {
933         match destination {
934             Some((id, label)) => {
935                 let target_id = if let Def::Label(loop_id) = self.expect_full_def(id) {
936                     Ok(self.lower_node_id(loop_id).node_id)
937                 } else {
938                     Err(hir::LoopIdError::UnresolvedLabel)
939                 };
940                 hir::Destination {
941                     label: self.lower_label(Some(label)),
942                     target_id,
943                 }
944             }
945             None => {
946                 let target_id = self.loop_scopes
947                     .last()
948                     .map(|innermost_loop_id| *innermost_loop_id)
949                     .map(|id| Ok(self.lower_node_id(id).node_id))
950                     .unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
951                     .into();
952
953                 hir::Destination {
954                     label: None,
955                     target_id,
956                 }
957             }
958         }
959     }
960
961     fn lower_attrs(&mut self, attrs: &[Attribute]) -> hir::HirVec<Attribute> {
962         attrs
963             .iter()
964             .map(|a| self.lower_attr(a))
965             .collect::<Vec<_>>()
966             .into()
967     }
968
969     fn lower_attr(&mut self, attr: &Attribute) -> Attribute {
970         Attribute {
971             id: attr.id,
972             style: attr.style,
973             path: attr.path.clone(),
974             tokens: self.lower_token_stream(attr.tokens.clone()),
975             is_sugared_doc: attr.is_sugared_doc,
976             span: attr.span,
977         }
978     }
979
980     fn lower_token_stream(&mut self, tokens: TokenStream) -> TokenStream {
981         tokens
982             .into_trees()
983             .flat_map(|tree| self.lower_token_tree(tree).into_trees())
984             .collect()
985     }
986
987     fn lower_token_tree(&mut self, tree: TokenTree) -> TokenStream {
988         match tree {
989             TokenTree::Token(span, token) => self.lower_token(token, span),
990             TokenTree::Delimited(span, delimited) => TokenTree::Delimited(
991                 span,
992                 Delimited {
993                     delim: delimited.delim,
994                     tts: self.lower_token_stream(delimited.tts.into()).into(),
995                 },
996             ).into(),
997         }
998     }
999
1000     fn lower_token(&mut self, token: Token, span: Span) -> TokenStream {
1001         match token {
1002             Token::Interpolated(_) => {}
1003             other => return TokenTree::Token(span, other).into(),
1004         }
1005
1006         let tts = token.interpolated_to_tokenstream(&self.sess.parse_sess, span);
1007         self.lower_token_stream(tts)
1008     }
1009
1010     fn lower_arm(&mut self, arm: &Arm) -> hir::Arm {
1011         hir::Arm {
1012             attrs: self.lower_attrs(&arm.attrs),
1013             pats: arm.pats.iter().map(|x| self.lower_pat(x)).collect(),
1014             guard: arm.guard.as_ref().map(|ref x| P(self.lower_expr(x))),
1015             body: P(self.lower_expr(&arm.body)),
1016         }
1017     }
1018
1019     fn lower_ty_binding(&mut self, b: &TypeBinding, itctx: ImplTraitContext) -> hir::TypeBinding {
1020         hir::TypeBinding {
1021             id: self.lower_node_id(b.id).node_id,
1022             name: self.lower_ident(b.ident),
1023             ty: self.lower_ty(&b.ty, itctx),
1024             span: b.span,
1025         }
1026     }
1027
1028     fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> P<hir::Ty> {
1029         let kind = match t.node {
1030             TyKind::Infer => hir::TyInfer,
1031             TyKind::Err => hir::TyErr,
1032             TyKind::Slice(ref ty) => hir::TySlice(self.lower_ty(ty, itctx)),
1033             TyKind::Ptr(ref mt) => hir::TyPtr(self.lower_mt(mt, itctx)),
1034             TyKind::Rptr(ref region, ref mt) => {
1035                 let span = t.span.shrink_to_lo();
1036                 let lifetime = match *region {
1037                     Some(ref lt) => self.lower_lifetime(lt),
1038                     None => self.elided_ref_lifetime(span),
1039                 };
1040                 hir::TyRptr(lifetime, self.lower_mt(mt, itctx))
1041             }
1042             TyKind::BareFn(ref f) => self.with_in_scope_lifetime_defs(
1043                 f.generic_params.iter().filter_map(|p| match p {
1044                     GenericParam::Lifetime(ld) => Some(ld),
1045                     _ => None,
1046                 }),
1047                 |this| {
1048                     this.with_anonymous_lifetime_mode(
1049                         AnonymousLifetimeMode::PassThrough,
1050                         |this| {
1051                             hir::TyBareFn(P(hir::BareFnTy {
1052                                 generic_params: this.lower_generic_params(
1053                                     &f.generic_params,
1054                                     &NodeMap(),
1055                                     ImplTraitContext::Disallowed,
1056                                 ),
1057                                 unsafety: this.lower_unsafety(f.unsafety),
1058                                 abi: f.abi,
1059                                 decl: this.lower_fn_decl(&f.decl, None, false),
1060                                 arg_names: this.lower_fn_args_to_names(&f.decl),
1061                             }))
1062                         },
1063                     )
1064                 },
1065             ),
1066             TyKind::Never => hir::TyNever,
1067             TyKind::Tup(ref tys) => {
1068                 hir::TyTup(tys.iter().map(|ty| self.lower_ty(ty, itctx)).collect())
1069             }
1070             TyKind::Paren(ref ty) => {
1071                 return self.lower_ty(ty, itctx);
1072             }
1073             TyKind::Path(ref qself, ref path) => {
1074                 let id = self.lower_node_id(t.id);
1075                 let qpath = self.lower_qpath(t.id, qself, path, ParamMode::Explicit, itctx);
1076                 let ty = self.ty_path(id, t.span, qpath);
1077                 if let hir::TyTraitObject(..) = ty.node {
1078                     self.maybe_lint_bare_trait(t.span, t.id, qself.is_none() && path.is_global());
1079                 }
1080                 return ty;
1081             }
1082             TyKind::ImplicitSelf => hir::TyPath(hir::QPath::Resolved(
1083                 None,
1084                 P(hir::Path {
1085                     def: self.expect_full_def(t.id),
1086                     segments: hir_vec![hir::PathSegment::from_name(keywords::SelfType.name())],
1087                     span: t.span,
1088                 }),
1089             )),
1090             TyKind::Array(ref ty, ref length) => {
1091                 hir::TyArray(self.lower_ty(ty, itctx), self.lower_anon_const(length))
1092             }
1093             TyKind::Typeof(ref expr) => {
1094                 hir::TyTypeof(self.lower_anon_const(expr))
1095             }
1096             TyKind::TraitObject(ref bounds, kind) => {
1097                 let mut lifetime_bound = None;
1098                 let bounds = bounds
1099                     .iter()
1100                     .filter_map(|bound| match *bound {
1101                         TraitTyParamBound(ref ty, TraitBoundModifier::None) => {
1102                             Some(self.lower_poly_trait_ref(ty, itctx))
1103                         }
1104                         TraitTyParamBound(_, TraitBoundModifier::Maybe) => None,
1105                         RegionTyParamBound(ref lifetime) => {
1106                             if lifetime_bound.is_none() {
1107                                 lifetime_bound = Some(self.lower_lifetime(lifetime));
1108                             }
1109                             None
1110                         }
1111                     })
1112                     .collect();
1113                 let lifetime_bound =
1114                     lifetime_bound.unwrap_or_else(|| self.elided_dyn_bound(t.span));
1115                 if kind != TraitObjectSyntax::Dyn {
1116                     self.maybe_lint_bare_trait(t.span, t.id, false);
1117                 }
1118                 hir::TyTraitObject(bounds, lifetime_bound)
1119             }
1120             TyKind::ImplTrait(ref bounds) => {
1121                 let span = t.span;
1122                 match itctx {
1123                     ImplTraitContext::Existential => {
1124                         let def_index = self.resolver.definitions().opt_def_index(t.id).unwrap();
1125                         let hir_bounds = self.lower_bounds(bounds, itctx);
1126                         let (lifetimes, lifetime_defs) =
1127                             self.lifetimes_from_impl_trait_bounds(def_index, &hir_bounds);
1128
1129                         hir::TyImplTraitExistential(
1130                             hir::ExistTy {
1131                                 generics: hir::Generics {
1132                                     params: lifetime_defs,
1133                                     where_clause: hir::WhereClause {
1134                                         id: self.next_id().node_id,
1135                                         predicates: Vec::new().into(),
1136                                     },
1137                                     span,
1138                                 },
1139                                 bounds: hir_bounds,
1140                             },
1141                             lifetimes,
1142                         )
1143                     }
1144                     ImplTraitContext::Universal(def_id) => {
1145                         let def_node_id = self.next_id().node_id;
1146
1147                         // Add a definition for the in-band TyParam
1148                         let def_index = self.resolver.definitions().create_def_with_parent(
1149                             def_id.index,
1150                             def_node_id,
1151                             DefPathData::ImplTrait,
1152                             DefIndexAddressSpace::High,
1153                             Mark::root(),
1154                             span,
1155                         );
1156
1157                         let hir_bounds = self.lower_bounds(bounds, itctx);
1158                         // Set the name to `impl Bound1 + Bound2`
1159                         let name = Symbol::intern(&pprust::ty_to_string(t));
1160                         self.in_band_ty_params.push(hir::TyParam {
1161                             name,
1162                             id: def_node_id,
1163                             bounds: hir_bounds,
1164                             default: None,
1165                             span,
1166                             pure_wrt_drop: false,
1167                             synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
1168                             attrs: P::new(),
1169                         });
1170
1171                         hir::TyPath(hir::QPath::Resolved(
1172                             None,
1173                             P(hir::Path {
1174                                 span,
1175                                 def: Def::TyParam(DefId::local(def_index)),
1176                                 segments: hir_vec![hir::PathSegment::from_name(name)],
1177                             }),
1178                         ))
1179                     }
1180                     ImplTraitContext::Disallowed => {
1181                         span_err!(
1182                             self.sess,
1183                             t.span,
1184                             E0562,
1185                             "`impl Trait` not allowed outside of function \
1186                              and inherent method return types"
1187                         );
1188                         hir::TyErr
1189                     }
1190                 }
1191             }
1192             TyKind::Mac(_) => panic!("TyMac should have been expanded by now."),
1193         };
1194
1195         let LoweredNodeId { node_id, hir_id } = self.lower_node_id(t.id);
1196         P(hir::Ty {
1197             id: node_id,
1198             node: kind,
1199             span: t.span,
1200             hir_id,
1201         })
1202     }
1203
1204     fn lifetimes_from_impl_trait_bounds(
1205         &mut self,
1206         parent_index: DefIndex,
1207         bounds: &hir::TyParamBounds,
1208     ) -> (HirVec<hir::Lifetime>, HirVec<hir::GenericParam>) {
1209         // This visitor walks over impl trait bounds and creates defs for all lifetimes which
1210         // appear in the bounds, excluding lifetimes that are created within the bounds.
1211         // e.g. 'a, 'b, but not 'c in `impl for<'c> SomeTrait<'a, 'b, 'c>`
1212         struct ImplTraitLifetimeCollector<'r, 'a: 'r> {
1213             context: &'r mut LoweringContext<'a>,
1214             parent: DefIndex,
1215             collect_elided_lifetimes: bool,
1216             currently_bound_lifetimes: Vec<hir::LifetimeName>,
1217             already_defined_lifetimes: HashSet<hir::LifetimeName>,
1218             output_lifetimes: Vec<hir::Lifetime>,
1219             output_lifetime_params: Vec<hir::GenericParam>,
1220         }
1221
1222         impl<'r, 'a: 'r, 'v> hir::intravisit::Visitor<'v> for ImplTraitLifetimeCollector<'r, 'a> {
1223             fn nested_visit_map<'this>(
1224                 &'this mut self,
1225             ) -> hir::intravisit::NestedVisitorMap<'this, 'v> {
1226                 hir::intravisit::NestedVisitorMap::None
1227             }
1228
1229             fn visit_path_parameters(&mut self, span: Span, parameters: &'v hir::PathParameters) {
1230                 // Don't collect elided lifetimes used inside of `Fn()` syntax.
1231                 if parameters.parenthesized {
1232                     let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
1233                     self.collect_elided_lifetimes = false;
1234                     hir::intravisit::walk_path_parameters(self, span, parameters);
1235                     self.collect_elided_lifetimes = old_collect_elided_lifetimes;
1236                 } else {
1237                     hir::intravisit::walk_path_parameters(self, span, parameters);
1238                 }
1239             }
1240
1241             fn visit_ty(&mut self, t: &'v hir::Ty) {
1242                 // Don't collect elided lifetimes used inside of `fn()` syntax
1243                 if let &hir::Ty_::TyBareFn(_) = &t.node {
1244                     let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
1245                     self.collect_elided_lifetimes = false;
1246
1247                     // Record the "stack height" of `for<'a>` lifetime bindings
1248                     // to be able to later fully undo their introduction.
1249                     let old_len = self.currently_bound_lifetimes.len();
1250                     hir::intravisit::walk_ty(self, t);
1251                     self.currently_bound_lifetimes.truncate(old_len);
1252
1253                     self.collect_elided_lifetimes = old_collect_elided_lifetimes;
1254                 } else {
1255                     hir::intravisit::walk_ty(self, t);
1256                 }
1257             }
1258
1259             fn visit_poly_trait_ref(
1260                 &mut self,
1261                 trait_ref: &'v hir::PolyTraitRef,
1262                 modifier: hir::TraitBoundModifier,
1263             ) {
1264                 // Record the "stack height" of `for<'a>` lifetime bindings
1265                 // to be able to later fully undo their introduction.
1266                 let old_len = self.currently_bound_lifetimes.len();
1267                 hir::intravisit::walk_poly_trait_ref(self, trait_ref, modifier);
1268                 self.currently_bound_lifetimes.truncate(old_len);
1269             }
1270
1271             fn visit_generic_param(&mut self, param: &'v hir::GenericParam) {
1272                 // Record the introduction of 'a in `for<'a> ...`
1273                 if let hir::GenericParam::Lifetime(ref lt_def) = *param {
1274                     // Introduce lifetimes one at a time so that we can handle
1275                     // cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd>`
1276                     self.currently_bound_lifetimes.push(lt_def.lifetime.name);
1277                 }
1278
1279                 hir::intravisit::walk_generic_param(self, param);
1280             }
1281
1282             fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
1283                 let name = match lifetime.name {
1284                     hir::LifetimeName::Implicit | hir::LifetimeName::Underscore => {
1285                         if self.collect_elided_lifetimes {
1286                             // Use `'_` for both implicit and underscore lifetimes in
1287                             // `abstract type Foo<'_>: SomeTrait<'_>;`
1288                             hir::LifetimeName::Underscore
1289                         } else {
1290                             return;
1291                         }
1292                     }
1293                     name @ hir::LifetimeName::Fresh(_) => name,
1294                     name @ hir::LifetimeName::Name(_) => name,
1295                     hir::LifetimeName::Static => return,
1296                 };
1297
1298                 if !self.currently_bound_lifetimes.contains(&name)
1299                     && !self.already_defined_lifetimes.contains(&name)
1300                 {
1301                     self.already_defined_lifetimes.insert(name);
1302
1303                     self.output_lifetimes.push(hir::Lifetime {
1304                         id: self.context.next_id().node_id,
1305                         span: lifetime.span,
1306                         name,
1307                     });
1308
1309                     let def_node_id = self.context.next_id().node_id;
1310                     self.context.resolver.definitions().create_def_with_parent(
1311                         self.parent,
1312                         def_node_id,
1313                         DefPathData::LifetimeDef(name.name().as_interned_str()),
1314                         DefIndexAddressSpace::High,
1315                         Mark::root(),
1316                         lifetime.span,
1317                     );
1318                     let def_lifetime = hir::Lifetime {
1319                         id: def_node_id,
1320                         span: lifetime.span,
1321                         name: name,
1322                     };
1323                     self.output_lifetime_params
1324                         .push(hir::GenericParam::Lifetime(hir::LifetimeDef {
1325                             lifetime: def_lifetime,
1326                             bounds: Vec::new().into(),
1327                             pure_wrt_drop: false,
1328                             in_band: false,
1329                         }));
1330                 }
1331             }
1332         }
1333
1334         let mut lifetime_collector = ImplTraitLifetimeCollector {
1335             context: self,
1336             parent: parent_index,
1337             collect_elided_lifetimes: true,
1338             currently_bound_lifetimes: Vec::new(),
1339             already_defined_lifetimes: HashSet::new(),
1340             output_lifetimes: Vec::new(),
1341             output_lifetime_params: Vec::new(),
1342         };
1343
1344         for bound in bounds {
1345             hir::intravisit::walk_ty_param_bound(&mut lifetime_collector, &bound);
1346         }
1347
1348         (
1349             lifetime_collector.output_lifetimes.into(),
1350             lifetime_collector.output_lifetime_params.into(),
1351         )
1352     }
1353
1354     fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod {
1355         hir::ForeignMod {
1356             abi: fm.abi,
1357             items: fm.items
1358                 .iter()
1359                 .map(|x| self.lower_foreign_item(x))
1360                 .collect(),
1361         }
1362     }
1363
1364     fn lower_global_asm(&mut self, ga: &GlobalAsm) -> P<hir::GlobalAsm> {
1365         P(hir::GlobalAsm {
1366             asm: ga.asm,
1367             ctxt: ga.ctxt,
1368         })
1369     }
1370
1371     fn lower_variant(&mut self, v: &Variant) -> hir::Variant {
1372         Spanned {
1373             node: hir::Variant_ {
1374                 name: v.node.ident.name,
1375                 attrs: self.lower_attrs(&v.node.attrs),
1376                 data: self.lower_variant_data(&v.node.data),
1377                 disr_expr: v.node.disr_expr.as_ref().map(|e| self.lower_anon_const(e)),
1378             },
1379             span: v.span,
1380         }
1381     }
1382
1383     fn lower_qpath(
1384         &mut self,
1385         id: NodeId,
1386         qself: &Option<QSelf>,
1387         p: &Path,
1388         param_mode: ParamMode,
1389         itctx: ImplTraitContext,
1390     ) -> hir::QPath {
1391         let qself_position = qself.as_ref().map(|q| q.position);
1392         let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx));
1393
1394         let resolution = self.resolver
1395             .get_resolution(id)
1396             .unwrap_or(PathResolution::new(Def::Err));
1397
1398         let proj_start = p.segments.len() - resolution.unresolved_segments();
1399         let path = P(hir::Path {
1400             def: resolution.base_def(),
1401             segments: p.segments[..proj_start]
1402                 .iter()
1403                 .enumerate()
1404                 .map(|(i, segment)| {
1405                     let param_mode = match (qself_position, param_mode) {
1406                         (Some(j), ParamMode::Optional) if i < j => {
1407                             // This segment is part of the trait path in a
1408                             // qualified path - one of `a`, `b` or `Trait`
1409                             // in `<X as a::b::Trait>::T::U::method`.
1410                             ParamMode::Explicit
1411                         }
1412                         _ => param_mode,
1413                     };
1414
1415                     // Figure out if this is a type/trait segment,
1416                     // which may need lifetime elision performed.
1417                     let parent_def_id = |this: &mut Self, def_id: DefId| DefId {
1418                         krate: def_id.krate,
1419                         index: this.def_key(def_id).parent.expect("missing parent"),
1420                     };
1421                     let type_def_id = match resolution.base_def() {
1422                         Def::AssociatedTy(def_id) if i + 2 == proj_start => {
1423                             Some(parent_def_id(self, def_id))
1424                         }
1425                         Def::Variant(def_id) if i + 1 == proj_start => {
1426                             Some(parent_def_id(self, def_id))
1427                         }
1428                         Def::Struct(def_id)
1429                         | Def::Union(def_id)
1430                         | Def::Enum(def_id)
1431                         | Def::TyAlias(def_id)
1432                         | Def::Trait(def_id) if i + 1 == proj_start =>
1433                         {
1434                             Some(def_id)
1435                         }
1436                         _ => None,
1437                     };
1438                     let parenthesized_generic_args = match resolution.base_def() {
1439                         // `a::b::Trait(Args)`
1440                         Def::Trait(..) if i + 1 == proj_start => ParenthesizedGenericArgs::Ok,
1441                         // `a::b::Trait(Args)::TraitItem`
1442                         Def::Method(..) | Def::AssociatedConst(..) | Def::AssociatedTy(..)
1443                             if i + 2 == proj_start =>
1444                         {
1445                             ParenthesizedGenericArgs::Ok
1446                         }
1447                         // Avoid duplicated errors
1448                         Def::Err => ParenthesizedGenericArgs::Ok,
1449                         // An error
1450                         Def::Struct(..)
1451                         | Def::Enum(..)
1452                         | Def::Union(..)
1453                         | Def::TyAlias(..)
1454                         | Def::Variant(..) if i + 1 == proj_start =>
1455                         {
1456                             ParenthesizedGenericArgs::Err
1457                         }
1458                         // A warning for now, for compatibility reasons
1459                         _ => ParenthesizedGenericArgs::Warn,
1460                     };
1461
1462                     let num_lifetimes = type_def_id.map_or(0, |def_id| {
1463                         if let Some(&n) = self.type_def_lifetime_params.get(&def_id) {
1464                             return n;
1465                         }
1466                         assert!(!def_id.is_local());
1467                         let item_generics =
1468                             self.cstore.item_generics_cloned_untracked(def_id, self.sess);
1469                         let n = item_generics.own_counts().lifetimes;
1470                         self.type_def_lifetime_params.insert(def_id, n);
1471                         n
1472                     });
1473                     self.lower_path_segment(
1474                         p.span,
1475                         segment,
1476                         param_mode,
1477                         num_lifetimes,
1478                         parenthesized_generic_args,
1479                         itctx,
1480                     )
1481                 })
1482                 .collect(),
1483             span: p.span,
1484         });
1485
1486         // Simple case, either no projections, or only fully-qualified.
1487         // E.g. `std::mem::size_of` or `<I as Iterator>::Item`.
1488         if resolution.unresolved_segments() == 0 {
1489             return hir::QPath::Resolved(qself, path);
1490         }
1491
1492         // Create the innermost type that we're projecting from.
1493         let mut ty = if path.segments.is_empty() {
1494             // If the base path is empty that means there exists a
1495             // syntactical `Self`, e.g. `&i32` in `<&i32>::clone`.
1496             qself.expect("missing QSelf for <T>::...")
1497         } else {
1498             // Otherwise, the base path is an implicit `Self` type path,
1499             // e.g. `Vec` in `Vec::new` or `<I as Iterator>::Item` in
1500             // `<I as Iterator>::Item::default`.
1501             let new_id = self.next_id();
1502             self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path))
1503         };
1504
1505         // Anything after the base path are associated "extensions",
1506         // out of which all but the last one are associated types,
1507         // e.g. for `std::vec::Vec::<T>::IntoIter::Item::clone`:
1508         // * base path is `std::vec::Vec<T>`
1509         // * "extensions" are `IntoIter`, `Item` and `clone`
1510         // * type nodes are:
1511         //   1. `std::vec::Vec<T>` (created above)
1512         //   2. `<std::vec::Vec<T>>::IntoIter`
1513         //   3. `<<std::vec::Vec<T>>::IntoIter>::Item`
1514         // * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
1515         for (i, segment) in p.segments.iter().enumerate().skip(proj_start) {
1516             let segment = P(self.lower_path_segment(
1517                 p.span,
1518                 segment,
1519                 param_mode,
1520                 0,
1521                 ParenthesizedGenericArgs::Warn,
1522                 itctx,
1523             ));
1524             let qpath = hir::QPath::TypeRelative(ty, segment);
1525
1526             // It's finished, return the extension of the right node type.
1527             if i == p.segments.len() - 1 {
1528                 return qpath;
1529             }
1530
1531             // Wrap the associated extension in another type node.
1532             let new_id = self.next_id();
1533             ty = self.ty_path(new_id, p.span, qpath);
1534         }
1535
1536         // Should've returned in the for loop above.
1537         span_bug!(
1538             p.span,
1539             "lower_qpath: no final extension segment in {}..{}",
1540             proj_start,
1541             p.segments.len()
1542         )
1543     }
1544
1545     fn lower_path_extra(
1546         &mut self,
1547         def: Def,
1548         p: &Path,
1549         name: Option<Name>,
1550         param_mode: ParamMode,
1551     ) -> hir::Path {
1552         hir::Path {
1553             def,
1554             segments: p.segments
1555                 .iter()
1556                 .map(|segment| {
1557                     self.lower_path_segment(
1558                         p.span,
1559                         segment,
1560                         param_mode,
1561                         0,
1562                         ParenthesizedGenericArgs::Err,
1563                         ImplTraitContext::Disallowed,
1564                     )
1565                 })
1566                 .chain(name.map(|name| hir::PathSegment::from_name(name)))
1567                 .collect(),
1568             span: p.span,
1569         }
1570     }
1571
1572     fn lower_path(&mut self, id: NodeId, p: &Path, param_mode: ParamMode) -> hir::Path {
1573         let def = self.expect_full_def(id);
1574         self.lower_path_extra(def, p, None, param_mode)
1575     }
1576
1577     fn lower_path_segment(
1578         &mut self,
1579         path_span: Span,
1580         segment: &PathSegment,
1581         param_mode: ParamMode,
1582         expected_lifetimes: usize,
1583         parenthesized_generic_args: ParenthesizedGenericArgs,
1584         itctx: ImplTraitContext,
1585     ) -> hir::PathSegment {
1586         let (mut parameters, infer_types) = if let Some(ref parameters) = segment.parameters {
1587             let msg = "parenthesized parameters may only be used with a trait";
1588             match **parameters {
1589                 PathParameters::AngleBracketed(ref data) => {
1590                     self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
1591                 }
1592                 PathParameters::Parenthesized(ref data) => match parenthesized_generic_args {
1593                     ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data),
1594                     ParenthesizedGenericArgs::Warn => {
1595                         self.sess.buffer_lint(
1596                             PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
1597                             CRATE_NODE_ID,
1598                             data.span,
1599                             msg.into(),
1600                         );
1601                         (hir::PathParameters::none(), true)
1602                     }
1603                     ParenthesizedGenericArgs::Err => {
1604                         struct_span_err!(self.sess, data.span, E0214, "{}", msg)
1605                             .span_label(data.span, "only traits may use parentheses")
1606                             .emit();
1607                         (hir::PathParameters::none(), true)
1608                     }
1609                 },
1610             }
1611         } else {
1612             self.lower_angle_bracketed_parameter_data(&Default::default(), param_mode, itctx)
1613         };
1614
1615         if !parameters.parenthesized && parameters.lifetimes.is_empty() {
1616             parameters.lifetimes = self.elided_path_lifetimes(path_span, expected_lifetimes);
1617         }
1618
1619         hir::PathSegment::new(
1620             self.lower_ident(segment.ident),
1621             parameters,
1622             infer_types,
1623         )
1624     }
1625
1626     fn lower_angle_bracketed_parameter_data(
1627         &mut self,
1628         data: &AngleBracketedParameterData,
1629         param_mode: ParamMode,
1630         itctx: ImplTraitContext,
1631     ) -> (hir::PathParameters, bool) {
1632         let &AngleBracketedParameterData {
1633             ref lifetimes,
1634             ref types,
1635             ref bindings,
1636             ..
1637         } = data;
1638         (
1639             hir::PathParameters {
1640                 lifetimes: self.lower_lifetimes(lifetimes),
1641                 types: types.iter().map(|ty| self.lower_ty(ty, itctx)).collect(),
1642                 bindings: bindings
1643                     .iter()
1644                     .map(|b| self.lower_ty_binding(b, itctx))
1645                     .collect(),
1646                 parenthesized: false,
1647             },
1648             types.is_empty() && param_mode == ParamMode::Optional,
1649         )
1650     }
1651
1652     fn lower_parenthesized_parameter_data(
1653         &mut self,
1654         data: &ParenthesizedParameterData,
1655     ) -> (hir::PathParameters, bool) {
1656         // Switch to `PassThrough` mode for anonymous lifetimes: this
1657         // means that we permit things like `&Ref<T>`, where `Ref` has
1658         // a hidden lifetime parameter. This is needed for backwards
1659         // compatibility, even in contexts like an impl header where
1660         // we generally don't permit such things (see #51008).
1661         self.with_anonymous_lifetime_mode(
1662             AnonymousLifetimeMode::PassThrough,
1663             |this| {
1664                 const DISALLOWED: ImplTraitContext = ImplTraitContext::Disallowed;
1665                 let &ParenthesizedParameterData {
1666                     ref inputs,
1667                     ref output,
1668                     span,
1669                 } = data;
1670                 let inputs = inputs
1671                     .iter()
1672                     .map(|ty| this.lower_ty(ty, DISALLOWED))
1673                     .collect();
1674                 let mk_tup = |this: &mut Self, tys, span| {
1675                     let LoweredNodeId { node_id, hir_id } = this.next_id();
1676                     P(hir::Ty {
1677                         node: hir::TyTup(tys),
1678                         id: node_id,
1679                         hir_id,
1680                         span,
1681                     })
1682                 };
1683
1684                 (
1685                     hir::PathParameters {
1686                         lifetimes: hir::HirVec::new(),
1687                         types: hir_vec![mk_tup(this, inputs, span)],
1688                         bindings: hir_vec![
1689                             hir::TypeBinding {
1690                                 id: this.next_id().node_id,
1691                                 name: Symbol::intern(FN_OUTPUT_NAME),
1692                                 ty: output
1693                                     .as_ref()
1694                                     .map(|ty| this.lower_ty(&ty, DISALLOWED))
1695                                     .unwrap_or_else(|| mk_tup(this, hir::HirVec::new(), span)),
1696                                 span: output.as_ref().map_or(span, |ty| ty.span),
1697                             }
1698                         ],
1699                         parenthesized: true,
1700                     },
1701                     false,
1702                 )
1703             }
1704         )
1705     }
1706
1707     fn lower_local(&mut self, l: &Local) -> P<hir::Local> {
1708         let LoweredNodeId { node_id, hir_id } = self.lower_node_id(l.id);
1709         P(hir::Local {
1710             id: node_id,
1711             hir_id,
1712             ty: l.ty
1713                 .as_ref()
1714                 .map(|t| self.lower_ty(t, ImplTraitContext::Disallowed)),
1715             pat: self.lower_pat(&l.pat),
1716             init: l.init.as_ref().map(|e| P(self.lower_expr(e))),
1717             span: l.span,
1718             attrs: l.attrs.clone(),
1719             source: hir::LocalSource::Normal,
1720         })
1721     }
1722
1723     fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability {
1724         match m {
1725             Mutability::Mutable => hir::MutMutable,
1726             Mutability::Immutable => hir::MutImmutable,
1727         }
1728     }
1729
1730     fn lower_arg(&mut self, arg: &Arg) -> hir::Arg {
1731         let LoweredNodeId { node_id, hir_id } = self.lower_node_id(arg.id);
1732         hir::Arg {
1733             id: node_id,
1734             hir_id,
1735             pat: self.lower_pat(&arg.pat),
1736         }
1737     }
1738
1739     fn lower_fn_args_to_names(&mut self, decl: &FnDecl) -> hir::HirVec<Spanned<Name>> {
1740         decl.inputs
1741             .iter()
1742             .map(|arg| match arg.pat.node {
1743                 PatKind::Ident(_, ident, None) => respan(ident.span, ident.name),
1744                 _ => respan(arg.pat.span, keywords::Invalid.name()),
1745             })
1746             .collect()
1747     }
1748
1749     fn lower_fn_decl(
1750         &mut self,
1751         decl: &FnDecl,
1752         fn_def_id: Option<DefId>,
1753         impl_trait_return_allow: bool,
1754     ) -> P<hir::FnDecl> {
1755         // NOTE: The two last parameters here have to do with impl Trait. If fn_def_id is Some,
1756         //       then impl Trait arguments are lowered into generic parameters on the given
1757         //       fn_def_id, otherwise impl Trait is disallowed. (for now)
1758         //
1759         //       Furthermore, if impl_trait_return_allow is true, then impl Trait may be used in
1760         //       return positions as well. This guards against trait declarations and their impls
1761         //       where impl Trait is disallowed. (again for now)
1762         P(hir::FnDecl {
1763             inputs: decl.inputs
1764                 .iter()
1765                 .map(|arg| {
1766                     if let Some(def_id) = fn_def_id {
1767                         self.lower_ty(&arg.ty, ImplTraitContext::Universal(def_id))
1768                     } else {
1769                         self.lower_ty(&arg.ty, ImplTraitContext::Disallowed)
1770                     }
1771                 })
1772                 .collect(),
1773             output: match decl.output {
1774                 FunctionRetTy::Ty(ref ty) => match fn_def_id {
1775                     Some(_) if impl_trait_return_allow => {
1776                         hir::Return(self.lower_ty(ty, ImplTraitContext::Existential))
1777                     }
1778                     _ => hir::Return(self.lower_ty(ty, ImplTraitContext::Disallowed)),
1779                 },
1780                 FunctionRetTy::Default(span) => hir::DefaultReturn(span),
1781             },
1782             variadic: decl.variadic,
1783             has_implicit_self: decl.inputs.get(0).map_or(false, |arg| match arg.ty.node {
1784                 TyKind::ImplicitSelf => true,
1785                 TyKind::Rptr(_, ref mt) => mt.ty.node == TyKind::ImplicitSelf,
1786                 _ => false,
1787             }),
1788         })
1789     }
1790
1791     fn lower_ty_param_bound(
1792         &mut self,
1793         tpb: &TyParamBound,
1794         itctx: ImplTraitContext,
1795     ) -> hir::TyParamBound {
1796         match *tpb {
1797             TraitTyParamBound(ref ty, modifier) => hir::TraitTyParamBound(
1798                 self.lower_poly_trait_ref(ty, itctx),
1799                 self.lower_trait_bound_modifier(modifier),
1800             ),
1801             RegionTyParamBound(ref lifetime) => {
1802                 hir::RegionTyParamBound(self.lower_lifetime(lifetime))
1803             }
1804         }
1805     }
1806
1807     fn lower_ty_param(
1808         &mut self,
1809         tp: &TyParam,
1810         add_bounds: &[TyParamBound],
1811         itctx: ImplTraitContext,
1812     ) -> hir::TyParam {
1813         let mut name = self.lower_ident(tp.ident);
1814
1815         // Don't expose `Self` (recovered "keyword used as ident" parse error).
1816         // `rustc::ty` expects `Self` to be only used for a trait's `Self`.
1817         // Instead, use gensym("Self") to create a distinct name that looks the same.
1818         if name == keywords::SelfType.name() {
1819             name = Symbol::gensym("Self");
1820         }
1821
1822         let mut bounds = self.lower_bounds(&tp.bounds, itctx);
1823         if !add_bounds.is_empty() {
1824             bounds = bounds
1825                 .into_iter()
1826                 .chain(self.lower_bounds(add_bounds, itctx).into_iter())
1827                 .collect();
1828         }
1829
1830         hir::TyParam {
1831             id: self.lower_node_id(tp.id).node_id,
1832             name,
1833             bounds,
1834             default: tp.default
1835                 .as_ref()
1836                 .map(|x| self.lower_ty(x, ImplTraitContext::Disallowed)),
1837             span: tp.ident.span,
1838             pure_wrt_drop: attr::contains_name(&tp.attrs, "may_dangle"),
1839             synthetic: tp.attrs
1840                 .iter()
1841                 .filter(|attr| attr.check_name("rustc_synthetic"))
1842                 .map(|_| hir::SyntheticTyParamKind::ImplTrait)
1843                 .nth(0),
1844             attrs: self.lower_attrs(&tp.attrs),
1845         }
1846     }
1847
1848     fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
1849         let span = l.ident.span;
1850         match self.lower_ident(l.ident) {
1851             x if x == "'static" => self.new_named_lifetime(l.id, span, hir::LifetimeName::Static),
1852             x if x == "'_" => match self.anonymous_lifetime_mode {
1853                 AnonymousLifetimeMode::CreateParameter => {
1854                     let fresh_name = self.collect_fresh_in_band_lifetime(span);
1855                     self.new_named_lifetime(l.id, span, fresh_name)
1856                 }
1857
1858                 AnonymousLifetimeMode::PassThrough => {
1859                     self.new_named_lifetime(l.id, span, hir::LifetimeName::Underscore)
1860                 }
1861             },
1862             name => {
1863                 self.maybe_collect_in_band_lifetime(span, name);
1864                 self.new_named_lifetime(l.id, span, hir::LifetimeName::Name(name))
1865             }
1866         }
1867     }
1868
1869     fn new_named_lifetime(
1870         &mut self,
1871         id: NodeId,
1872         span: Span,
1873         name: hir::LifetimeName,
1874     ) -> hir::Lifetime {
1875         hir::Lifetime {
1876             id: self.lower_node_id(id).node_id,
1877             span,
1878             name: name,
1879         }
1880     }
1881
1882     fn lower_lifetime_def(&mut self, l: &LifetimeDef) -> hir::LifetimeDef {
1883         let was_collecting_in_band = self.is_collecting_in_band_lifetimes;
1884         self.is_collecting_in_band_lifetimes = false;
1885
1886         let def = hir::LifetimeDef {
1887             lifetime: self.lower_lifetime(&l.lifetime),
1888             bounds: self.lower_lifetimes(&l.bounds),
1889             pure_wrt_drop: attr::contains_name(&l.attrs, "may_dangle"),
1890             in_band: false,
1891         };
1892
1893         self.is_collecting_in_band_lifetimes = was_collecting_in_band;
1894
1895         def
1896     }
1897
1898     fn lower_lifetimes(&mut self, lts: &Vec<Lifetime>) -> hir::HirVec<hir::Lifetime> {
1899         lts.iter().map(|l| self.lower_lifetime(l)).collect()
1900     }
1901
1902     fn lower_generic_params(
1903         &mut self,
1904         params: &Vec<GenericParam>,
1905         add_bounds: &NodeMap<Vec<TyParamBound>>,
1906         itctx: ImplTraitContext,
1907     ) -> hir::HirVec<hir::GenericParam> {
1908         params
1909             .iter()
1910             .map(|param| match *param {
1911                 GenericParam::Lifetime(ref lifetime_def) => {
1912                     hir::GenericParam::Lifetime(self.lower_lifetime_def(lifetime_def))
1913                 }
1914                 GenericParam::Type(ref ty_param) => hir::GenericParam::Type(self.lower_ty_param(
1915                     ty_param,
1916                     add_bounds.get(&ty_param.id).map_or(&[][..], |x| &x),
1917                     itctx,
1918                 )),
1919             })
1920             .collect()
1921     }
1922
1923     fn lower_generics(&mut self, g: &Generics, itctx: ImplTraitContext) -> hir::Generics {
1924         // Collect `?Trait` bounds in where clause and move them to parameter definitions.
1925         // FIXME: This could probably be done with less rightward drift. Also looks like two control
1926         //        paths where report_error is called are also the only paths that advance to after
1927         //        the match statement, so the error reporting could probably just be moved there.
1928         let mut add_bounds = NodeMap();
1929         for pred in &g.where_clause.predicates {
1930             if let WherePredicate::BoundPredicate(ref bound_pred) = *pred {
1931                 'next_bound: for bound in &bound_pred.bounds {
1932                     if let TraitTyParamBound(_, TraitBoundModifier::Maybe) = *bound {
1933                         let report_error = |this: &mut Self| {
1934                             this.diagnostic().span_err(
1935                                 bound_pred.bounded_ty.span,
1936                                 "`?Trait` bounds are only permitted at the \
1937                                  point where a type parameter is declared",
1938                             );
1939                         };
1940                         // Check if the where clause type is a plain type parameter.
1941                         match bound_pred.bounded_ty.node {
1942                             TyKind::Path(None, ref path)
1943                                 if path.segments.len() == 1
1944                                     && bound_pred.bound_generic_params.is_empty() =>
1945                             {
1946                                 if let Some(Def::TyParam(def_id)) = self.resolver
1947                                     .get_resolution(bound_pred.bounded_ty.id)
1948                                     .map(|d| d.base_def())
1949                                 {
1950                                     if let Some(node_id) =
1951                                         self.resolver.definitions().as_local_node_id(def_id)
1952                                     {
1953                                         for param in &g.params {
1954                                             if let GenericParam::Type(ref ty_param) = *param {
1955                                                 if node_id == ty_param.id {
1956                                                     add_bounds
1957                                                         .entry(ty_param.id)
1958                                                         .or_insert(Vec::new())
1959                                                         .push(bound.clone());
1960                                                     continue 'next_bound;
1961                                                 }
1962                                             }
1963                                         }
1964                                     }
1965                                 }
1966                                 report_error(self)
1967                             }
1968                             _ => report_error(self),
1969                         }
1970                     }
1971                 }
1972             }
1973         }
1974
1975         hir::Generics {
1976             params: self.lower_generic_params(&g.params, &add_bounds, itctx),
1977             where_clause: self.lower_where_clause(&g.where_clause),
1978             span: g.span,
1979         }
1980     }
1981
1982     fn lower_where_clause(&mut self, wc: &WhereClause) -> hir::WhereClause {
1983         hir::WhereClause {
1984             id: self.lower_node_id(wc.id).node_id,
1985             predicates: wc.predicates
1986                 .iter()
1987                 .map(|predicate| self.lower_where_predicate(predicate))
1988                 .collect(),
1989         }
1990     }
1991
1992     fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate {
1993         match *pred {
1994             WherePredicate::BoundPredicate(WhereBoundPredicate {
1995                 ref bound_generic_params,
1996                 ref bounded_ty,
1997                 ref bounds,
1998                 span,
1999             }) => {
2000                 self.with_in_scope_lifetime_defs(
2001                     bound_generic_params.iter().filter_map(|p| match p {
2002                         GenericParam::Lifetime(ld) => Some(ld),
2003                         _ => None,
2004                     }),
2005                     |this| {
2006                         hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
2007                             bound_generic_params: this.lower_generic_params(
2008                                 bound_generic_params,
2009                                 &NodeMap(),
2010                                 ImplTraitContext::Disallowed,
2011                             ),
2012                             bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::Disallowed),
2013                             bounds: bounds
2014                                 .iter()
2015                                 .filter_map(|bound| match *bound {
2016                                     // Ignore `?Trait` bounds.
2017                                     // Tthey were copied into type parameters already.
2018                                     TraitTyParamBound(_, TraitBoundModifier::Maybe) => None,
2019                                     _ => Some(this.lower_ty_param_bound(
2020                                         bound,
2021                                         ImplTraitContext::Disallowed,
2022                                     )),
2023                                 })
2024                                 .collect(),
2025                             span,
2026                         })
2027                     },
2028                 )
2029             }
2030             WherePredicate::RegionPredicate(WhereRegionPredicate {
2031                 ref lifetime,
2032                 ref bounds,
2033                 span,
2034             }) => hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
2035                 span,
2036                 lifetime: self.lower_lifetime(lifetime),
2037                 bounds: bounds
2038                     .iter()
2039                     .map(|bound| self.lower_lifetime(bound))
2040                     .collect(),
2041             }),
2042             WherePredicate::EqPredicate(WhereEqPredicate {
2043                 id,
2044                 ref lhs_ty,
2045                 ref rhs_ty,
2046                 span,
2047             }) => hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
2048                 id: self.lower_node_id(id).node_id,
2049                 lhs_ty: self.lower_ty(lhs_ty, ImplTraitContext::Disallowed),
2050                 rhs_ty: self.lower_ty(rhs_ty, ImplTraitContext::Disallowed),
2051                 span,
2052             }),
2053         }
2054     }
2055
2056     fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData {
2057         match *vdata {
2058             VariantData::Struct(ref fields, id) => hir::VariantData::Struct(
2059                 fields
2060                     .iter()
2061                     .enumerate()
2062                     .map(|f| self.lower_struct_field(f))
2063                     .collect(),
2064                 self.lower_node_id(id).node_id,
2065             ),
2066             VariantData::Tuple(ref fields, id) => hir::VariantData::Tuple(
2067                 fields
2068                     .iter()
2069                     .enumerate()
2070                     .map(|f| self.lower_struct_field(f))
2071                     .collect(),
2072                 self.lower_node_id(id).node_id,
2073             ),
2074             VariantData::Unit(id) => hir::VariantData::Unit(self.lower_node_id(id).node_id),
2075         }
2076     }
2077
2078     fn lower_trait_ref(&mut self, p: &TraitRef, itctx: ImplTraitContext) -> hir::TraitRef {
2079         let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
2080             hir::QPath::Resolved(None, path) => path.and_then(|path| path),
2081             qpath => bug!("lower_trait_ref: unexpected QPath `{:?}`", qpath),
2082         };
2083         hir::TraitRef {
2084             path,
2085             ref_id: self.lower_node_id(p.ref_id).node_id,
2086         }
2087     }
2088
2089     fn lower_poly_trait_ref(
2090         &mut self,
2091         p: &PolyTraitRef,
2092         itctx: ImplTraitContext,
2093     ) -> hir::PolyTraitRef {
2094         let bound_generic_params =
2095             self.lower_generic_params(&p.bound_generic_params, &NodeMap(), itctx);
2096         let trait_ref = self.with_parent_impl_lifetime_defs(
2097             &bound_generic_params
2098                 .iter()
2099                 .filter_map(|p| match *p {
2100                     hir::GenericParam::Lifetime(ref ld) => Some(ld.clone()),
2101                     _ => None,
2102                 })
2103                 .collect::<Vec<_>>(),
2104             |this| this.lower_trait_ref(&p.trait_ref, itctx),
2105         );
2106
2107         hir::PolyTraitRef {
2108             bound_generic_params,
2109             trait_ref,
2110             span: p.span,
2111         }
2112     }
2113
2114     fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::StructField {
2115         hir::StructField {
2116             span: f.span,
2117             id: self.lower_node_id(f.id).node_id,
2118             ident: match f.ident {
2119                 Some(ident) => ident,
2120                 // FIXME(jseyfried) positional field hygiene
2121                 None => Ident::new(Symbol::intern(&index.to_string()), f.span),
2122             },
2123             vis: self.lower_visibility(&f.vis, None),
2124             ty: self.lower_ty(&f.ty, ImplTraitContext::Disallowed),
2125             attrs: self.lower_attrs(&f.attrs),
2126         }
2127     }
2128
2129     fn lower_field(&mut self, f: &Field) -> hir::Field {
2130         hir::Field {
2131             id: self.next_id().node_id,
2132             ident: f.ident,
2133             expr: P(self.lower_expr(&f.expr)),
2134             span: f.span,
2135             is_shorthand: f.is_shorthand,
2136         }
2137     }
2138
2139     fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy {
2140         hir::MutTy {
2141             ty: self.lower_ty(&mt.ty, itctx),
2142             mutbl: self.lower_mutability(mt.mutbl),
2143         }
2144     }
2145
2146     fn lower_bounds(
2147         &mut self,
2148         bounds: &[TyParamBound],
2149         itctx: ImplTraitContext,
2150     ) -> hir::TyParamBounds {
2151         bounds
2152             .iter()
2153             .map(|bound| self.lower_ty_param_bound(bound, itctx))
2154             .collect()
2155     }
2156
2157     fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> P<hir::Block> {
2158         let mut expr = None;
2159
2160         let mut stmts = vec![];
2161
2162         for (index, stmt) in b.stmts.iter().enumerate() {
2163             if index == b.stmts.len() - 1 {
2164                 if let StmtKind::Expr(ref e) = stmt.node {
2165                     expr = Some(P(self.lower_expr(e)));
2166                 } else {
2167                     stmts.extend(self.lower_stmt(stmt));
2168                 }
2169             } else {
2170                 stmts.extend(self.lower_stmt(stmt));
2171             }
2172         }
2173
2174         let LoweredNodeId { node_id, hir_id } = self.lower_node_id(b.id);
2175
2176         P(hir::Block {
2177             id: node_id,
2178             hir_id,
2179             stmts: stmts.into(),
2180             expr,
2181             rules: self.lower_block_check_mode(&b.rules),
2182             span: b.span,
2183             targeted_by_break,
2184             recovered: b.recovered,
2185         })
2186     }
2187
2188     fn lower_item_kind(
2189         &mut self,
2190         id: NodeId,
2191         name: &mut Name,
2192         attrs: &hir::HirVec<Attribute>,
2193         vis: &mut hir::Visibility,
2194         i: &ItemKind,
2195     ) -> hir::Item_ {
2196         match *i {
2197             ItemKind::ExternCrate(orig_name) => hir::ItemExternCrate(orig_name),
2198             ItemKind::Use(ref use_tree) => {
2199                 // Start with an empty prefix
2200                 let prefix = Path {
2201                     segments: vec![],
2202                     span: use_tree.span,
2203                 };
2204
2205                 self.lower_use_tree(use_tree, &prefix, id, vis, name, attrs)
2206             }
2207             ItemKind::Static(ref t, m, ref e) => {
2208                 let value = self.lower_body(None, |this| this.lower_expr(e));
2209                 hir::ItemStatic(
2210                     self.lower_ty(t, ImplTraitContext::Disallowed),
2211                     self.lower_mutability(m),
2212                     value,
2213                 )
2214             }
2215             ItemKind::Const(ref t, ref e) => {
2216                 let value = self.lower_body(None, |this| this.lower_expr(e));
2217                 hir::ItemConst(self.lower_ty(t, ImplTraitContext::Disallowed), value)
2218             }
2219             ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
2220                 let fn_def_id = self.resolver.definitions().local_def_id(id);
2221                 self.with_new_scopes(|this| {
2222                     let body_id = this.lower_body(Some(decl), |this| {
2223                         let body = this.lower_block(body, false);
2224                         this.expr_block(body, ThinVec::new())
2225                     });
2226                     let (generics, fn_decl) = this.add_in_band_defs(
2227                         generics,
2228                         fn_def_id,
2229                         AnonymousLifetimeMode::PassThrough,
2230                         |this| this.lower_fn_decl(decl, Some(fn_def_id), true),
2231                     );
2232
2233                     hir::ItemFn(
2234                         fn_decl,
2235                         this.lower_unsafety(unsafety),
2236                         this.lower_constness(constness),
2237                         abi,
2238                         generics,
2239                         body_id,
2240                     )
2241                 })
2242             }
2243             ItemKind::Mod(ref m) => hir::ItemMod(self.lower_mod(m)),
2244             ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(self.lower_foreign_mod(nm)),
2245             ItemKind::GlobalAsm(ref ga) => hir::ItemGlobalAsm(self.lower_global_asm(ga)),
2246             ItemKind::Ty(ref t, ref generics) => hir::ItemTy(
2247                 self.lower_ty(t, ImplTraitContext::Disallowed),
2248                 self.lower_generics(generics, ImplTraitContext::Disallowed),
2249             ),
2250             ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemEnum(
2251                 hir::EnumDef {
2252                     variants: enum_definition
2253                         .variants
2254                         .iter()
2255                         .map(|x| self.lower_variant(x))
2256                         .collect(),
2257                 },
2258                 self.lower_generics(generics, ImplTraitContext::Disallowed),
2259             ),
2260             ItemKind::Struct(ref struct_def, ref generics) => {
2261                 let struct_def = self.lower_variant_data(struct_def);
2262                 hir::ItemStruct(
2263                     struct_def,
2264                     self.lower_generics(generics, ImplTraitContext::Disallowed),
2265                 )
2266             }
2267             ItemKind::Union(ref vdata, ref generics) => {
2268                 let vdata = self.lower_variant_data(vdata);
2269                 hir::ItemUnion(
2270                     vdata,
2271                     self.lower_generics(generics, ImplTraitContext::Disallowed),
2272                 )
2273             }
2274             ItemKind::Impl(
2275                 unsafety,
2276                 polarity,
2277                 defaultness,
2278                 ref ast_generics,
2279                 ref trait_ref,
2280                 ref ty,
2281                 ref impl_items,
2282             ) => {
2283                 let def_id = self.resolver.definitions().local_def_id(id);
2284
2285                 // Lower the "impl header" first. This ordering is important
2286                 // for in-band lifetimes! Consider `'a` here:
2287                 //
2288                 //     impl Foo<'a> for u32 {
2289                 //         fn method(&'a self) { .. }
2290                 //     }
2291                 //
2292                 // Because we start by lowering the `Foo<'a> for u32`
2293                 // part, we will add `'a` to the list of generics on
2294                 // the impl. When we then encounter it later in the
2295                 // method, it will not be considered an in-band
2296                 // lifetime to be added, but rather a reference to a
2297                 // parent lifetime.
2298                 let (generics, (trait_ref, lowered_ty)) = self.add_in_band_defs(
2299                     ast_generics,
2300                     def_id,
2301                     AnonymousLifetimeMode::CreateParameter,
2302                     |this| {
2303                         let trait_ref = trait_ref.as_ref().map(|trait_ref| {
2304                             this.lower_trait_ref(trait_ref, ImplTraitContext::Disallowed)
2305                         });
2306
2307                         if let Some(ref trait_ref) = trait_ref {
2308                             if let Def::Trait(def_id) = trait_ref.path.def {
2309                                 this.trait_impls.entry(def_id).or_insert(vec![]).push(id);
2310                             }
2311                         }
2312
2313                         let lowered_ty = this.lower_ty(ty, ImplTraitContext::Disallowed);
2314
2315                         (trait_ref, lowered_ty)
2316                     },
2317                 );
2318
2319                 let new_impl_items = self.with_in_scope_lifetime_defs(
2320                     ast_generics.params.iter().filter_map(|p| match p {
2321                         GenericParam::Lifetime(ld) => Some(ld),
2322                         _ => None,
2323                     }),
2324                     |this| {
2325                         impl_items
2326                             .iter()
2327                             .map(|item| this.lower_impl_item_ref(item))
2328                             .collect()
2329                     },
2330                 );
2331
2332                 hir::ItemImpl(
2333                     self.lower_unsafety(unsafety),
2334                     self.lower_impl_polarity(polarity),
2335                     self.lower_defaultness(defaultness, true /* [1] */),
2336                     generics,
2337                     trait_ref,
2338                     lowered_ty,
2339                     new_impl_items,
2340                 )
2341             }
2342             ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => {
2343                 let bounds = self.lower_bounds(bounds, ImplTraitContext::Disallowed);
2344                 let items = items
2345                     .iter()
2346                     .map(|item| self.lower_trait_item_ref(item))
2347                     .collect();
2348                 hir::ItemTrait(
2349                     self.lower_is_auto(is_auto),
2350                     self.lower_unsafety(unsafety),
2351                     self.lower_generics(generics, ImplTraitContext::Disallowed),
2352                     bounds,
2353                     items,
2354                 )
2355             }
2356             ItemKind::TraitAlias(ref generics, ref bounds) => hir::ItemTraitAlias(
2357                 self.lower_generics(generics, ImplTraitContext::Disallowed),
2358                 self.lower_bounds(bounds, ImplTraitContext::Disallowed),
2359             ),
2360             ItemKind::MacroDef(..) | ItemKind::Mac(..) => panic!("Shouldn't still be around"),
2361         }
2362
2363         // [1] `defaultness.has_value()` is never called for an `impl`, always `true` in order to
2364         //     not cause an assertion failure inside the `lower_defaultness` function
2365     }
2366
2367     fn lower_use_tree(
2368         &mut self,
2369         tree: &UseTree,
2370         prefix: &Path,
2371         id: NodeId,
2372         vis: &mut hir::Visibility,
2373         name: &mut Name,
2374         attrs: &hir::HirVec<Attribute>,
2375     ) -> hir::Item_ {
2376         let path = &tree.prefix;
2377
2378         match tree.kind {
2379             UseTreeKind::Simple(rename, id1, id2) => {
2380                 *name = tree.ident().name;
2381
2382                 // First apply the prefix to the path
2383                 let mut path = Path {
2384                     segments: prefix
2385                         .segments
2386                         .iter()
2387                         .chain(path.segments.iter())
2388                         .cloned()
2389                         .collect(),
2390                     span: path.span,
2391                 };
2392
2393                 // Correctly resolve `self` imports
2394                 if path.segments.len() > 1
2395                     && path.segments.last().unwrap().ident.name == keywords::SelfValue.name()
2396                 {
2397                     let _ = path.segments.pop();
2398                     if rename.is_none() {
2399                         *name = path.segments.last().unwrap().ident.name;
2400                     }
2401                 }
2402
2403                 let parent_def_index = self.current_hir_id_owner.last().unwrap().0;
2404                 let mut defs = self.expect_full_def_from_use(id);
2405                 // we want to return *something* from this function, so hang onto the first item
2406                 // for later
2407                 let mut ret_def = defs.next().unwrap_or(Def::Err);
2408
2409                 for (def, &new_node_id) in defs.zip([id1, id2].iter()) {
2410                     let vis = vis.clone();
2411                     let name = name.clone();
2412                     let span = path.span;
2413                     self.resolver.definitions().create_def_with_parent(
2414                         parent_def_index,
2415                         new_node_id,
2416                         DefPathData::Misc,
2417                         DefIndexAddressSpace::High,
2418                         Mark::root(),
2419                         span);
2420                     self.allocate_hir_id_counter(new_node_id, &path);
2421
2422                     self.with_hir_id_owner(new_node_id, |this| {
2423                         let new_id = this.lower_node_id(new_node_id);
2424                         let path = this.lower_path_extra(def, &path, None, ParamMode::Explicit);
2425                         let item = hir::ItemUse(P(path), hir::UseKind::Single);
2426                         let vis = match vis {
2427                             hir::Visibility::Public => hir::Visibility::Public,
2428                             hir::Visibility::Crate(sugar) => hir::Visibility::Crate(sugar),
2429                             hir::Visibility::Inherited => hir::Visibility::Inherited,
2430                             hir::Visibility::Restricted { ref path, id: _ } => {
2431                                 hir::Visibility::Restricted {
2432                                     path: path.clone(),
2433                                     // We are allocating a new NodeId here
2434                                     id: this.next_id().node_id,
2435                                 }
2436                             }
2437                         };
2438
2439                         this.items.insert(
2440                             new_id.node_id,
2441                             hir::Item {
2442                                 id: new_id.node_id,
2443                                 hir_id: new_id.hir_id,
2444                                 name: name,
2445                                 attrs: attrs.clone(),
2446                                 node: item,
2447                                 vis,
2448                                 span,
2449                             },
2450                         );
2451                     });
2452                 }
2453
2454                 let path = P(self.lower_path_extra(ret_def, &path, None, ParamMode::Explicit));
2455                 hir::ItemUse(path, hir::UseKind::Single)
2456             }
2457             UseTreeKind::Glob => {
2458                 let path = P(self.lower_path(
2459                     id,
2460                     &Path {
2461                         segments: prefix
2462                             .segments
2463                             .iter()
2464                             .chain(path.segments.iter())
2465                             .cloned()
2466                             .collect(),
2467                         span: path.span,
2468                     },
2469                     ParamMode::Explicit,
2470                 ));
2471                 hir::ItemUse(path, hir::UseKind::Glob)
2472             }
2473             UseTreeKind::Nested(ref trees) => {
2474                 let prefix = Path {
2475                     segments: prefix
2476                         .segments
2477                         .iter()
2478                         .chain(path.segments.iter())
2479                         .cloned()
2480                         .collect(),
2481                     span: prefix.span.to(path.span),
2482                 };
2483
2484                 // Add all the nested PathListItems in the HIR
2485                 for &(ref use_tree, id) in trees {
2486                     self.allocate_hir_id_counter(id, &use_tree);
2487                     let LoweredNodeId {
2488                         node_id: new_id,
2489                         hir_id: new_hir_id,
2490                     } = self.lower_node_id(id);
2491
2492                     let mut vis = vis.clone();
2493                     let mut name = name.clone();
2494                     let item =
2495                         self.lower_use_tree(use_tree, &prefix, new_id, &mut vis, &mut name, &attrs);
2496
2497                     self.with_hir_id_owner(new_id, |this| {
2498                         let vis = match vis {
2499                             hir::Visibility::Public => hir::Visibility::Public,
2500                             hir::Visibility::Crate(sugar) => hir::Visibility::Crate(sugar),
2501                             hir::Visibility::Inherited => hir::Visibility::Inherited,
2502                             hir::Visibility::Restricted { ref path, id: _ } => {
2503                                 hir::Visibility::Restricted {
2504                                     path: path.clone(),
2505                                     // We are allocating a new NodeId here
2506                                     id: this.next_id().node_id,
2507                                 }
2508                             }
2509                         };
2510
2511                         this.items.insert(
2512                             new_id,
2513                             hir::Item {
2514                                 id: new_id,
2515                                 hir_id: new_hir_id,
2516                                 name: name,
2517                                 attrs: attrs.clone(),
2518                                 node: item,
2519                                 vis,
2520                                 span: use_tree.span,
2521                             },
2522                         );
2523                     });
2524                 }
2525
2526                 // Privatize the degenerate import base, used only to check
2527                 // the stability of `use a::{};`, to avoid it showing up as
2528                 // a re-export by accident when `pub`, e.g. in documentation.
2529                 let path = P(self.lower_path(id, &prefix, ParamMode::Explicit));
2530                 *vis = hir::Inherited;
2531                 hir::ItemUse(path, hir::UseKind::ListStem)
2532             }
2533         }
2534     }
2535
2536     fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
2537         let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id);
2538         let trait_item_def_id = self.resolver.definitions().local_def_id(node_id);
2539
2540         let (generics, node) = match i.node {
2541             TraitItemKind::Const(ref ty, ref default) => (
2542                 self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
2543                 hir::TraitItemKind::Const(
2544                     self.lower_ty(ty, ImplTraitContext::Disallowed),
2545                     default
2546                         .as_ref()
2547                         .map(|x| self.lower_body(None, |this| this.lower_expr(x))),
2548                 ),
2549             ),
2550             TraitItemKind::Method(ref sig, None) => {
2551                 let names = self.lower_fn_args_to_names(&sig.decl);
2552                 self.add_in_band_defs(
2553                     &i.generics,
2554                     trait_item_def_id,
2555                     AnonymousLifetimeMode::PassThrough,
2556                     |this| {
2557                         hir::TraitItemKind::Method(
2558                             this.lower_method_sig(sig, trait_item_def_id, false),
2559                             hir::TraitMethod::Required(names),
2560                         )
2561                     },
2562                 )
2563             }
2564             TraitItemKind::Method(ref sig, Some(ref body)) => {
2565                 let body_id = self.lower_body(Some(&sig.decl), |this| {
2566                     let body = this.lower_block(body, false);
2567                     this.expr_block(body, ThinVec::new())
2568                 });
2569
2570                 self.add_in_band_defs(
2571                     &i.generics,
2572                     trait_item_def_id,
2573                     AnonymousLifetimeMode::PassThrough,
2574                     |this| {
2575                         hir::TraitItemKind::Method(
2576                             this.lower_method_sig(sig, trait_item_def_id, false),
2577                             hir::TraitMethod::Provided(body_id),
2578                         )
2579                     },
2580                 )
2581             }
2582             TraitItemKind::Type(ref bounds, ref default) => (
2583                 self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
2584                 hir::TraitItemKind::Type(
2585                     self.lower_bounds(bounds, ImplTraitContext::Disallowed),
2586                     default
2587                         .as_ref()
2588                         .map(|x| self.lower_ty(x, ImplTraitContext::Disallowed)),
2589                 ),
2590             ),
2591             TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"),
2592         };
2593
2594         hir::TraitItem {
2595             id: node_id,
2596             hir_id,
2597             name: self.lower_ident(i.ident),
2598             attrs: self.lower_attrs(&i.attrs),
2599             generics,
2600             node,
2601             span: i.span,
2602         }
2603     }
2604
2605     fn lower_trait_item_ref(&mut self, i: &TraitItem) -> hir::TraitItemRef {
2606         let (kind, has_default) = match i.node {
2607             TraitItemKind::Const(_, ref default) => {
2608                 (hir::AssociatedItemKind::Const, default.is_some())
2609             }
2610             TraitItemKind::Type(_, ref default) => {
2611                 (hir::AssociatedItemKind::Type, default.is_some())
2612             }
2613             TraitItemKind::Method(ref sig, ref default) => (
2614                 hir::AssociatedItemKind::Method {
2615                     has_self: sig.decl.has_self(),
2616                 },
2617                 default.is_some(),
2618             ),
2619             TraitItemKind::Macro(..) => unimplemented!(),
2620         };
2621         hir::TraitItemRef {
2622             id: hir::TraitItemId { node_id: i.id },
2623             name: self.lower_ident(i.ident),
2624             span: i.span,
2625             defaultness: self.lower_defaultness(Defaultness::Default, has_default),
2626             kind,
2627         }
2628     }
2629
2630     fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
2631         let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id);
2632         let impl_item_def_id = self.resolver.definitions().local_def_id(node_id);
2633
2634         let (generics, node) = match i.node {
2635             ImplItemKind::Const(ref ty, ref expr) => {
2636                 let body_id = self.lower_body(None, |this| this.lower_expr(expr));
2637                 (
2638                     self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
2639                     hir::ImplItemKind::Const(
2640                         self.lower_ty(ty, ImplTraitContext::Disallowed),
2641                         body_id,
2642                     ),
2643                 )
2644             }
2645             ImplItemKind::Method(ref sig, ref body) => {
2646                 let body_id = self.lower_body(Some(&sig.decl), |this| {
2647                     let body = this.lower_block(body, false);
2648                     this.expr_block(body, ThinVec::new())
2649                 });
2650                 let impl_trait_return_allow = !self.is_in_trait_impl;
2651
2652                 self.add_in_band_defs(
2653                     &i.generics,
2654                     impl_item_def_id,
2655                     AnonymousLifetimeMode::PassThrough,
2656                     |this| {
2657                         hir::ImplItemKind::Method(
2658                             this.lower_method_sig(
2659                                 sig,
2660                                 impl_item_def_id,
2661                                 impl_trait_return_allow,
2662                             ),
2663                             body_id,
2664                         )
2665                     },
2666                 )
2667             }
2668             ImplItemKind::Type(ref ty) => (
2669                 self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
2670                 hir::ImplItemKind::Type(self.lower_ty(ty, ImplTraitContext::Disallowed)),
2671             ),
2672             ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
2673         };
2674
2675         hir::ImplItem {
2676             id: node_id,
2677             hir_id,
2678             name: self.lower_ident(i.ident),
2679             attrs: self.lower_attrs(&i.attrs),
2680             generics,
2681             vis: self.lower_visibility(&i.vis, None),
2682             defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
2683             node,
2684             span: i.span,
2685         }
2686
2687         // [1] since `default impl` is not yet implemented, this is always true in impls
2688     }
2689
2690     fn lower_impl_item_ref(&mut self, i: &ImplItem) -> hir::ImplItemRef {
2691         hir::ImplItemRef {
2692             id: hir::ImplItemId { node_id: i.id },
2693             name: self.lower_ident(i.ident),
2694             span: i.span,
2695             vis: self.lower_visibility(&i.vis, Some(i.id)),
2696             defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
2697             kind: match i.node {
2698                 ImplItemKind::Const(..) => hir::AssociatedItemKind::Const,
2699                 ImplItemKind::Type(..) => hir::AssociatedItemKind::Type,
2700                 ImplItemKind::Method(ref sig, _) => hir::AssociatedItemKind::Method {
2701                     has_self: sig.decl.has_self(),
2702                 },
2703                 ImplItemKind::Macro(..) => unimplemented!(),
2704             },
2705         }
2706
2707         // [1] since `default impl` is not yet implemented, this is always true in impls
2708     }
2709
2710     fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
2711         hir::Mod {
2712             inner: m.inner,
2713             item_ids: m.items.iter().flat_map(|x| self.lower_item_id(x)).collect(),
2714         }
2715     }
2716
2717     fn lower_item_id(&mut self, i: &Item) -> SmallVector<hir::ItemId> {
2718         match i.node {
2719             ItemKind::Use(ref use_tree) => {
2720                 let mut vec = SmallVector::one(hir::ItemId { id: i.id });
2721                 self.lower_item_id_use_tree(use_tree, i.id, &mut vec);
2722                 return vec;
2723             }
2724             ItemKind::MacroDef(..) => return SmallVector::new(),
2725             _ => {}
2726         }
2727         SmallVector::one(hir::ItemId { id: i.id })
2728     }
2729
2730     fn lower_item_id_use_tree(&mut self,
2731                               tree: &UseTree,
2732                               base_id: NodeId,
2733                               vec: &mut SmallVector<hir::ItemId>)
2734     {
2735         match tree.kind {
2736             UseTreeKind::Nested(ref nested_vec) => for &(ref nested, id) in nested_vec {
2737                 vec.push(hir::ItemId { id });
2738                 self.lower_item_id_use_tree(nested, id, vec);
2739             },
2740             UseTreeKind::Glob => {}
2741             UseTreeKind::Simple(_, id1, id2) => {
2742                 for (_, &id) in self.expect_full_def_from_use(base_id)
2743                                     .skip(1)
2744                                     .zip([id1, id2].iter())
2745                 {
2746                     vec.push(hir::ItemId { id });
2747                 }
2748             },
2749         }
2750     }
2751
2752     pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item> {
2753         let mut name = i.ident.name;
2754         let mut vis = self.lower_visibility(&i.vis, None);
2755         let attrs = self.lower_attrs(&i.attrs);
2756         if let ItemKind::MacroDef(ref def) = i.node {
2757             if !def.legacy || attr::contains_name(&i.attrs, "macro_export") {
2758                 let body = self.lower_token_stream(def.stream());
2759                 self.exported_macros.push(hir::MacroDef {
2760                     name,
2761                     vis,
2762                     attrs,
2763                     id: i.id,
2764                     span: i.span,
2765                     body,
2766                     legacy: def.legacy,
2767                 });
2768             }
2769             return None;
2770         }
2771
2772         let node = self.lower_item_kind(i.id, &mut name, &attrs, &mut vis, &i.node);
2773
2774         let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id);
2775
2776         Some(hir::Item {
2777             id: node_id,
2778             hir_id,
2779             name,
2780             attrs,
2781             node,
2782             vis,
2783             span: i.span,
2784         })
2785     }
2786
2787     fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
2788         let node_id = self.lower_node_id(i.id).node_id;
2789         let def_id = self.resolver.definitions().local_def_id(node_id);
2790         hir::ForeignItem {
2791             id: node_id,
2792             name: i.ident.name,
2793             attrs: self.lower_attrs(&i.attrs),
2794             node: match i.node {
2795                 ForeignItemKind::Fn(ref fdec, ref generics) => {
2796                     let (generics, (fn_dec, fn_args)) = self.add_in_band_defs(
2797                         generics,
2798                         def_id,
2799                         AnonymousLifetimeMode::PassThrough,
2800                         |this| {
2801                             (
2802                                 // Disallow impl Trait in foreign items
2803                                 this.lower_fn_decl(fdec, None, false),
2804                                 this.lower_fn_args_to_names(fdec),
2805                             )
2806                         },
2807                     );
2808
2809                     hir::ForeignItemFn(fn_dec, fn_args, generics)
2810                 }
2811                 ForeignItemKind::Static(ref t, m) => {
2812                     hir::ForeignItemStatic(self.lower_ty(t, ImplTraitContext::Disallowed), m)
2813                 }
2814                 ForeignItemKind::Ty => hir::ForeignItemType,
2815                 ForeignItemKind::Macro(_) => panic!("shouldn't exist here"),
2816             },
2817             vis: self.lower_visibility(&i.vis, None),
2818             span: i.span,
2819         }
2820     }
2821
2822     fn lower_method_sig(
2823         &mut self,
2824         sig: &MethodSig,
2825         fn_def_id: DefId,
2826         impl_trait_return_allow: bool,
2827     ) -> hir::MethodSig {
2828         hir::MethodSig {
2829             abi: sig.abi,
2830             unsafety: self.lower_unsafety(sig.unsafety),
2831             constness: self.lower_constness(sig.constness),
2832             decl: self.lower_fn_decl(&sig.decl, Some(fn_def_id), impl_trait_return_allow),
2833         }
2834     }
2835
2836     fn lower_is_auto(&mut self, a: IsAuto) -> hir::IsAuto {
2837         match a {
2838             IsAuto::Yes => hir::IsAuto::Yes,
2839             IsAuto::No => hir::IsAuto::No,
2840         }
2841     }
2842
2843     fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
2844         match u {
2845             Unsafety::Unsafe => hir::Unsafety::Unsafe,
2846             Unsafety::Normal => hir::Unsafety::Normal,
2847         }
2848     }
2849
2850     fn lower_constness(&mut self, c: Spanned<Constness>) -> hir::Constness {
2851         match c.node {
2852             Constness::Const => hir::Constness::Const,
2853             Constness::NotConst => hir::Constness::NotConst,
2854         }
2855     }
2856
2857     fn lower_unop(&mut self, u: UnOp) -> hir::UnOp {
2858         match u {
2859             UnOp::Deref => hir::UnDeref,
2860             UnOp::Not => hir::UnNot,
2861             UnOp::Neg => hir::UnNeg,
2862         }
2863     }
2864
2865     fn lower_binop(&mut self, b: BinOp) -> hir::BinOp {
2866         Spanned {
2867             node: match b.node {
2868                 BinOpKind::Add => hir::BiAdd,
2869                 BinOpKind::Sub => hir::BiSub,
2870                 BinOpKind::Mul => hir::BiMul,
2871                 BinOpKind::Div => hir::BiDiv,
2872                 BinOpKind::Rem => hir::BiRem,
2873                 BinOpKind::And => hir::BiAnd,
2874                 BinOpKind::Or => hir::BiOr,
2875                 BinOpKind::BitXor => hir::BiBitXor,
2876                 BinOpKind::BitAnd => hir::BiBitAnd,
2877                 BinOpKind::BitOr => hir::BiBitOr,
2878                 BinOpKind::Shl => hir::BiShl,
2879                 BinOpKind::Shr => hir::BiShr,
2880                 BinOpKind::Eq => hir::BiEq,
2881                 BinOpKind::Lt => hir::BiLt,
2882                 BinOpKind::Le => hir::BiLe,
2883                 BinOpKind::Ne => hir::BiNe,
2884                 BinOpKind::Ge => hir::BiGe,
2885                 BinOpKind::Gt => hir::BiGt,
2886             },
2887             span: b.span,
2888         }
2889     }
2890
2891     fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
2892         let node = match p.node {
2893             PatKind::Wild => hir::PatKind::Wild,
2894             PatKind::Ident(ref binding_mode, ident, ref sub) => {
2895                 match self.resolver.get_resolution(p.id).map(|d| d.base_def()) {
2896                     // `None` can occur in body-less function signatures
2897                     def @ None | def @ Some(Def::Local(_)) => {
2898                         let canonical_id = match def {
2899                             Some(Def::Local(id)) => id,
2900                             _ => p.id,
2901                         };
2902                         hir::PatKind::Binding(
2903                             self.lower_binding_mode(binding_mode),
2904                             canonical_id,
2905                             respan(ident.span, ident.name),
2906                             sub.as_ref().map(|x| self.lower_pat(x)),
2907                         )
2908                     }
2909                     Some(def) => hir::PatKind::Path(hir::QPath::Resolved(
2910                         None,
2911                         P(hir::Path {
2912                             span: ident.span,
2913                             def,
2914                             segments: hir_vec![hir::PathSegment::from_name(ident.name)],
2915                         }),
2916                     )),
2917                 }
2918             }
2919             PatKind::Lit(ref e) => hir::PatKind::Lit(P(self.lower_expr(e))),
2920             PatKind::TupleStruct(ref path, ref pats, ddpos) => {
2921                 let qpath = self.lower_qpath(
2922                     p.id,
2923                     &None,
2924                     path,
2925                     ParamMode::Optional,
2926                     ImplTraitContext::Disallowed,
2927                 );
2928                 hir::PatKind::TupleStruct(
2929                     qpath,
2930                     pats.iter().map(|x| self.lower_pat(x)).collect(),
2931                     ddpos,
2932                 )
2933             }
2934             PatKind::Path(ref qself, ref path) => hir::PatKind::Path(self.lower_qpath(
2935                 p.id,
2936                 qself,
2937                 path,
2938                 ParamMode::Optional,
2939                 ImplTraitContext::Disallowed,
2940             )),
2941             PatKind::Struct(ref path, ref fields, etc) => {
2942                 let qpath = self.lower_qpath(
2943                     p.id,
2944                     &None,
2945                     path,
2946                     ParamMode::Optional,
2947                     ImplTraitContext::Disallowed,
2948                 );
2949
2950                 let fs = fields
2951                     .iter()
2952                     .map(|f| Spanned {
2953                         span: f.span,
2954                         node: hir::FieldPat {
2955                             id: self.next_id().node_id,
2956                             ident: f.node.ident,
2957                             pat: self.lower_pat(&f.node.pat),
2958                             is_shorthand: f.node.is_shorthand,
2959                         },
2960                     })
2961                     .collect();
2962                 hir::PatKind::Struct(qpath, fs, etc)
2963             }
2964             PatKind::Tuple(ref elts, ddpos) => {
2965                 hir::PatKind::Tuple(elts.iter().map(|x| self.lower_pat(x)).collect(), ddpos)
2966             }
2967             PatKind::Box(ref inner) => hir::PatKind::Box(self.lower_pat(inner)),
2968             PatKind::Ref(ref inner, mutbl) => {
2969                 hir::PatKind::Ref(self.lower_pat(inner), self.lower_mutability(mutbl))
2970             }
2971             PatKind::Range(ref e1, ref e2, ref end) => hir::PatKind::Range(
2972                 P(self.lower_expr(e1)),
2973                 P(self.lower_expr(e2)),
2974                 self.lower_range_end(end),
2975             ),
2976             PatKind::Slice(ref before, ref slice, ref after) => hir::PatKind::Slice(
2977                 before.iter().map(|x| self.lower_pat(x)).collect(),
2978                 slice.as_ref().map(|x| self.lower_pat(x)),
2979                 after.iter().map(|x| self.lower_pat(x)).collect(),
2980             ),
2981             PatKind::Paren(ref inner) => return self.lower_pat(inner),
2982             PatKind::Mac(_) => panic!("Shouldn't exist here"),
2983         };
2984
2985         let LoweredNodeId { node_id, hir_id } = self.lower_node_id(p.id);
2986         P(hir::Pat {
2987             id: node_id,
2988             hir_id,
2989             node,
2990             span: p.span,
2991         })
2992     }
2993
2994     fn lower_range_end(&mut self, e: &RangeEnd) -> hir::RangeEnd {
2995         match *e {
2996             RangeEnd::Included(_) => hir::RangeEnd::Included,
2997             RangeEnd::Excluded => hir::RangeEnd::Excluded,
2998         }
2999     }
3000
3001     fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
3002         let LoweredNodeId { node_id, hir_id } = self.lower_node_id(c.id);
3003
3004         hir::AnonConst {
3005             id: node_id,
3006             hir_id,
3007             body: self.lower_body(None, |this| this.lower_expr(&c.value)),
3008         }
3009     }
3010
3011     fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
3012         let kind = match e.node {
3013             ExprKind::Box(ref inner) => hir::ExprBox(P(self.lower_expr(inner))),
3014             ExprKind::ObsoleteInPlace(..) => {
3015                 self.sess.abort_if_errors();
3016                 span_bug!(e.span, "encountered ObsoleteInPlace expr during lowering");
3017             }
3018             ExprKind::Array(ref exprs) => {
3019                 hir::ExprArray(exprs.iter().map(|x| self.lower_expr(x)).collect())
3020             }
3021             ExprKind::Repeat(ref expr, ref count) => {
3022                 let expr = P(self.lower_expr(expr));
3023                 let count = self.lower_anon_const(count);
3024                 hir::ExprRepeat(expr, count)
3025             }
3026             ExprKind::Tup(ref elts) => {
3027                 hir::ExprTup(elts.iter().map(|x| self.lower_expr(x)).collect())
3028             }
3029             ExprKind::Call(ref f, ref args) => {
3030                 let f = P(self.lower_expr(f));
3031                 hir::ExprCall(f, args.iter().map(|x| self.lower_expr(x)).collect())
3032             }
3033             ExprKind::MethodCall(ref seg, ref args) => {
3034                 let hir_seg = self.lower_path_segment(
3035                     e.span,
3036                     seg,
3037                     ParamMode::Optional,
3038                     0,
3039                     ParenthesizedGenericArgs::Err,
3040                     ImplTraitContext::Disallowed,
3041                 );
3042                 let args = args.iter().map(|x| self.lower_expr(x)).collect();
3043                 hir::ExprMethodCall(hir_seg, seg.ident.span, args)
3044             }
3045             ExprKind::Binary(binop, ref lhs, ref rhs) => {
3046                 let binop = self.lower_binop(binop);
3047                 let lhs = P(self.lower_expr(lhs));
3048                 let rhs = P(self.lower_expr(rhs));
3049                 hir::ExprBinary(binop, lhs, rhs)
3050             }
3051             ExprKind::Unary(op, ref ohs) => {
3052                 let op = self.lower_unop(op);
3053                 let ohs = P(self.lower_expr(ohs));
3054                 hir::ExprUnary(op, ohs)
3055             }
3056             ExprKind::Lit(ref l) => hir::ExprLit(P((**l).clone())),
3057             ExprKind::Cast(ref expr, ref ty) => {
3058                 let expr = P(self.lower_expr(expr));
3059                 hir::ExprCast(expr, self.lower_ty(ty, ImplTraitContext::Disallowed))
3060             }
3061             ExprKind::Type(ref expr, ref ty) => {
3062                 let expr = P(self.lower_expr(expr));
3063                 hir::ExprType(expr, self.lower_ty(ty, ImplTraitContext::Disallowed))
3064             }
3065             ExprKind::AddrOf(m, ref ohs) => {
3066                 let m = self.lower_mutability(m);
3067                 let ohs = P(self.lower_expr(ohs));
3068                 hir::ExprAddrOf(m, ohs)
3069             }
3070             // More complicated than you might expect because the else branch
3071             // might be `if let`.
3072             ExprKind::If(ref cond, ref blk, ref else_opt) => {
3073                 let else_opt = else_opt.as_ref().map(|els| {
3074                     match els.node {
3075                         ExprKind::IfLet(..) => {
3076                             // wrap the if-let expr in a block
3077                             let span = els.span;
3078                             let els = P(self.lower_expr(els));
3079                             let LoweredNodeId { node_id, hir_id } = self.next_id();
3080                             let blk = P(hir::Block {
3081                                 stmts: hir_vec![],
3082                                 expr: Some(els),
3083                                 id: node_id,
3084                                 hir_id,
3085                                 rules: hir::DefaultBlock,
3086                                 span,
3087                                 targeted_by_break: false,
3088                                 recovered: blk.recovered,
3089                             });
3090                             P(self.expr_block(blk, ThinVec::new()))
3091                         }
3092                         _ => P(self.lower_expr(els)),
3093                     }
3094                 });
3095
3096                 let then_blk = self.lower_block(blk, false);
3097                 let then_expr = self.expr_block(then_blk, ThinVec::new());
3098
3099                 hir::ExprIf(P(self.lower_expr(cond)), P(then_expr), else_opt)
3100             }
3101             ExprKind::While(ref cond, ref body, opt_label) => self.with_loop_scope(e.id, |this| {
3102                 hir::ExprWhile(
3103                     this.with_loop_condition_scope(|this| P(this.lower_expr(cond))),
3104                     this.lower_block(body, false),
3105                     this.lower_label(opt_label),
3106                 )
3107             }),
3108             ExprKind::Loop(ref body, opt_label) => self.with_loop_scope(e.id, |this| {
3109                 hir::ExprLoop(
3110                     this.lower_block(body, false),
3111                     this.lower_label(opt_label),
3112                     hir::LoopSource::Loop,
3113                 )
3114             }),
3115             ExprKind::Catch(ref body) => {
3116                 self.with_catch_scope(body.id, |this| {
3117                     let unstable_span =
3118                         this.allow_internal_unstable(CompilerDesugaringKind::Catch, body.span);
3119                     let mut block = this.lower_block(body, true).into_inner();
3120                     let tail = block.expr.take().map_or_else(
3121                         || {
3122                             let LoweredNodeId { node_id, hir_id } = this.next_id();
3123                             let span = this.sess.codemap().end_point(unstable_span);
3124                             hir::Expr {
3125                                 id: node_id,
3126                                 span,
3127                                 node: hir::ExprTup(hir_vec![]),
3128                                 attrs: ThinVec::new(),
3129                                 hir_id,
3130                             }
3131                         },
3132                         |x: P<hir::Expr>| x.into_inner(),
3133                     );
3134                     block.expr = Some(this.wrap_in_try_constructor(
3135                         "from_ok", tail, unstable_span));
3136                     hir::ExprBlock(P(block), None)
3137                 })
3138             }
3139             ExprKind::Match(ref expr, ref arms) => hir::ExprMatch(
3140                 P(self.lower_expr(expr)),
3141                 arms.iter().map(|x| self.lower_arm(x)).collect(),
3142                 hir::MatchSource::Normal,
3143             ),
3144             ExprKind::Closure(capture_clause, movability, ref decl, ref body, fn_decl_span) => {
3145                 self.with_new_scopes(|this| {
3146                     let mut is_generator = false;
3147                     let body_id = this.lower_body(Some(decl), |this| {
3148                         let e = this.lower_expr(body);
3149                         is_generator = this.is_generator;
3150                         e
3151                     });
3152                     let generator_option = if is_generator {
3153                         if !decl.inputs.is_empty() {
3154                             span_err!(
3155                                 this.sess,
3156                                 fn_decl_span,
3157                                 E0628,
3158                                 "generators cannot have explicit arguments"
3159                             );
3160                             this.sess.abort_if_errors();
3161                         }
3162                         Some(match movability {
3163                             Movability::Movable => hir::GeneratorMovability::Movable,
3164                             Movability::Static => hir::GeneratorMovability::Static,
3165                         })
3166                     } else {
3167                         if movability == Movability::Static {
3168                             span_err!(
3169                                 this.sess,
3170                                 fn_decl_span,
3171                                 E0697,
3172                                 "closures cannot be static"
3173                             );
3174                         }
3175                         None
3176                     };
3177                     hir::ExprClosure(
3178                         this.lower_capture_clause(capture_clause),
3179                         this.lower_fn_decl(decl, None, false),
3180                         body_id,
3181                         fn_decl_span,
3182                         generator_option,
3183                     )
3184                 })
3185             }
3186             ExprKind::Block(ref blk, opt_label) => {
3187                 hir::ExprBlock(self.lower_block(blk,
3188                                                 opt_label.is_some()),
3189                                                 self.lower_label(opt_label))
3190             }
3191             ExprKind::Assign(ref el, ref er) => {
3192                 hir::ExprAssign(P(self.lower_expr(el)), P(self.lower_expr(er)))
3193             }
3194             ExprKind::AssignOp(op, ref el, ref er) => hir::ExprAssignOp(
3195                 self.lower_binop(op),
3196                 P(self.lower_expr(el)),
3197                 P(self.lower_expr(er)),
3198             ),
3199             ExprKind::Field(ref el, ident) => hir::ExprField(P(self.lower_expr(el)), ident),
3200             ExprKind::Index(ref el, ref er) => {
3201                 hir::ExprIndex(P(self.lower_expr(el)), P(self.lower_expr(er)))
3202             }
3203             // Desugar `<start>..=<end>` to `std::ops::RangeInclusive::new(<start>, <end>)`
3204             ExprKind::Range(Some(ref e1), Some(ref e2), RangeLimits::Closed) => {
3205                 // FIXME: Use e.span directly after RangeInclusive::new() is stabilized in stage0.
3206                 let span = self.allow_internal_unstable(CompilerDesugaringKind::DotFill, e.span);
3207                 let id = self.next_id();
3208                 let e1 = self.lower_expr(e1);
3209                 let e2 = self.lower_expr(e2);
3210                 let ty_path = P(self.std_path(span, &["ops", "RangeInclusive"], false));
3211                 let ty = self.ty_path(id, span, hir::QPath::Resolved(None, ty_path));
3212                 let new_seg = P(hir::PathSegment::from_name(Symbol::intern("new")));
3213                 let new_path = hir::QPath::TypeRelative(ty, new_seg);
3214                 let new = P(self.expr(span, hir::ExprPath(new_path), ThinVec::new()));
3215                 hir::ExprCall(new, hir_vec![e1, e2])
3216             }
3217             ExprKind::Range(ref e1, ref e2, lims) => {
3218                 use syntax::ast::RangeLimits::*;
3219
3220                 let path = match (e1, e2, lims) {
3221                     (&None, &None, HalfOpen) => "RangeFull",
3222                     (&Some(..), &None, HalfOpen) => "RangeFrom",
3223                     (&None, &Some(..), HalfOpen) => "RangeTo",
3224                     (&Some(..), &Some(..), HalfOpen) => "Range",
3225                     (&None, &Some(..), Closed) => "RangeToInclusive",
3226                     (&Some(..), &Some(..), Closed) => unreachable!(),
3227                     (_, &None, Closed) => self.diagnostic()
3228                         .span_fatal(e.span, "inclusive range with no end")
3229                         .raise(),
3230                 };
3231
3232                 let fields = e1.iter()
3233                     .map(|e| ("start", e))
3234                     .chain(e2.iter().map(|e| ("end", e)))
3235                     .map(|(s, e)| {
3236                         let expr = P(self.lower_expr(&e));
3237                         let unstable_span =
3238                             self.allow_internal_unstable(CompilerDesugaringKind::DotFill, e.span);
3239                         let ident = Ident::new(Symbol::intern(s), unstable_span);
3240                         self.field(ident, expr, unstable_span)
3241                     })
3242                     .collect::<P<[hir::Field]>>();
3243
3244                 let is_unit = fields.is_empty();
3245                 let unstable_span =
3246                     self.allow_internal_unstable(CompilerDesugaringKind::DotFill, e.span);
3247                 let struct_path = iter::once("ops")
3248                     .chain(iter::once(path))
3249                     .collect::<Vec<_>>();
3250                 let struct_path = self.std_path(unstable_span, &struct_path, is_unit);
3251                 let struct_path = hir::QPath::Resolved(None, P(struct_path));
3252
3253                 let LoweredNodeId { node_id, hir_id } = self.lower_node_id(e.id);
3254
3255                 return hir::Expr {
3256                     id: node_id,
3257                     hir_id,
3258                     node: if is_unit {
3259                         hir::ExprPath(struct_path)
3260                     } else {
3261                         hir::ExprStruct(struct_path, fields, None)
3262                     },
3263                     span: unstable_span,
3264                     attrs: e.attrs.clone(),
3265                 };
3266             }
3267             ExprKind::Path(ref qself, ref path) => hir::ExprPath(self.lower_qpath(
3268                 e.id,
3269                 qself,
3270                 path,
3271                 ParamMode::Optional,
3272                 ImplTraitContext::Disallowed,
3273             )),
3274             ExprKind::Break(opt_label, ref opt_expr) => {
3275                 let destination = if self.is_in_loop_condition && opt_label.is_none() {
3276                     hir::Destination {
3277                         label: None,
3278                         target_id: Err(hir::LoopIdError::UnlabeledCfInWhileCondition).into(),
3279                     }
3280                 } else {
3281                     self.lower_loop_destination(opt_label.map(|label| (e.id, label)))
3282                 };
3283                 hir::ExprBreak(
3284                     destination,
3285                     opt_expr.as_ref().map(|x| P(self.lower_expr(x))),
3286                 )
3287             }
3288             ExprKind::Continue(opt_label) => {
3289                 hir::ExprAgain(if self.is_in_loop_condition && opt_label.is_none() {
3290                     hir::Destination {
3291                         label: None,
3292                         target_id: Err(hir::LoopIdError::UnlabeledCfInWhileCondition).into(),
3293                     }
3294                 } else {
3295                     self.lower_loop_destination(opt_label.map(|label| (e.id, label)))
3296                 })
3297             }
3298             ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| P(self.lower_expr(x)))),
3299             ExprKind::InlineAsm(ref asm) => {
3300                 let hir_asm = hir::InlineAsm {
3301                     inputs: asm.inputs.iter().map(|&(ref c, _)| c.clone()).collect(),
3302                     outputs: asm.outputs
3303                         .iter()
3304                         .map(|out| hir::InlineAsmOutput {
3305                             constraint: out.constraint.clone(),
3306                             is_rw: out.is_rw,
3307                             is_indirect: out.is_indirect,
3308                         })
3309                         .collect(),
3310                     asm: asm.asm.clone(),
3311                     asm_str_style: asm.asm_str_style,
3312                     clobbers: asm.clobbers.clone().into(),
3313                     volatile: asm.volatile,
3314                     alignstack: asm.alignstack,
3315                     dialect: asm.dialect,
3316                     ctxt: asm.ctxt,
3317                 };
3318                 let outputs = asm.outputs
3319                     .iter()
3320                     .map(|out| self.lower_expr(&out.expr))
3321                     .collect();
3322                 let inputs = asm.inputs
3323                     .iter()
3324                     .map(|&(_, ref input)| self.lower_expr(input))
3325                     .collect();
3326                 hir::ExprInlineAsm(P(hir_asm), outputs, inputs)
3327             }
3328             ExprKind::Struct(ref path, ref fields, ref maybe_expr) => hir::ExprStruct(
3329                 self.lower_qpath(
3330                     e.id,
3331                     &None,
3332                     path,
3333                     ParamMode::Optional,
3334                     ImplTraitContext::Disallowed,
3335                 ),
3336                 fields.iter().map(|x| self.lower_field(x)).collect(),
3337                 maybe_expr.as_ref().map(|x| P(self.lower_expr(x))),
3338             ),
3339             ExprKind::Paren(ref ex) => {
3340                 let mut ex = self.lower_expr(ex);
3341                 // include parens in span, but only if it is a super-span.
3342                 if e.span.contains(ex.span) {
3343                     ex.span = e.span;
3344                 }
3345                 // merge attributes into the inner expression.
3346                 let mut attrs = e.attrs.clone();
3347                 attrs.extend::<Vec<_>>(ex.attrs.into());
3348                 ex.attrs = attrs;
3349                 return ex;
3350             }
3351
3352             ExprKind::Yield(ref opt_expr) => {
3353                 self.is_generator = true;
3354                 let expr = opt_expr
3355                     .as_ref()
3356                     .map(|x| self.lower_expr(x))
3357                     .unwrap_or_else(|| self.expr(e.span, hir::ExprTup(hir_vec![]), ThinVec::new()));
3358                 hir::ExprYield(P(expr))
3359             }
3360
3361             // Desugar ExprIfLet
3362             // From: `if let <pat> = <sub_expr> <body> [<else_opt>]`
3363             ExprKind::IfLet(ref pats, ref sub_expr, ref body, ref else_opt) => {
3364                 // to:
3365                 //
3366                 //   match <sub_expr> {
3367                 //     <pat> => <body>,
3368                 //     _ => [<else_opt> | ()]
3369                 //   }
3370
3371                 let mut arms = vec![];
3372
3373                 // `<pat> => <body>`
3374                 {
3375                     let body = self.lower_block(body, false);
3376                     let body_expr = P(self.expr_block(body, ThinVec::new()));
3377                     let pats = pats.iter().map(|pat| self.lower_pat(pat)).collect();
3378                     arms.push(self.arm(pats, body_expr));
3379                 }
3380
3381                 // _ => [<else_opt>|()]
3382                 {
3383                     let wildcard_arm: Option<&Expr> = else_opt.as_ref().map(|p| &**p);
3384                     let wildcard_pattern = self.pat_wild(e.span);
3385                     let body = if let Some(else_expr) = wildcard_arm {
3386                         P(self.lower_expr(else_expr))
3387                     } else {
3388                         self.expr_tuple(e.span, hir_vec![])
3389                     };
3390                     arms.push(self.arm(hir_vec![wildcard_pattern], body));
3391                 }
3392
3393                 let contains_else_clause = else_opt.is_some();
3394
3395                 let sub_expr = P(self.lower_expr(sub_expr));
3396
3397                 hir::ExprMatch(
3398                     sub_expr,
3399                     arms.into(),
3400                     hir::MatchSource::IfLetDesugar {
3401                         contains_else_clause,
3402                     },
3403                 )
3404             }
3405
3406             // Desugar ExprWhileLet
3407             // From: `[opt_ident]: while let <pat> = <sub_expr> <body>`
3408             ExprKind::WhileLet(ref pats, ref sub_expr, ref body, opt_label) => {
3409                 // to:
3410                 //
3411                 //   [opt_ident]: loop {
3412                 //     match <sub_expr> {
3413                 //       <pat> => <body>,
3414                 //       _ => break
3415                 //     }
3416                 //   }
3417
3418                 // Note that the block AND the condition are evaluated in the loop scope.
3419                 // This is done to allow `break` from inside the condition of the loop.
3420                 let (body, break_expr, sub_expr) = self.with_loop_scope(e.id, |this| {
3421                     (
3422                         this.lower_block(body, false),
3423                         this.expr_break(e.span, ThinVec::new()),
3424                         this.with_loop_condition_scope(|this| P(this.lower_expr(sub_expr))),
3425                     )
3426                 });
3427
3428                 // `<pat> => <body>`
3429                 let pat_arm = {
3430                     let body_expr = P(self.expr_block(body, ThinVec::new()));
3431                     let pats = pats.iter().map(|pat| self.lower_pat(pat)).collect();
3432                     self.arm(pats, body_expr)
3433                 };
3434
3435                 // `_ => break`
3436                 let break_arm = {
3437                     let pat_under = self.pat_wild(e.span);
3438                     self.arm(hir_vec![pat_under], break_expr)
3439                 };
3440
3441                 // `match <sub_expr> { ... }`
3442                 let arms = hir_vec![pat_arm, break_arm];
3443                 let match_expr = self.expr(
3444                     sub_expr.span,
3445                     hir::ExprMatch(sub_expr, arms, hir::MatchSource::WhileLetDesugar),
3446                     ThinVec::new(),
3447                 );
3448
3449                 // `[opt_ident]: loop { ... }`
3450                 let loop_block = P(self.block_expr(P(match_expr)));
3451                 let loop_expr = hir::ExprLoop(
3452                     loop_block,
3453                     self.lower_label(opt_label),
3454                     hir::LoopSource::WhileLet,
3455                 );
3456                 // add attributes to the outer returned expr node
3457                 loop_expr
3458             }
3459
3460             // Desugar ExprForLoop
3461             // From: `[opt_ident]: for <pat> in <head> <body>`
3462             ExprKind::ForLoop(ref pat, ref head, ref body, opt_label) => {
3463                 // to:
3464                 //
3465                 //   {
3466                 //     let result = match ::std::iter::IntoIterator::into_iter(<head>) {
3467                 //       mut iter => {
3468                 //         [opt_ident]: loop {
3469                 //           let mut __next;
3470                 //           match ::std::iter::Iterator::next(&mut iter) {
3471                 //             ::std::option::Option::Some(val) => __next = val,
3472                 //             ::std::option::Option::None => break
3473                 //           };
3474                 //           let <pat> = __next;
3475                 //           StmtExpr(<body>);
3476                 //         }
3477                 //       }
3478                 //     };
3479                 //     result
3480                 //   }
3481
3482                 // expand <head>
3483                 let head = self.lower_expr(head);
3484                 let head_sp = head.span;
3485
3486                 let iter = self.str_to_ident("iter");
3487
3488                 let next_ident = self.str_to_ident("__next");
3489                 let next_pat = self.pat_ident_binding_mode(
3490                     pat.span,
3491                     next_ident,
3492                     hir::BindingAnnotation::Mutable,
3493                 );
3494
3495                 // `::std::option::Option::Some(val) => next = val`
3496                 let pat_arm = {
3497                     let val_ident = self.str_to_ident("val");
3498                     let val_pat = self.pat_ident(pat.span, val_ident);
3499                     let val_expr = P(self.expr_ident(pat.span, val_ident, val_pat.id));
3500                     let next_expr = P(self.expr_ident(pat.span, next_ident, next_pat.id));
3501                     let assign = P(self.expr(
3502                         pat.span,
3503                         hir::ExprAssign(next_expr, val_expr),
3504                         ThinVec::new(),
3505                     ));
3506                     let some_pat = self.pat_some(pat.span, val_pat);
3507                     self.arm(hir_vec![some_pat], assign)
3508                 };
3509
3510                 // `::std::option::Option::None => break`
3511                 let break_arm = {
3512                     let break_expr =
3513                         self.with_loop_scope(e.id, |this| this.expr_break(e.span, ThinVec::new()));
3514                     let pat = self.pat_none(e.span);
3515                     self.arm(hir_vec![pat], break_expr)
3516                 };
3517
3518                 // `mut iter`
3519                 let iter_pat =
3520                     self.pat_ident_binding_mode(head_sp, iter, hir::BindingAnnotation::Mutable);
3521
3522                 // `match ::std::iter::Iterator::next(&mut iter) { ... }`
3523                 let match_expr = {
3524                     let iter = P(self.expr_ident(head_sp, iter, iter_pat.id));
3525                     let ref_mut_iter = self.expr_mut_addr_of(head_sp, iter);
3526                     let next_path = &["iter", "Iterator", "next"];
3527                     let next_path = P(self.expr_std_path(head_sp, next_path, ThinVec::new()));
3528                     let next_expr = P(self.expr_call(head_sp, next_path, hir_vec![ref_mut_iter]));
3529                     let arms = hir_vec![pat_arm, break_arm];
3530
3531                     P(self.expr(
3532                         head_sp,
3533                         hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar),
3534                         ThinVec::new(),
3535                     ))
3536                 };
3537                 let match_stmt = respan(head_sp, hir::StmtExpr(match_expr, self.next_id().node_id));
3538
3539                 let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat.id));
3540
3541                 // `let mut __next`
3542                 let next_let =
3543                     self.stmt_let_pat(head_sp, None, next_pat, hir::LocalSource::ForLoopDesugar);
3544
3545                 // `let <pat> = __next`
3546                 let pat = self.lower_pat(pat);
3547                 let pat_let = self.stmt_let_pat(
3548                     head_sp,
3549                     Some(next_expr),
3550                     pat,
3551                     hir::LocalSource::ForLoopDesugar,
3552                 );
3553
3554                 let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false));
3555                 let body_expr = P(self.expr_block(body_block, ThinVec::new()));
3556                 let body_stmt = respan(body.span, hir::StmtExpr(body_expr, self.next_id().node_id));
3557
3558                 let loop_block = P(self.block_all(
3559                     e.span,
3560                     hir_vec![next_let, match_stmt, pat_let, body_stmt],
3561                     None,
3562                 ));
3563
3564                 // `[opt_ident]: loop { ... }`
3565                 let loop_expr = hir::ExprLoop(
3566                     loop_block,
3567                     self.lower_label(opt_label),
3568                     hir::LoopSource::ForLoop,
3569                 );
3570                 let LoweredNodeId { node_id, hir_id } = self.lower_node_id(e.id);
3571                 let loop_expr = P(hir::Expr {
3572                     id: node_id,
3573                     hir_id,
3574                     node: loop_expr,
3575                     span: e.span,
3576                     attrs: ThinVec::new(),
3577                 });
3578
3579                 // `mut iter => { ... }`
3580                 let iter_arm = self.arm(hir_vec![iter_pat], loop_expr);
3581
3582                 // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
3583                 let into_iter_expr = {
3584                     let into_iter_path = &["iter", "IntoIterator", "into_iter"];
3585                     let into_iter = P(self.expr_std_path(head_sp, into_iter_path, ThinVec::new()));
3586                     P(self.expr_call(head_sp, into_iter, hir_vec![head]))
3587                 };
3588
3589                 let match_expr = P(self.expr_match(
3590                     head_sp,
3591                     into_iter_expr,
3592                     hir_vec![iter_arm],
3593                     hir::MatchSource::ForLoopDesugar,
3594                 ));
3595
3596                 // `{ let _result = ...; _result }`
3597                 // underscore prevents an unused_variables lint if the head diverges
3598                 let result_ident = self.str_to_ident("_result");
3599                 let (let_stmt, let_stmt_binding) =
3600                     self.stmt_let(e.span, false, result_ident, match_expr);
3601
3602                 let result = P(self.expr_ident(e.span, result_ident, let_stmt_binding));
3603                 let block = P(self.block_all(e.span, hir_vec![let_stmt], Some(result)));
3604                 // add the attributes to the outer returned expr node
3605                 return self.expr_block(block, e.attrs.clone());
3606             }
3607
3608             // Desugar ExprKind::Try
3609             // From: `<expr>?`
3610             ExprKind::Try(ref sub_expr) => {
3611                 // to:
3612                 //
3613                 // match Try::into_result(<expr>) {
3614                 //     Ok(val) => #[allow(unreachable_code)] val,
3615                 //     Err(err) => #[allow(unreachable_code)]
3616                 //                 // If there is an enclosing `catch {...}`
3617                 //                 break 'catch_target Try::from_error(From::from(err)),
3618                 //                 // Otherwise
3619                 //                 return Try::from_error(From::from(err)),
3620                 // }
3621
3622                 let unstable_span =
3623                     self.allow_internal_unstable(CompilerDesugaringKind::QuestionMark, e.span);
3624
3625                 // Try::into_result(<expr>)
3626                 let discr = {
3627                     // expand <expr>
3628                     let sub_expr = self.lower_expr(sub_expr);
3629
3630                     let path = &["ops", "Try", "into_result"];
3631                     let path = P(self.expr_std_path(unstable_span, path, ThinVec::new()));
3632                     P(self.expr_call(e.span, path, hir_vec![sub_expr]))
3633                 };
3634
3635                 // #[allow(unreachable_code)]
3636                 let attr = {
3637                     // allow(unreachable_code)
3638                     let allow = {
3639                         let allow_ident = Ident::from_str("allow").with_span_pos(e.span);
3640                         let uc_ident = Ident::from_str("unreachable_code").with_span_pos(e.span);
3641                         let uc_nested = attr::mk_nested_word_item(uc_ident);
3642                         attr::mk_list_item(e.span, allow_ident, vec![uc_nested])
3643                     };
3644                     attr::mk_spanned_attr_outer(e.span, attr::mk_attr_id(), allow)
3645                 };
3646                 let attrs = vec![attr];
3647
3648                 // Ok(val) => #[allow(unreachable_code)] val,
3649                 let ok_arm = {
3650                     let val_ident = self.str_to_ident("val");
3651                     let val_pat = self.pat_ident(e.span, val_ident);
3652                     let val_expr = P(self.expr_ident_with_attrs(
3653                         e.span,
3654                         val_ident,
3655                         val_pat.id,
3656                         ThinVec::from(attrs.clone()),
3657                     ));
3658                     let ok_pat = self.pat_ok(e.span, val_pat);
3659
3660                     self.arm(hir_vec![ok_pat], val_expr)
3661                 };
3662
3663                 // Err(err) => #[allow(unreachable_code)]
3664                 //             return Try::from_error(From::from(err)),
3665                 let err_arm = {
3666                     let err_ident = self.str_to_ident("err");
3667                     let err_local = self.pat_ident(e.span, err_ident);
3668                     let from_expr = {
3669                         let path = &["convert", "From", "from"];
3670                         let from = P(self.expr_std_path(e.span, path, ThinVec::new()));
3671                         let err_expr = self.expr_ident(e.span, err_ident, err_local.id);
3672
3673                         self.expr_call(e.span, from, hir_vec![err_expr])
3674                     };
3675                     let from_err_expr =
3676                         self.wrap_in_try_constructor("from_error", from_expr, unstable_span);
3677                     let thin_attrs = ThinVec::from(attrs);
3678                     let catch_scope = self.catch_scopes.last().map(|x| *x);
3679                     let ret_expr = if let Some(catch_node) = catch_scope {
3680                         P(self.expr(
3681                             e.span,
3682                             hir::ExprBreak(
3683                                 hir::Destination {
3684                                     label: None,
3685                                     target_id: Ok(catch_node),
3686                                 },
3687                                 Some(from_err_expr),
3688                             ),
3689                             thin_attrs,
3690                         ))
3691                     } else {
3692                         P(self.expr(e.span, hir::Expr_::ExprRet(Some(from_err_expr)), thin_attrs))
3693                     };
3694
3695                     let err_pat = self.pat_err(e.span, err_local);
3696                     self.arm(hir_vec![err_pat], ret_expr)
3697                 };
3698
3699                 hir::ExprMatch(
3700                     discr,
3701                     hir_vec![err_arm, ok_arm],
3702                     hir::MatchSource::TryDesugar,
3703                 )
3704             }
3705
3706             ExprKind::Mac(_) => panic!("Shouldn't exist here"),
3707         };
3708
3709         let LoweredNodeId { node_id, hir_id } = self.lower_node_id(e.id);
3710
3711         hir::Expr {
3712             id: node_id,
3713             hir_id,
3714             node: kind,
3715             span: e.span,
3716             attrs: e.attrs.clone(),
3717         }
3718     }
3719
3720     fn lower_stmt(&mut self, s: &Stmt) -> SmallVector<hir::Stmt> {
3721         SmallVector::one(match s.node {
3722             StmtKind::Local(ref l) => Spanned {
3723                 node: hir::StmtDecl(
3724                     P(Spanned {
3725                         node: hir::DeclLocal(self.lower_local(l)),
3726                         span: s.span,
3727                     }),
3728                     self.lower_node_id(s.id).node_id,
3729                 ),
3730                 span: s.span,
3731             },
3732             StmtKind::Item(ref it) => {
3733                 // Can only use the ID once.
3734                 let mut id = Some(s.id);
3735                 return self.lower_item_id(it)
3736                     .into_iter()
3737                     .map(|item_id| Spanned {
3738                         node: hir::StmtDecl(
3739                             P(Spanned {
3740                                 node: hir::DeclItem(item_id),
3741                                 span: s.span,
3742                             }),
3743                             id.take()
3744                                 .map(|id| self.lower_node_id(id).node_id)
3745                                 .unwrap_or_else(|| self.next_id().node_id),
3746                         ),
3747                         span: s.span,
3748                     })
3749                     .collect();
3750             }
3751             StmtKind::Expr(ref e) => Spanned {
3752                 node: hir::StmtExpr(P(self.lower_expr(e)), self.lower_node_id(s.id).node_id),
3753                 span: s.span,
3754             },
3755             StmtKind::Semi(ref e) => Spanned {
3756                 node: hir::StmtSemi(P(self.lower_expr(e)), self.lower_node_id(s.id).node_id),
3757                 span: s.span,
3758             },
3759             StmtKind::Mac(..) => panic!("Shouldn't exist here"),
3760         })
3761     }
3762
3763     fn lower_capture_clause(&mut self, c: CaptureBy) -> hir::CaptureClause {
3764         match c {
3765             CaptureBy::Value => hir::CaptureByValue,
3766             CaptureBy::Ref => hir::CaptureByRef,
3767         }
3768     }
3769
3770     /// If an `explicit_owner` is given, this method allocates the `HirId` in
3771     /// the address space of that item instead of the item currently being
3772     /// lowered. This can happen during `lower_impl_item_ref()` where we need to
3773     /// lower a `Visibility` value although we haven't lowered the owning
3774     /// `ImplItem` in question yet.
3775     fn lower_visibility(
3776         &mut self,
3777         v: &Visibility,
3778         explicit_owner: Option<NodeId>,
3779     ) -> hir::Visibility {
3780         match v.node {
3781             VisibilityKind::Public => hir::Public,
3782             VisibilityKind::Crate(sugar) => hir::Visibility::Crate(sugar),
3783             VisibilityKind::Restricted { ref path, id, .. } => hir::Visibility::Restricted {
3784                 path: P(self.lower_path(id, path, ParamMode::Explicit)),
3785                 id: if let Some(owner) = explicit_owner {
3786                     self.lower_node_id_with_owner(id, owner).node_id
3787                 } else {
3788                     self.lower_node_id(id).node_id
3789                 },
3790             },
3791             VisibilityKind::Inherited => hir::Inherited,
3792         }
3793     }
3794
3795     fn lower_defaultness(&mut self, d: Defaultness, has_value: bool) -> hir::Defaultness {
3796         match d {
3797             Defaultness::Default => hir::Defaultness::Default {
3798                 has_value: has_value,
3799             },
3800             Defaultness::Final => {
3801                 assert!(has_value);
3802                 hir::Defaultness::Final
3803             }
3804         }
3805     }
3806
3807     fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode {
3808         match *b {
3809             BlockCheckMode::Default => hir::DefaultBlock,
3810             BlockCheckMode::Unsafe(u) => hir::UnsafeBlock(self.lower_unsafe_source(u)),
3811         }
3812     }
3813
3814     fn lower_binding_mode(&mut self, b: &BindingMode) -> hir::BindingAnnotation {
3815         match *b {
3816             BindingMode::ByValue(Mutability::Immutable) => hir::BindingAnnotation::Unannotated,
3817             BindingMode::ByRef(Mutability::Immutable) => hir::BindingAnnotation::Ref,
3818             BindingMode::ByValue(Mutability::Mutable) => hir::BindingAnnotation::Mutable,
3819             BindingMode::ByRef(Mutability::Mutable) => hir::BindingAnnotation::RefMut,
3820         }
3821     }
3822
3823     fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
3824         match u {
3825             CompilerGenerated => hir::CompilerGenerated,
3826             UserProvided => hir::UserProvided,
3827         }
3828     }
3829
3830     fn lower_impl_polarity(&mut self, i: ImplPolarity) -> hir::ImplPolarity {
3831         match i {
3832             ImplPolarity::Positive => hir::ImplPolarity::Positive,
3833             ImplPolarity::Negative => hir::ImplPolarity::Negative,
3834         }
3835     }
3836
3837     fn lower_trait_bound_modifier(&mut self, f: TraitBoundModifier) -> hir::TraitBoundModifier {
3838         match f {
3839             TraitBoundModifier::None => hir::TraitBoundModifier::None,
3840             TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe,
3841         }
3842     }
3843
3844     // Helper methods for building HIR.
3845
3846     fn arm(&mut self, pats: hir::HirVec<P<hir::Pat>>, expr: P<hir::Expr>) -> hir::Arm {
3847         hir::Arm {
3848             attrs: hir_vec![],
3849             pats,
3850             guard: None,
3851             body: expr,
3852         }
3853     }
3854
3855     fn field(&mut self, ident: Ident, expr: P<hir::Expr>, span: Span) -> hir::Field {
3856         hir::Field {
3857             id: self.next_id().node_id,
3858             ident,
3859             span,
3860             expr,
3861             is_shorthand: false,
3862         }
3863     }
3864
3865     fn expr_break(&mut self, span: Span, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
3866         let expr_break = hir::ExprBreak(self.lower_loop_destination(None), None);
3867         P(self.expr(span, expr_break, attrs))
3868     }
3869
3870     fn expr_call(
3871         &mut self,
3872         span: Span,
3873         e: P<hir::Expr>,
3874         args: hir::HirVec<hir::Expr>,
3875     ) -> hir::Expr {
3876         self.expr(span, hir::ExprCall(e, args), ThinVec::new())
3877     }
3878
3879     fn expr_ident(&mut self, span: Span, id: Name, binding: NodeId) -> hir::Expr {
3880         self.expr_ident_with_attrs(span, id, binding, ThinVec::new())
3881     }
3882
3883     fn expr_ident_with_attrs(
3884         &mut self,
3885         span: Span,
3886         id: Name,
3887         binding: NodeId,
3888         attrs: ThinVec<Attribute>,
3889     ) -> hir::Expr {
3890         let expr_path = hir::ExprPath(hir::QPath::Resolved(
3891             None,
3892             P(hir::Path {
3893                 span,
3894                 def: Def::Local(binding),
3895                 segments: hir_vec![hir::PathSegment::from_name(id)],
3896             }),
3897         ));
3898
3899         self.expr(span, expr_path, attrs)
3900     }
3901
3902     fn expr_mut_addr_of(&mut self, span: Span, e: P<hir::Expr>) -> hir::Expr {
3903         self.expr(span, hir::ExprAddrOf(hir::MutMutable, e), ThinVec::new())
3904     }
3905
3906     fn expr_std_path(
3907         &mut self,
3908         span: Span,
3909         components: &[&str],
3910         attrs: ThinVec<Attribute>,
3911     ) -> hir::Expr {
3912         let path = self.std_path(span, components, true);
3913         self.expr(
3914             span,
3915             hir::ExprPath(hir::QPath::Resolved(None, P(path))),
3916             attrs,
3917         )
3918     }
3919
3920     fn expr_match(
3921         &mut self,
3922         span: Span,
3923         arg: P<hir::Expr>,
3924         arms: hir::HirVec<hir::Arm>,
3925         source: hir::MatchSource,
3926     ) -> hir::Expr {
3927         self.expr(span, hir::ExprMatch(arg, arms, source), ThinVec::new())
3928     }
3929
3930     fn expr_block(&mut self, b: P<hir::Block>, attrs: ThinVec<Attribute>) -> hir::Expr {
3931         self.expr(b.span, hir::ExprBlock(b, None), attrs)
3932     }
3933
3934     fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec<hir::Expr>) -> P<hir::Expr> {
3935         P(self.expr(sp, hir::ExprTup(exprs), ThinVec::new()))
3936     }
3937
3938     fn expr(&mut self, span: Span, node: hir::Expr_, attrs: ThinVec<Attribute>) -> hir::Expr {
3939         let LoweredNodeId { node_id, hir_id } = self.next_id();
3940         hir::Expr {
3941             id: node_id,
3942             hir_id,
3943             node,
3944             span,
3945             attrs,
3946         }
3947     }
3948
3949     fn stmt_let_pat(
3950         &mut self,
3951         sp: Span,
3952         ex: Option<P<hir::Expr>>,
3953         pat: P<hir::Pat>,
3954         source: hir::LocalSource,
3955     ) -> hir::Stmt {
3956         let LoweredNodeId { node_id, hir_id } = self.next_id();
3957
3958         let local = P(hir::Local {
3959             pat,
3960             ty: None,
3961             init: ex,
3962             id: node_id,
3963             hir_id,
3964             span: sp,
3965             attrs: ThinVec::new(),
3966             source,
3967         });
3968         let decl = respan(sp, hir::DeclLocal(local));
3969         respan(sp, hir::StmtDecl(P(decl), self.next_id().node_id))
3970     }
3971
3972     fn stmt_let(
3973         &mut self,
3974         sp: Span,
3975         mutbl: bool,
3976         ident: Name,
3977         ex: P<hir::Expr>,
3978     ) -> (hir::Stmt, NodeId) {
3979         let pat = if mutbl {
3980             self.pat_ident_binding_mode(sp, ident, hir::BindingAnnotation::Mutable)
3981         } else {
3982             self.pat_ident(sp, ident)
3983         };
3984         let pat_id = pat.id;
3985         (
3986             self.stmt_let_pat(sp, Some(ex), pat, hir::LocalSource::Normal),
3987             pat_id,
3988         )
3989     }
3990
3991     fn block_expr(&mut self, expr: P<hir::Expr>) -> hir::Block {
3992         self.block_all(expr.span, hir::HirVec::new(), Some(expr))
3993     }
3994
3995     fn block_all(
3996         &mut self,
3997         span: Span,
3998         stmts: hir::HirVec<hir::Stmt>,
3999         expr: Option<P<hir::Expr>>,
4000     ) -> hir::Block {
4001         let LoweredNodeId { node_id, hir_id } = self.next_id();
4002
4003         hir::Block {
4004             stmts,
4005             expr,
4006             id: node_id,
4007             hir_id,
4008             rules: hir::DefaultBlock,
4009             span,
4010             targeted_by_break: false,
4011             recovered: false,
4012         }
4013     }
4014
4015     fn pat_ok(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
4016         self.pat_std_enum(span, &["result", "Result", "Ok"], hir_vec![pat])
4017     }
4018
4019     fn pat_err(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
4020         self.pat_std_enum(span, &["result", "Result", "Err"], hir_vec![pat])
4021     }
4022
4023     fn pat_some(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
4024         self.pat_std_enum(span, &["option", "Option", "Some"], hir_vec![pat])
4025     }
4026
4027     fn pat_none(&mut self, span: Span) -> P<hir::Pat> {
4028         self.pat_std_enum(span, &["option", "Option", "None"], hir_vec![])
4029     }
4030
4031     fn pat_std_enum(
4032         &mut self,
4033         span: Span,
4034         components: &[&str],
4035         subpats: hir::HirVec<P<hir::Pat>>,
4036     ) -> P<hir::Pat> {
4037         let path = self.std_path(span, components, true);
4038         let qpath = hir::QPath::Resolved(None, P(path));
4039         let pt = if subpats.is_empty() {
4040             hir::PatKind::Path(qpath)
4041         } else {
4042             hir::PatKind::TupleStruct(qpath, subpats, None)
4043         };
4044         self.pat(span, pt)
4045     }
4046
4047     fn pat_ident(&mut self, span: Span, name: Name) -> P<hir::Pat> {
4048         self.pat_ident_binding_mode(span, name, hir::BindingAnnotation::Unannotated)
4049     }
4050
4051     fn pat_ident_binding_mode(
4052         &mut self,
4053         span: Span,
4054         name: Name,
4055         bm: hir::BindingAnnotation,
4056     ) -> P<hir::Pat> {
4057         let LoweredNodeId { node_id, hir_id } = self.next_id();
4058
4059         P(hir::Pat {
4060             id: node_id,
4061             hir_id,
4062             node: hir::PatKind::Binding(bm, node_id, Spanned { span, node: name }, None),
4063             span,
4064         })
4065     }
4066
4067     fn pat_wild(&mut self, span: Span) -> P<hir::Pat> {
4068         self.pat(span, hir::PatKind::Wild)
4069     }
4070
4071     fn pat(&mut self, span: Span, pat: hir::PatKind) -> P<hir::Pat> {
4072         let LoweredNodeId { node_id, hir_id } = self.next_id();
4073         P(hir::Pat {
4074             id: node_id,
4075             hir_id,
4076             node: pat,
4077             span,
4078         })
4079     }
4080
4081     /// Given suffix ["b","c","d"], returns path `::std::b::c::d` when
4082     /// `fld.cx.use_std`, and `::core::b::c::d` otherwise.
4083     /// The path is also resolved according to `is_value`.
4084     fn std_path(&mut self, span: Span, components: &[&str], is_value: bool) -> hir::Path {
4085         self.resolver
4086             .resolve_str_path(span, self.crate_root, components, is_value)
4087     }
4088
4089     fn ty_path(&mut self, id: LoweredNodeId, span: Span, qpath: hir::QPath) -> P<hir::Ty> {
4090         let mut id = id;
4091         let node = match qpath {
4092             hir::QPath::Resolved(None, path) => {
4093                 // Turn trait object paths into `TyTraitObject` instead.
4094                 if let Def::Trait(_) = path.def {
4095                     let principal = hir::PolyTraitRef {
4096                         bound_generic_params: hir::HirVec::new(),
4097                         trait_ref: hir::TraitRef {
4098                             path: path.and_then(|path| path),
4099                             ref_id: id.node_id,
4100                         },
4101                         span,
4102                     };
4103
4104                     // The original ID is taken by the `PolyTraitRef`,
4105                     // so the `Ty` itself needs a different one.
4106                     id = self.next_id();
4107                     hir::TyTraitObject(hir_vec![principal], self.elided_dyn_bound(span))
4108                 } else {
4109                     hir::TyPath(hir::QPath::Resolved(None, path))
4110                 }
4111             }
4112             _ => hir::TyPath(qpath),
4113         };
4114         P(hir::Ty {
4115             id: id.node_id,
4116             hir_id: id.hir_id,
4117             node,
4118             span,
4119         })
4120     }
4121
4122     /// Invoked to create the lifetime argument for a type `&T`
4123     /// with no explicit lifetime.
4124     fn elided_ref_lifetime(&mut self, span: Span) -> hir::Lifetime {
4125         match self.anonymous_lifetime_mode {
4126             // Intercept when we are in an impl header and introduce an in-band lifetime.
4127             // Hence `impl Foo for &u32` becomes `impl<'f> Foo for &'f u32` for some fresh
4128             // `'f`.
4129             AnonymousLifetimeMode::CreateParameter => {
4130                 let fresh_name = self.collect_fresh_in_band_lifetime(span);
4131                 hir::Lifetime {
4132                     id: self.next_id().node_id,
4133                     span,
4134                     name: fresh_name,
4135                 }
4136             }
4137
4138             AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span),
4139         }
4140     }
4141
4142     /// Invoked to create the lifetime argument(s) for a path like
4143     /// `std::cell::Ref<T>`; note that implicit lifetimes in these
4144     /// sorts of cases are deprecated. This may therefore report a warning or an
4145     /// error, depending on the mode.
4146     fn elided_path_lifetimes(&mut self, span: Span, count: usize) -> P<[hir::Lifetime]> {
4147         match self.anonymous_lifetime_mode {
4148             // NB. We intentionally ignore the create-parameter mode here
4149             // and instead "pass through" to resolve-lifetimes, which will then
4150             // report an error. This is because we don't want to support
4151             // impl elision for deprecated forms like
4152             //
4153             //     impl Foo for std::cell::Ref<u32> // note lack of '_
4154             AnonymousLifetimeMode::CreateParameter => {}
4155
4156             // This is the normal case.
4157             AnonymousLifetimeMode::PassThrough => {}
4158         }
4159
4160         (0..count)
4161             .map(|_| self.new_implicit_lifetime(span))
4162             .collect()
4163     }
4164
4165     /// Invoked to create the lifetime argument(s) for an elided trait object
4166     /// bound, like the bound in `Box<dyn Debug>`. This method is not invoked
4167     /// when the bound is written, even if it is written with `'_` like in
4168     /// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked.
4169     fn elided_dyn_bound(&mut self, span: Span) -> hir::Lifetime {
4170         match self.anonymous_lifetime_mode {
4171             // NB. We intentionally ignore the create-parameter mode here.
4172             // and instead "pass through" to resolve-lifetimes, which will apply
4173             // the object-lifetime-defaulting rules. Elided object lifetime defaults
4174             // do not act like other elided lifetimes. In other words, given this:
4175             //
4176             //     impl Foo for Box<dyn Debug>
4177             //
4178             // we do not introduce a fresh `'_` to serve as the bound, but instead
4179             // ultimately translate to the equivalent of:
4180             //
4181             //     impl Foo for Box<dyn Debug + 'static>
4182             //
4183             // `resolve_lifetime` has the code to make that happen.
4184             AnonymousLifetimeMode::CreateParameter => {}
4185
4186             // This is the normal case.
4187             AnonymousLifetimeMode::PassThrough => {}
4188         }
4189
4190         self.new_implicit_lifetime(span)
4191     }
4192
4193     fn new_implicit_lifetime(&mut self, span: Span) -> hir::Lifetime {
4194         hir::Lifetime {
4195             id: self.next_id().node_id,
4196             span,
4197             name: hir::LifetimeName::Implicit,
4198         }
4199     }
4200
4201     fn maybe_lint_bare_trait(&self, span: Span, id: NodeId, is_global: bool) {
4202         self.sess.buffer_lint_with_diagnostic(
4203             builtin::BARE_TRAIT_OBJECTS,
4204             id,
4205             span,
4206             "trait objects without an explicit `dyn` are deprecated",
4207             builtin::BuiltinLintDiagnostics::BareTraitObject(span, is_global),
4208         )
4209     }
4210
4211     fn wrap_in_try_constructor(
4212         &mut self,
4213         method: &'static str,
4214         e: hir::Expr,
4215         unstable_span: Span,
4216     ) -> P<hir::Expr> {
4217         let path = &["ops", "Try", method];
4218         let from_err = P(self.expr_std_path(unstable_span, path,
4219                                             ThinVec::new()));
4220         P(self.expr_call(e.span, from_err, hir_vec![e]))
4221     }
4222 }
4223
4224 fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body>) -> Vec<hir::BodyId> {
4225     // Sorting by span ensures that we get things in order within a
4226     // file, and also puts the files in a sensible order.
4227     let mut body_ids: Vec<_> = bodies.keys().cloned().collect();
4228     body_ids.sort_by_key(|b| bodies[b].value.span);
4229     body_ids
4230 }