]> git.lizzy.rs Git - rust.git/blob - src/librustc/hir/lowering.rs
df0a23c1b867109044ee3800e08809a14f7a2244
[rust.git] / src / librustc / hir / lowering.rs
1 // ignore-tidy-filelength
2
3 //! Lowers the AST to the HIR.
4 //!
5 //! Since the AST and HIR are fairly similar, this is mostly a simple procedure,
6 //! much like a fold. Where lowering involves a bit more work things get more
7 //! interesting and there are some invariants you should know about. These mostly
8 //! concern spans and IDs.
9 //!
10 //! Spans are assigned to AST nodes during parsing and then are modified during
11 //! expansion to indicate the origin of a node and the process it went through
12 //! being expanded. IDs are assigned to AST nodes just before lowering.
13 //!
14 //! For the simpler lowering steps, IDs and spans should be preserved. Unlike
15 //! expansion we do not preserve the process of lowering in the spans, so spans
16 //! should not be modified here. When creating a new node (as opposed to
17 //! 'folding' an existing one), then you create a new ID using `next_id()`.
18 //!
19 //! You must ensure that IDs are unique. That means that you should only use the
20 //! ID from an AST node in a single HIR node (you can assume that AST node IDs
21 //! are unique). Every new node must have a unique ID. Avoid cloning HIR nodes.
22 //! If you do, you must then set the new node's ID to a fresh one.
23 //!
24 //! Spans are used for error messages and for tools to map semantics back to
25 //! source code. It is therefore not as important with spans as IDs to be strict
26 //! about use (you can't break the compiler by screwing up a span). Obviously, a
27 //! HIR node can only have a single span. But multiple nodes can have the same
28 //! span and spans don't need to be kept in order, etc. Where code is preserved
29 //! by lowering, it should have the same span as in the AST. Where HIR nodes are
30 //! new it is probably best to give a span for the whole AST node being lowered.
31 //! All nodes should have real spans, don't use dummy spans. Tools are likely to
32 //! get confused if the spans from leaf AST nodes occur in multiple places
33 //! in the HIR, especially for multiple identifiers.
34
35 use crate::dep_graph::DepGraph;
36 use crate::hir::{self, ParamName};
37 use crate::hir::HirVec;
38 use crate::hir::map::{DefKey, DefPathData, Definitions};
39 use crate::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
40 use crate::hir::def::{Res, DefKind, PartialRes, PerNS};
41 use crate::hir::{GenericArg, ConstArg};
42 use crate::lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
43                     ELIDED_LIFETIMES_IN_PATHS};
44 use crate::middle::cstore::CrateStore;
45 use crate::session::Session;
46 use crate::session::config::nightly_options;
47 use crate::util::common::FN_OUTPUT_NAME;
48 use crate::util::nodemap::{DefIdMap, NodeMap};
49 use errors::Applicability;
50 use rustc_data_structures::fx::FxHashSet;
51 use rustc_data_structures::indexed_vec::IndexVec;
52 use rustc_data_structures::thin_vec::ThinVec;
53 use rustc_data_structures::sync::Lrc;
54
55 use std::collections::{BTreeSet, BTreeMap};
56 use std::mem;
57 use smallvec::SmallVec;
58 use syntax::attr;
59 use syntax::ast;
60 use syntax::ast::*;
61 use syntax::errors;
62 use syntax::ext::hygiene::{Mark, SyntaxContext};
63 use syntax::print::pprust;
64 use syntax::ptr::P;
65 use syntax::source_map::{self, respan, CompilerDesugaringKind, Spanned};
66 use syntax::source_map::CompilerDesugaringKind::IfTemporary;
67 use syntax::std_inject;
68 use syntax::symbol::{kw, sym, Symbol};
69 use syntax::tokenstream::{TokenStream, TokenTree};
70 use syntax::parse::token::Token;
71 use syntax::visit::{self, Visitor};
72 use syntax_pos::{edition, Span};
73
74 const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF;
75
76 pub struct LoweringContext<'a> {
77     crate_root: Option<Symbol>,
78
79     /// Used to assign ids to HIR nodes that do not directly correspond to an AST node.
80     sess: &'a Session,
81
82     cstore: &'a dyn CrateStore,
83
84     resolver: &'a mut dyn Resolver,
85
86     /// The items being lowered are collected here.
87     items: BTreeMap<hir::HirId, hir::Item>,
88
89     trait_items: BTreeMap<hir::TraitItemId, hir::TraitItem>,
90     impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>,
91     bodies: BTreeMap<hir::BodyId, hir::Body>,
92     exported_macros: Vec<hir::MacroDef>,
93
94     trait_impls: BTreeMap<DefId, Vec<hir::HirId>>,
95
96     modules: BTreeMap<NodeId, hir::ModuleItems>,
97
98     is_generator: bool,
99     is_async_body: bool,
100
101     /// Used to get the current `fn`'s def span to point to when using `await`
102     /// outside of an `async fn`.
103     current_item: Option<Span>,
104
105     catch_scopes: Vec<NodeId>,
106     loop_scopes: Vec<NodeId>,
107     is_in_loop_condition: bool,
108     is_in_trait_impl: bool,
109
110     /// What to do when we encounter either an "anonymous lifetime
111     /// reference". The term "anonymous" is meant to encompass both
112     /// `'_` lifetimes as well as fully elided cases where nothing is
113     /// written at all (e.g., `&T` or `std::cell::Ref<T>`).
114     anonymous_lifetime_mode: AnonymousLifetimeMode,
115
116     /// Used to create lifetime definitions from in-band lifetime usages.
117     /// e.g., `fn foo(x: &'x u8) -> &'x u8` to `fn foo<'x>(x: &'x u8) -> &'x u8`
118     /// When a named lifetime is encountered in a function or impl header and
119     /// has not been defined
120     /// (i.e., it doesn't appear in the in_scope_lifetimes list), it is added
121     /// to this list. The results of this list are then added to the list of
122     /// lifetime definitions in the corresponding impl or function generics.
123     lifetimes_to_define: Vec<(Span, ParamName)>,
124
125     /// Whether or not in-band lifetimes are being collected. This is used to
126     /// indicate whether or not we're in a place where new lifetimes will result
127     /// in in-band lifetime definitions, such a function or an impl header,
128     /// including implicit lifetimes from `impl_header_lifetime_elision`.
129     is_collecting_in_band_lifetimes: bool,
130
131     /// Currently in-scope lifetimes defined in impl headers, fn headers, or HRTB.
132     /// When `is_collectin_in_band_lifetimes` is true, each lifetime is checked
133     /// against this list to see if it is already in-scope, or if a definition
134     /// needs to be created for it.
135     in_scope_lifetimes: Vec<Ident>,
136
137     current_module: NodeId,
138
139     type_def_lifetime_params: DefIdMap<usize>,
140
141     current_hir_id_owner: Vec<(DefIndex, u32)>,
142     item_local_id_counters: NodeMap<u32>,
143     node_id_to_hir_id: IndexVec<NodeId, hir::HirId>,
144 }
145
146 pub trait Resolver {
147     /// Resolve a path generated by the lowerer when expanding `for`, `if let`, etc.
148     fn resolve_hir_path(
149         &mut self,
150         path: &ast::Path,
151         is_value: bool,
152     ) -> hir::Path;
153
154     /// Obtain resolution for a `NodeId` with a single resolution.
155     fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes>;
156
157     /// Obtain per-namespace resolutions for `use` statement with the given `NoedId`.
158     fn get_import_res(&mut self, id: NodeId) -> PerNS<Option<Res<NodeId>>>;
159
160     /// Obtain resolution for a label with the given `NodeId`.
161     fn get_label_res(&mut self, id: NodeId) -> Option<NodeId>;
162
163     /// We must keep the set of definitions up to date as we add nodes that weren't in the AST.
164     /// This should only return `None` during testing.
165     fn definitions(&mut self) -> &mut Definitions;
166
167     /// Given suffix `["b", "c", "d"]`, creates a HIR path for `[::crate_root]::b::c::d` and
168     /// resolves it based on `is_value`.
169     fn resolve_str_path(
170         &mut self,
171         span: Span,
172         crate_root: Option<Symbol>,
173         components: &[Symbol],
174         is_value: bool,
175     ) -> hir::Path;
176 }
177
178 #[derive(Debug)]
179 enum ImplTraitContext<'a> {
180     /// Treat `impl Trait` as shorthand for a new universal generic parameter.
181     /// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually
182     /// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.
183     ///
184     /// Newly generated parameters should be inserted into the given `Vec`.
185     Universal(&'a mut Vec<hir::GenericParam>),
186
187     /// Treat `impl Trait` as shorthand for a new existential parameter.
188     /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
189     /// equivalent to a fresh existential parameter like `existential type T; fn foo() -> T`.
190     ///
191     /// We optionally store a `DefId` for the parent item here so we can look up necessary
192     /// information later. It is `None` when no information about the context should be stored,
193     /// e.g., for consts and statics.
194     Existential(Option<DefId>),
195
196     /// `impl Trait` is not accepted in this position.
197     Disallowed(ImplTraitPosition),
198 }
199
200 /// Position in which `impl Trait` is disallowed. Used for error reporting.
201 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
202 enum ImplTraitPosition {
203     Binding,
204     Other,
205 }
206
207 impl<'a> ImplTraitContext<'a> {
208     #[inline]
209     fn disallowed() -> Self {
210         ImplTraitContext::Disallowed(ImplTraitPosition::Other)
211     }
212
213     fn reborrow(&'b mut self) -> ImplTraitContext<'b> {
214         use self::ImplTraitContext::*;
215         match self {
216             Universal(params) => Universal(params),
217             Existential(did) => Existential(*did),
218             Disallowed(pos) => Disallowed(*pos),
219         }
220     }
221 }
222
223 pub fn lower_crate(
224     sess: &Session,
225     cstore: &dyn CrateStore,
226     dep_graph: &DepGraph,
227     krate: &Crate,
228     resolver: &mut dyn Resolver,
229 ) -> hir::Crate {
230     // We're constructing the HIR here; we don't care what we will
231     // read, since we haven't even constructed the *input* to
232     // incr. comp. yet.
233     dep_graph.assert_ignored();
234
235     LoweringContext {
236         crate_root: std_inject::injected_crate_name().map(Symbol::intern),
237         sess,
238         cstore,
239         resolver,
240         items: BTreeMap::new(),
241         trait_items: BTreeMap::new(),
242         impl_items: BTreeMap::new(),
243         bodies: BTreeMap::new(),
244         trait_impls: BTreeMap::new(),
245         modules: BTreeMap::new(),
246         exported_macros: Vec::new(),
247         catch_scopes: Vec::new(),
248         loop_scopes: Vec::new(),
249         is_in_loop_condition: false,
250         anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
251         type_def_lifetime_params: Default::default(),
252         current_module: CRATE_NODE_ID,
253         current_hir_id_owner: vec![(CRATE_DEF_INDEX, 0)],
254         item_local_id_counters: Default::default(),
255         node_id_to_hir_id: IndexVec::new(),
256         is_generator: false,
257         is_async_body: false,
258         current_item: None,
259         is_in_trait_impl: false,
260         lifetimes_to_define: Vec::new(),
261         is_collecting_in_band_lifetimes: false,
262         in_scope_lifetimes: Vec::new(),
263     }.lower_crate(krate)
264 }
265
266 #[derive(Copy, Clone, PartialEq)]
267 enum ParamMode {
268     /// Any path in a type context.
269     Explicit,
270     /// The `module::Type` in `module::Type::method` in an expression.
271     Optional,
272 }
273
274 enum ParenthesizedGenericArgs {
275     Ok,
276     Warn,
277     Err,
278 }
279
280 /// What to do when we encounter an **anonymous** lifetime
281 /// reference. Anonymous lifetime references come in two flavors. You
282 /// have implicit, or fully elided, references to lifetimes, like the
283 /// one in `&T` or `Ref<T>`, and you have `'_` lifetimes, like `&'_ T`
284 /// or `Ref<'_, T>`. These often behave the same, but not always:
285 ///
286 /// - certain usages of implicit references are deprecated, like
287 ///   `Ref<T>`, and we sometimes just give hard errors in those cases
288 ///   as well.
289 /// - for object bounds there is a difference: `Box<dyn Foo>` is not
290 ///   the same as `Box<dyn Foo + '_>`.
291 ///
292 /// We describe the effects of the various modes in terms of three cases:
293 ///
294 /// - **Modern** -- includes all uses of `'_`, but also the lifetime arg
295 ///   of a `&` (e.g., the missing lifetime in something like `&T`)
296 /// - **Dyn Bound** -- if you have something like `Box<dyn Foo>`,
297 ///   there is an elided lifetime bound (`Box<dyn Foo + 'X>`). These
298 ///   elided bounds follow special rules. Note that this only covers
299 ///   cases where *nothing* is written; the `'_` in `Box<dyn Foo +
300 ///   '_>` is a case of "modern" elision.
301 /// - **Deprecated** -- this coverse cases like `Ref<T>`, where the lifetime
302 ///   parameter to ref is completely elided. `Ref<'_, T>` would be the modern,
303 ///   non-deprecated equivalent.
304 ///
305 /// Currently, the handling of lifetime elision is somewhat spread out
306 /// between HIR lowering and -- as described below -- the
307 /// `resolve_lifetime` module. Often we "fallthrough" to that code by generating
308 /// an "elided" or "underscore" lifetime name. In the future, we probably want to move
309 /// everything into HIR lowering.
310 #[derive(Copy, Clone)]
311 enum AnonymousLifetimeMode {
312     /// For **Modern** cases, create a new anonymous region parameter
313     /// and reference that.
314     ///
315     /// For **Dyn Bound** cases, pass responsibility to
316     /// `resolve_lifetime` code.
317     ///
318     /// For **Deprecated** cases, report an error.
319     CreateParameter,
320
321     /// Give a hard error when either `&` or `'_` is written. Used to
322     /// rule out things like `where T: Foo<'_>`. Does not imply an
323     /// error on default object bounds (e.g., `Box<dyn Foo>`).
324     ReportError,
325
326     /// Pass responsibility to `resolve_lifetime` code for all cases.
327     PassThrough,
328
329     /// Used in the return types of `async fn` where there exists
330     /// exactly one argument-position elided lifetime.
331     ///
332     /// In `async fn`, we lower the arguments types using the `CreateParameter`
333     /// mode, meaning that non-`dyn` elided lifetimes are assigned a fresh name.
334     /// If any corresponding elided lifetimes appear in the output, we need to
335     /// replace them with references to the fresh name assigned to the corresponding
336     /// elided lifetime in the arguments.
337     ///
338     /// For **Modern cases**, replace the anonymous parameter with a
339     /// reference to a specific freshly-named lifetime that was
340     /// introduced in argument
341     ///
342     /// For **Dyn Bound** cases, pass responsibility to
343     /// `resole_lifetime` code.
344     Replace(LtReplacement),
345 }
346
347 /// The type of elided lifetime replacement to perform on `async fn` return types.
348 #[derive(Copy, Clone)]
349 enum LtReplacement {
350     /// Fresh name introduced by the single non-dyn elided lifetime
351     /// in the arguments of the async fn.
352     Some(ParamName),
353
354     /// There is no single non-dyn elided lifetime because no lifetimes
355     /// appeared in the arguments.
356     NoLifetimes,
357
358     /// There is no single non-dyn elided lifetime because multiple
359     /// lifetimes appeared in the arguments.
360     MultipleLifetimes,
361 }
362
363 /// Calculates the `LtReplacement` to use for elided lifetimes in the return
364 /// type based on the fresh elided lifetimes introduced in argument position.
365 fn get_elided_lt_replacement(arg_position_lifetimes: &[(Span, ParamName)]) -> LtReplacement {
366     match arg_position_lifetimes {
367         [] => LtReplacement::NoLifetimes,
368         [(_span, param)] => LtReplacement::Some(*param),
369         _ => LtReplacement::MultipleLifetimes,
370     }
371 }
372
373 struct ImplTraitTypeIdVisitor<'a> { ids: &'a mut SmallVec<[NodeId; 1]> }
374
375 impl<'a, 'b> Visitor<'a> for ImplTraitTypeIdVisitor<'b> {
376     fn visit_ty(&mut self, ty: &'a Ty) {
377         match ty.node {
378             | TyKind::Typeof(_)
379             | TyKind::BareFn(_)
380             => return,
381
382             TyKind::ImplTrait(id, _) => self.ids.push(id),
383             _ => {},
384         }
385         visit::walk_ty(self, ty);
386     }
387
388     fn visit_path_segment(
389         &mut self,
390         path_span: Span,
391         path_segment: &'v PathSegment,
392     ) {
393         if let Some(ref p) = path_segment.args {
394             if let GenericArgs::Parenthesized(_) = **p {
395                 return;
396             }
397         }
398         visit::walk_path_segment(self, path_span, path_segment)
399     }
400 }
401
402 impl<'a> LoweringContext<'a> {
403     fn lower_crate(mut self, c: &Crate) -> hir::Crate {
404         /// Full-crate AST visitor that inserts into a fresh
405         /// `LoweringContext` any information that may be
406         /// needed from arbitrary locations in the crate,
407         /// e.g., the number of lifetime generic parameters
408         /// declared for every type and trait definition.
409         struct MiscCollector<'lcx, 'interner: 'lcx> {
410             lctx: &'lcx mut LoweringContext<'interner>,
411             hir_id_owner: Option<NodeId>,
412         }
413
414         impl MiscCollector<'_, '_> {
415             fn allocate_use_tree_hir_id_counters(
416                 &mut self,
417                 tree: &UseTree,
418                 owner: DefIndex,
419             ) {
420                 match tree.kind {
421                     UseTreeKind::Simple(_, id1, id2) => {
422                         for &id in &[id1, id2] {
423                             self.lctx.resolver.definitions().create_def_with_parent(
424                                 owner,
425                                 id,
426                                 DefPathData::Misc,
427                                 Mark::root(),
428                                 tree.prefix.span,
429                             );
430                             self.lctx.allocate_hir_id_counter(id);
431                         }
432                     }
433                     UseTreeKind::Glob => (),
434                     UseTreeKind::Nested(ref trees) => {
435                         for &(ref use_tree, id) in trees {
436                             let hir_id = self.lctx.allocate_hir_id_counter(id);
437                             self.allocate_use_tree_hir_id_counters(use_tree, hir_id.owner);
438                         }
439                     }
440                 }
441             }
442
443             fn with_hir_id_owner<F, T>(&mut self, owner: Option<NodeId>, f: F) -> T
444             where
445                 F: FnOnce(&mut Self) -> T,
446             {
447                 let old = mem::replace(&mut self.hir_id_owner, owner);
448                 let r = f(self);
449                 self.hir_id_owner = old;
450                 r
451             }
452         }
453
454         impl<'lcx, 'interner> Visitor<'lcx> for MiscCollector<'lcx, 'interner> {
455             fn visit_pat(&mut self, p: &'lcx Pat) {
456                 match p.node {
457                     // Doesn't generate a HIR node
458                     PatKind::Paren(..) => {},
459                     _ => {
460                         if let Some(owner) = self.hir_id_owner {
461                             self.lctx.lower_node_id_with_owner(p.id, owner);
462                         }
463                     }
464                 };
465
466                 visit::walk_pat(self, p)
467             }
468
469             fn visit_item(&mut self, item: &'lcx Item) {
470                 let hir_id = self.lctx.allocate_hir_id_counter(item.id);
471
472                 match item.node {
473                     ItemKind::Struct(_, ref generics)
474                     | ItemKind::Union(_, ref generics)
475                     | ItemKind::Enum(_, ref generics)
476                     | ItemKind::Ty(_, ref generics)
477                     | ItemKind::Existential(_, ref generics)
478                     | ItemKind::Trait(_, _, ref generics, ..) => {
479                         let def_id = self.lctx.resolver.definitions().local_def_id(item.id);
480                         let count = generics
481                             .params
482                             .iter()
483                             .filter(|param| match param.kind {
484                                 ast::GenericParamKind::Lifetime { .. } => true,
485                                 _ => false,
486                             })
487                             .count();
488                         self.lctx.type_def_lifetime_params.insert(def_id, count);
489                     }
490                     ItemKind::Use(ref use_tree) => {
491                         self.allocate_use_tree_hir_id_counters(use_tree, hir_id.owner);
492                     }
493                     _ => {}
494                 }
495
496                 self.with_hir_id_owner(Some(item.id), |this| {
497                     visit::walk_item(this, item);
498                 });
499             }
500
501             fn visit_trait_item(&mut self, item: &'lcx TraitItem) {
502                 self.lctx.allocate_hir_id_counter(item.id);
503
504                 match item.node {
505                     TraitItemKind::Method(_, None) => {
506                         // Ignore patterns in trait methods without bodies
507                         self.with_hir_id_owner(None, |this| {
508                             visit::walk_trait_item(this, item)
509                         });
510                     }
511                     _ => self.with_hir_id_owner(Some(item.id), |this| {
512                         visit::walk_trait_item(this, item);
513                     })
514                 }
515             }
516
517             fn visit_impl_item(&mut self, item: &'lcx ImplItem) {
518                 self.lctx.allocate_hir_id_counter(item.id);
519                 self.with_hir_id_owner(Some(item.id), |this| {
520                     visit::walk_impl_item(this, item);
521                 });
522             }
523
524             fn visit_foreign_item(&mut self, i: &'lcx ForeignItem) {
525                 // Ignore patterns in foreign items
526                 self.with_hir_id_owner(None, |this| {
527                     visit::walk_foreign_item(this, i)
528                 });
529             }
530
531             fn visit_ty(&mut self, t: &'lcx Ty) {
532                 match t.node {
533                     // Mirrors the case in visit::walk_ty
534                     TyKind::BareFn(ref f) => {
535                         walk_list!(
536                             self,
537                             visit_generic_param,
538                             &f.generic_params
539                         );
540                         // Mirrors visit::walk_fn_decl
541                         for argument in &f.decl.inputs {
542                             // We don't lower the ids of argument patterns
543                             self.with_hir_id_owner(None, |this| {
544                                 this.visit_pat(&argument.pat);
545                             });
546                             self.visit_ty(&argument.ty)
547                         }
548                         self.visit_fn_ret_ty(&f.decl.output)
549                     }
550                     _ => visit::walk_ty(self, t),
551                 }
552             }
553         }
554
555         struct ItemLowerer<'lcx, 'interner: 'lcx> {
556             lctx: &'lcx mut LoweringContext<'interner>,
557         }
558
559         impl<'lcx, 'interner> ItemLowerer<'lcx, 'interner> {
560             fn with_trait_impl_ref<F>(&mut self, trait_impl_ref: &Option<TraitRef>, f: F)
561             where
562                 F: FnOnce(&mut Self),
563             {
564                 let old = self.lctx.is_in_trait_impl;
565                 self.lctx.is_in_trait_impl = if let &None = trait_impl_ref {
566                     false
567                 } else {
568                     true
569                 };
570                 f(self);
571                 self.lctx.is_in_trait_impl = old;
572             }
573         }
574
575         impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> {
576             fn visit_mod(&mut self, m: &'lcx Mod, _s: Span, _attrs: &[Attribute], n: NodeId) {
577                 self.lctx.modules.insert(n, hir::ModuleItems {
578                     items: BTreeSet::new(),
579                     trait_items: BTreeSet::new(),
580                     impl_items: BTreeSet::new(),
581                 });
582
583                 let old = self.lctx.current_module;
584                 self.lctx.current_module = n;
585                 visit::walk_mod(self, m);
586                 self.lctx.current_module = old;
587             }
588
589             fn visit_item(&mut self, item: &'lcx Item) {
590                 let mut item_hir_id = None;
591                 self.lctx.with_hir_id_owner(item.id, |lctx| {
592                     if let Some(hir_item) = lctx.lower_item(item) {
593                         item_hir_id = Some(hir_item.hir_id);
594                         lctx.insert_item(hir_item);
595                     }
596                 });
597
598                 if let Some(hir_id) = item_hir_id {
599                     let item_generics = match self.lctx.items.get(&hir_id).unwrap().node {
600                         hir::ItemKind::Impl(_, _, _, ref generics, ..)
601                         | hir::ItemKind::Trait(_, _, ref generics, ..) => {
602                             generics.params.clone()
603                         }
604                         _ => HirVec::new(),
605                     };
606
607                     self.lctx.with_parent_impl_lifetime_defs(&item_generics, |this| {
608                         let this = &mut ItemLowerer { lctx: this };
609                         if let ItemKind::Impl(.., ref opt_trait_ref, _, _) = item.node {
610                             this.with_trait_impl_ref(opt_trait_ref, |this| {
611                                 visit::walk_item(this, item)
612                             });
613                         } else {
614                             visit::walk_item(this, item);
615                         }
616                     });
617                 }
618             }
619
620             fn visit_trait_item(&mut self, item: &'lcx TraitItem) {
621                 self.lctx.with_hir_id_owner(item.id, |lctx| {
622                     let hir_item = lctx.lower_trait_item(item);
623                     let id = hir::TraitItemId { hir_id: hir_item.hir_id };
624                     lctx.trait_items.insert(id, hir_item);
625                     lctx.modules.get_mut(&lctx.current_module).unwrap().trait_items.insert(id);
626                 });
627
628                 visit::walk_trait_item(self, item);
629             }
630
631             fn visit_impl_item(&mut self, item: &'lcx ImplItem) {
632                 self.lctx.with_hir_id_owner(item.id, |lctx| {
633                     let hir_item = lctx.lower_impl_item(item);
634                     let id = hir::ImplItemId { hir_id: hir_item.hir_id };
635                     lctx.impl_items.insert(id, hir_item);
636                     lctx.modules.get_mut(&lctx.current_module).unwrap().impl_items.insert(id);
637                 });
638                 visit::walk_impl_item(self, item);
639             }
640         }
641
642         self.lower_node_id(CRATE_NODE_ID);
643         debug_assert!(self.node_id_to_hir_id[CRATE_NODE_ID] == hir::CRATE_HIR_ID);
644
645         visit::walk_crate(&mut MiscCollector { lctx: &mut self, hir_id_owner: None }, c);
646         visit::walk_crate(&mut ItemLowerer { lctx: &mut self }, c);
647
648         let module = self.lower_mod(&c.module);
649         let attrs = self.lower_attrs(&c.attrs);
650         let body_ids = body_ids(&self.bodies);
651
652         self.resolver
653             .definitions()
654             .init_node_id_to_hir_id_mapping(self.node_id_to_hir_id);
655
656         hir::Crate {
657             module,
658             attrs,
659             span: c.span,
660             exported_macros: hir::HirVec::from(self.exported_macros),
661             items: self.items,
662             trait_items: self.trait_items,
663             impl_items: self.impl_items,
664             bodies: self.bodies,
665             body_ids,
666             trait_impls: self.trait_impls,
667             modules: self.modules,
668         }
669     }
670
671     fn insert_item(&mut self, item: hir::Item) {
672         let id = item.hir_id;
673         // FIXME: Use debug_asset-rt
674         assert_eq!(id.local_id, hir::ItemLocalId::from_u32(0));
675         self.items.insert(id, item);
676         self.modules.get_mut(&self.current_module).unwrap().items.insert(id);
677     }
678
679     fn allocate_hir_id_counter(&mut self, owner: NodeId) -> hir::HirId {
680         // Setup the counter if needed
681         self.item_local_id_counters.entry(owner).or_insert(0);
682         // Always allocate the first `HirId` for the owner itself.
683         let lowered = self.lower_node_id_with_owner(owner, owner);
684         debug_assert_eq!(lowered.local_id.as_u32(), 0);
685         lowered
686     }
687
688     fn lower_node_id_generic<F>(&mut self, ast_node_id: NodeId, alloc_hir_id: F) -> hir::HirId
689     where
690         F: FnOnce(&mut Self) -> hir::HirId,
691     {
692         if ast_node_id == DUMMY_NODE_ID {
693             return hir::DUMMY_HIR_ID;
694         }
695
696         let min_size = ast_node_id.as_usize() + 1;
697
698         if min_size > self.node_id_to_hir_id.len() {
699             self.node_id_to_hir_id.resize(min_size, hir::DUMMY_HIR_ID);
700         }
701
702         let existing_hir_id = self.node_id_to_hir_id[ast_node_id];
703
704         if existing_hir_id == hir::DUMMY_HIR_ID {
705             // Generate a new `HirId`.
706             let hir_id = alloc_hir_id(self);
707             self.node_id_to_hir_id[ast_node_id] = hir_id;
708
709             hir_id
710         } else {
711             existing_hir_id
712         }
713     }
714
715     fn with_hir_id_owner<F, T>(&mut self, owner: NodeId, f: F) -> T
716     where
717         F: FnOnce(&mut Self) -> T,
718     {
719         let counter = self.item_local_id_counters
720             .insert(owner, HIR_ID_COUNTER_LOCKED)
721             .unwrap_or_else(|| panic!("No item_local_id_counters entry for {:?}", owner));
722         let def_index = self.resolver.definitions().opt_def_index(owner).unwrap();
723         self.current_hir_id_owner.push((def_index, counter));
724         let ret = f(self);
725         let (new_def_index, new_counter) = self.current_hir_id_owner.pop().unwrap();
726
727         debug_assert!(def_index == new_def_index);
728         debug_assert!(new_counter >= counter);
729
730         let prev = self.item_local_id_counters
731             .insert(owner, new_counter)
732             .unwrap();
733         debug_assert!(prev == HIR_ID_COUNTER_LOCKED);
734         ret
735     }
736
737     /// This method allocates a new `HirId` for the given `NodeId` and stores it in
738     /// the `LoweringContext`'s `NodeId => HirId` map.
739     /// Take care not to call this method if the resulting `HirId` is then not
740     /// actually used in the HIR, as that would trigger an assertion in the
741     /// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped
742     /// properly. Calling the method twice with the same `NodeId` is fine though.
743     fn lower_node_id(&mut self, ast_node_id: NodeId) -> hir::HirId {
744         self.lower_node_id_generic(ast_node_id, |this| {
745             let &mut (def_index, ref mut local_id_counter) =
746                 this.current_hir_id_owner.last_mut().unwrap();
747             let local_id = *local_id_counter;
748             *local_id_counter += 1;
749             hir::HirId {
750                 owner: def_index,
751                 local_id: hir::ItemLocalId::from_u32(local_id),
752             }
753         })
754     }
755
756     fn lower_node_id_with_owner(&mut self, ast_node_id: NodeId, owner: NodeId) -> hir::HirId {
757         self.lower_node_id_generic(ast_node_id, |this| {
758             let local_id_counter = this
759                 .item_local_id_counters
760                 .get_mut(&owner)
761                 .expect("called lower_node_id_with_owner before allocate_hir_id_counter");
762             let local_id = *local_id_counter;
763
764             // We want to be sure not to modify the counter in the map while it
765             // is also on the stack. Otherwise we'll get lost updates when writing
766             // back from the stack to the map.
767             debug_assert!(local_id != HIR_ID_COUNTER_LOCKED);
768
769             *local_id_counter += 1;
770             let def_index = this
771                 .resolver
772                 .definitions()
773                 .opt_def_index(owner)
774                 .expect("You forgot to call `create_def_with_parent` or are lowering node ids \
775                          that do not belong to the current owner");
776
777             hir::HirId {
778                 owner: def_index,
779                 local_id: hir::ItemLocalId::from_u32(local_id),
780             }
781         })
782     }
783
784     fn record_body(&mut self, value: hir::Expr, arguments: HirVec<hir::Arg>) -> hir::BodyId {
785         if self.is_generator && self.is_async_body {
786             span_err!(
787                 self.sess,
788                 value.span,
789                 E0727,
790                 "`async` generators are not yet supported",
791             );
792             self.sess.abort_if_errors();
793         }
794         let body = hir::Body {
795             is_generator: self.is_generator || self.is_async_body,
796             arguments,
797             value,
798         };
799         let id = body.id();
800         self.bodies.insert(id, body);
801         id
802     }
803
804     fn next_id(&mut self) -> hir::HirId {
805         self.lower_node_id(self.sess.next_node_id())
806     }
807
808     fn lower_res(&mut self, res: Res<NodeId>) -> Res {
809         res.map_id(|id| {
810             self.lower_node_id_generic(id, |_| {
811                 panic!("expected node_id to be lowered already for res {:#?}", res)
812             })
813         })
814     }
815
816     fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {
817         self.resolver.get_partial_res(id).map_or(Res::Err, |pr| {
818             if pr.unresolved_segments() != 0 {
819                 bug!("path not fully resolved: {:?}", pr);
820             }
821             pr.base_res()
822         })
823     }
824
825     fn expect_full_res_from_use(&mut self, id: NodeId) -> impl Iterator<Item = Res<NodeId>> {
826         self.resolver.get_import_res(id).present_items()
827     }
828
829     fn diagnostic(&self) -> &errors::Handler {
830         self.sess.diagnostic()
831     }
832
833     /// Reuses the span but adds information like the kind of the desugaring and features that are
834     /// allowed inside this span.
835     fn mark_span_with_reason(
836         &self,
837         reason: CompilerDesugaringKind,
838         span: Span,
839         allow_internal_unstable: Option<Lrc<[Symbol]>>,
840     ) -> Span {
841         let mark = Mark::fresh(Mark::root());
842         mark.set_expn_info(source_map::ExpnInfo {
843             call_site: span,
844             def_site: Some(span),
845             format: source_map::CompilerDesugaring(reason),
846             allow_internal_unstable,
847             allow_internal_unsafe: false,
848             local_inner_macros: false,
849             edition: edition::Edition::from_session(),
850         });
851         span.with_ctxt(SyntaxContext::empty().apply_mark(mark))
852     }
853
854     fn with_anonymous_lifetime_mode<R>(
855         &mut self,
856         anonymous_lifetime_mode: AnonymousLifetimeMode,
857         op: impl FnOnce(&mut Self) -> R,
858     ) -> R {
859         let old_anonymous_lifetime_mode = self.anonymous_lifetime_mode;
860         self.anonymous_lifetime_mode = anonymous_lifetime_mode;
861         let result = op(self);
862         self.anonymous_lifetime_mode = old_anonymous_lifetime_mode;
863         result
864     }
865
866     /// Creates a new hir::GenericParam for every new lifetime and
867     /// type parameter encountered while evaluating `f`. Definitions
868     /// are created with the parent provided. If no `parent_id` is
869     /// provided, no definitions will be returned.
870     ///
871     /// Presuming that in-band lifetimes are enabled, then
872     /// `self.anonymous_lifetime_mode` will be updated to match the
873     /// argument while `f` is running (and restored afterwards).
874     fn collect_in_band_defs<T, F>(
875         &mut self,
876         parent_id: DefId,
877         anonymous_lifetime_mode: AnonymousLifetimeMode,
878         f: F,
879     ) -> (Vec<hir::GenericParam>, T)
880     where
881         F: FnOnce(&mut LoweringContext<'_>) -> (Vec<hir::GenericParam>, T),
882     {
883         assert!(!self.is_collecting_in_band_lifetimes);
884         assert!(self.lifetimes_to_define.is_empty());
885         let old_anonymous_lifetime_mode = self.anonymous_lifetime_mode;
886
887         self.anonymous_lifetime_mode = anonymous_lifetime_mode;
888         self.is_collecting_in_band_lifetimes = true;
889
890         let (in_band_ty_params, res) = f(self);
891
892         self.is_collecting_in_band_lifetimes = false;
893         self.anonymous_lifetime_mode = old_anonymous_lifetime_mode;
894
895         let lifetimes_to_define = self.lifetimes_to_define.split_off(0);
896
897         let params = lifetimes_to_define
898             .into_iter()
899             .map(|(span, hir_name)| self.lifetime_to_generic_param(
900                 span, hir_name, parent_id.index,
901             ))
902             .chain(in_band_ty_params.into_iter())
903             .collect();
904
905         (params, res)
906     }
907
908     /// Converts a lifetime into a new generic parameter.
909     fn lifetime_to_generic_param(
910         &mut self,
911         span: Span,
912         hir_name: ParamName,
913         parent_index: DefIndex,
914     ) -> hir::GenericParam {
915         let node_id = self.sess.next_node_id();
916
917         // Get the name we'll use to make the def-path. Note
918         // that collisions are ok here and this shouldn't
919         // really show up for end-user.
920         let (str_name, kind) = match hir_name {
921             ParamName::Plain(ident) => (
922                 ident.as_interned_str(),
923                 hir::LifetimeParamKind::InBand,
924             ),
925             ParamName::Fresh(_) => (
926                 kw::UnderscoreLifetime.as_interned_str(),
927                 hir::LifetimeParamKind::Elided,
928             ),
929             ParamName::Error => (
930                 kw::UnderscoreLifetime.as_interned_str(),
931                 hir::LifetimeParamKind::Error,
932             ),
933         };
934
935         // Add a definition for the in-band lifetime def.
936         self.resolver.definitions().create_def_with_parent(
937             parent_index,
938             node_id,
939             DefPathData::LifetimeNs(str_name),
940             Mark::root(),
941             span,
942         );
943
944         hir::GenericParam {
945             hir_id: self.lower_node_id(node_id),
946             name: hir_name,
947             attrs: hir_vec![],
948             bounds: hir_vec![],
949             span,
950             pure_wrt_drop: false,
951             kind: hir::GenericParamKind::Lifetime { kind }
952         }
953     }
954
955     /// When there is a reference to some lifetime `'a`, and in-band
956     /// lifetimes are enabled, then we want to push that lifetime into
957     /// the vector of names to define later. In that case, it will get
958     /// added to the appropriate generics.
959     fn maybe_collect_in_band_lifetime(&mut self, ident: Ident) {
960         if !self.is_collecting_in_band_lifetimes {
961             return;
962         }
963
964         if !self.sess.features_untracked().in_band_lifetimes {
965             return;
966         }
967
968         if self.in_scope_lifetimes.contains(&ident.modern()) {
969             return;
970         }
971
972         let hir_name = ParamName::Plain(ident);
973
974         if self.lifetimes_to_define.iter()
975                                    .any(|(_, lt_name)| lt_name.modern() == hir_name.modern()) {
976             return;
977         }
978
979         self.lifetimes_to_define.push((ident.span, hir_name));
980     }
981
982     /// When we have either an elided or `'_` lifetime in an impl
983     /// header, we convert it to an in-band lifetime.
984     fn collect_fresh_in_band_lifetime(&mut self, span: Span) -> ParamName {
985         assert!(self.is_collecting_in_band_lifetimes);
986         let index = self.lifetimes_to_define.len();
987         let hir_name = ParamName::Fresh(index);
988         self.lifetimes_to_define.push((span, hir_name));
989         hir_name
990     }
991
992     // Evaluates `f` with the lifetimes in `params` in-scope.
993     // This is used to track which lifetimes have already been defined, and
994     // which are new in-band lifetimes that need to have a definition created
995     // for them.
996     fn with_in_scope_lifetime_defs<T, F>(&mut self, params: &[GenericParam], f: F) -> T
997     where
998         F: FnOnce(&mut LoweringContext<'_>) -> T,
999     {
1000         let old_len = self.in_scope_lifetimes.len();
1001         let lt_def_names = params.iter().filter_map(|param| match param.kind {
1002             GenericParamKind::Lifetime { .. } => Some(param.ident.modern()),
1003             _ => None,
1004         });
1005         self.in_scope_lifetimes.extend(lt_def_names);
1006
1007         let res = f(self);
1008
1009         self.in_scope_lifetimes.truncate(old_len);
1010         res
1011     }
1012
1013     // Same as the method above, but accepts `hir::GenericParam`s
1014     // instead of `ast::GenericParam`s.
1015     // This should only be used with generics that have already had their
1016     // in-band lifetimes added. In practice, this means that this function is
1017     // only used when lowering a child item of a trait or impl.
1018     fn with_parent_impl_lifetime_defs<T, F>(&mut self,
1019         params: &HirVec<hir::GenericParam>,
1020         f: F
1021     ) -> T where
1022         F: FnOnce(&mut LoweringContext<'_>) -> T,
1023     {
1024         let old_len = self.in_scope_lifetimes.len();
1025         let lt_def_names = params.iter().filter_map(|param| match param.kind {
1026             hir::GenericParamKind::Lifetime { .. } => Some(param.name.ident().modern()),
1027             _ => None,
1028         });
1029         self.in_scope_lifetimes.extend(lt_def_names);
1030
1031         let res = f(self);
1032
1033         self.in_scope_lifetimes.truncate(old_len);
1034         res
1035     }
1036
1037     /// Appends in-band lifetime defs and argument-position `impl
1038     /// Trait` defs to the existing set of generics.
1039     ///
1040     /// Presuming that in-band lifetimes are enabled, then
1041     /// `self.anonymous_lifetime_mode` will be updated to match the
1042     /// argument while `f` is running (and restored afterwards).
1043     fn add_in_band_defs<F, T>(
1044         &mut self,
1045         generics: &Generics,
1046         parent_id: DefId,
1047         anonymous_lifetime_mode: AnonymousLifetimeMode,
1048         f: F,
1049     ) -> (hir::Generics, T)
1050     where
1051         F: FnOnce(&mut LoweringContext<'_>, &mut Vec<hir::GenericParam>) -> T,
1052     {
1053         let (in_band_defs, (mut lowered_generics, res)) = self.with_in_scope_lifetime_defs(
1054             &generics.params,
1055             |this| {
1056                 this.collect_in_band_defs(parent_id, anonymous_lifetime_mode, |this| {
1057                     let mut params = Vec::new();
1058                     // Note: it is necessary to lower generics *before* calling `f`.
1059                     // When lowering `async fn`, there's a final step when lowering
1060                     // the return type that assumes that all in-scope lifetimes have
1061                     // already been added to either `in_scope_lifetimes` or
1062                     // `lifetimes_to_define`. If we swapped the order of these two,
1063                     // in-band-lifetimes introduced by generics or where-clauses
1064                     // wouldn't have been added yet.
1065                     let generics = this.lower_generics(
1066                         generics,
1067                         ImplTraitContext::Universal(&mut params),
1068                     );
1069                     let res = f(this, &mut params);
1070                     (params, (generics, res))
1071                 })
1072             },
1073         );
1074
1075         lowered_generics.params = lowered_generics
1076             .params
1077             .iter()
1078             .cloned()
1079             .chain(in_band_defs)
1080             .collect();
1081
1082         // FIXME(const_generics): the compiler doesn't always cope with
1083         // unsorted generic parameters at the moment, so we make sure
1084         // that they're ordered correctly here for now. (When we chain
1085         // the `in_band_defs`, we might make the order unsorted.)
1086         lowered_generics.params.sort_by_key(|param| {
1087             match param.kind {
1088                 hir::GenericParamKind::Lifetime { .. } => ParamKindOrd::Lifetime,
1089                 hir::GenericParamKind::Type { .. } => ParamKindOrd::Type,
1090                 hir::GenericParamKind::Const { .. } => ParamKindOrd::Const,
1091             }
1092         });
1093
1094         (lowered_generics, res)
1095     }
1096
1097     fn with_catch_scope<T, F>(&mut self, catch_id: NodeId, f: F) -> T
1098     where
1099         F: FnOnce(&mut LoweringContext<'_>) -> T,
1100     {
1101         let len = self.catch_scopes.len();
1102         self.catch_scopes.push(catch_id);
1103
1104         let result = f(self);
1105         assert_eq!(
1106             len + 1,
1107             self.catch_scopes.len(),
1108             "catch scopes should be added and removed in stack order"
1109         );
1110
1111         self.catch_scopes.pop().unwrap();
1112
1113         result
1114     }
1115
1116     fn make_async_expr(
1117         &mut self,
1118         capture_clause: CaptureBy,
1119         closure_node_id: NodeId,
1120         ret_ty: Option<&Ty>,
1121         span: Span,
1122         body: impl FnOnce(&mut LoweringContext<'_>) -> hir::Expr,
1123     ) -> hir::ExprKind {
1124         let prev_is_generator = mem::replace(&mut self.is_generator, false);
1125         let prev_is_async_body = mem::replace(&mut self.is_async_body, true);
1126         let output = match ret_ty {
1127             Some(ty) => FunctionRetTy::Ty(P(ty.clone())),
1128             None => FunctionRetTy::Default(span),
1129         };
1130         let decl = FnDecl {
1131             inputs: vec![],
1132             output,
1133             c_variadic: false
1134         };
1135         // Lower the arguments before the body otherwise the body will call `lower_res` expecting
1136         // the argument to have been assigned an id already.
1137         let arguments = self.lower_args(Some(&decl));
1138         let body_expr = body(self);
1139         let body_id = self.record_body(body_expr, arguments);
1140         self.is_generator = prev_is_generator;
1141         self.is_async_body = prev_is_async_body;
1142
1143         let capture_clause = self.lower_capture_clause(capture_clause);
1144         let decl = self.lower_fn_decl(&decl, None, /* impl trait allowed */ false, None);
1145         let generator = hir::Expr {
1146             hir_id: self.lower_node_id(closure_node_id),
1147             node: hir::ExprKind::Closure(capture_clause, decl, body_id, span,
1148                 Some(hir::GeneratorMovability::Static)),
1149             span,
1150             attrs: ThinVec::new(),
1151         };
1152
1153         let unstable_span = self.mark_span_with_reason(
1154             CompilerDesugaringKind::Async,
1155             span,
1156             Some(vec![sym::gen_future].into()),
1157         );
1158         let gen_future = self.expr_std_path(
1159             unstable_span, &[sym::future, sym::from_generator], None, ThinVec::new());
1160         hir::ExprKind::Call(P(gen_future), hir_vec![generator])
1161     }
1162
1163     fn lower_body<F>(&mut self, decl: Option<&FnDecl>, f: F) -> hir::BodyId
1164     where
1165         F: FnOnce(&mut LoweringContext<'_>) -> hir::Expr,
1166     {
1167         let prev_generator = mem::replace(&mut self.is_generator, false);
1168         let prev_async = mem::replace(&mut self.is_async_body, false);
1169         let arguments = self.lower_args(decl);
1170         let result = f(self);
1171         let r = self.record_body(result, arguments);
1172         self.is_generator = prev_generator;
1173         self.is_async_body = prev_async;
1174         return r;
1175     }
1176
1177     fn with_loop_scope<T, F>(&mut self, loop_id: NodeId, f: F) -> T
1178     where
1179         F: FnOnce(&mut LoweringContext<'_>) -> T,
1180     {
1181         // We're no longer in the base loop's condition; we're in another loop.
1182         let was_in_loop_condition = self.is_in_loop_condition;
1183         self.is_in_loop_condition = false;
1184
1185         let len = self.loop_scopes.len();
1186         self.loop_scopes.push(loop_id);
1187
1188         let result = f(self);
1189         assert_eq!(
1190             len + 1,
1191             self.loop_scopes.len(),
1192             "Loop scopes should be added and removed in stack order"
1193         );
1194
1195         self.loop_scopes.pop().unwrap();
1196
1197         self.is_in_loop_condition = was_in_loop_condition;
1198
1199         result
1200     }
1201
1202     fn with_loop_condition_scope<T, F>(&mut self, f: F) -> T
1203     where
1204         F: FnOnce(&mut LoweringContext<'_>) -> T,
1205     {
1206         let was_in_loop_condition = self.is_in_loop_condition;
1207         self.is_in_loop_condition = true;
1208
1209         let result = f(self);
1210
1211         self.is_in_loop_condition = was_in_loop_condition;
1212
1213         result
1214     }
1215
1216     fn with_new_scopes<T, F>(&mut self, f: F) -> T
1217     where
1218         F: FnOnce(&mut LoweringContext<'_>) -> T,
1219     {
1220         let was_in_loop_condition = self.is_in_loop_condition;
1221         self.is_in_loop_condition = false;
1222
1223         let catch_scopes = mem::replace(&mut self.catch_scopes, Vec::new());
1224         let loop_scopes = mem::replace(&mut self.loop_scopes, Vec::new());
1225         let ret = f(self);
1226         self.catch_scopes = catch_scopes;
1227         self.loop_scopes = loop_scopes;
1228
1229         self.is_in_loop_condition = was_in_loop_condition;
1230
1231         ret
1232     }
1233
1234     fn def_key(&mut self, id: DefId) -> DefKey {
1235         if id.is_local() {
1236             self.resolver.definitions().def_key(id.index)
1237         } else {
1238             self.cstore.def_key(id)
1239         }
1240     }
1241
1242     fn lower_label(&mut self, label: Option<Label>) -> Option<hir::Label> {
1243         label.map(|label| hir::Label {
1244             ident: label.ident,
1245         })
1246     }
1247
1248     fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hir::Destination {
1249         let target_id = match destination {
1250             Some((id, _)) => {
1251                 if let Some(loop_id) = self.resolver.get_label_res(id) {
1252                     Ok(self.lower_node_id(loop_id))
1253                 } else {
1254                     Err(hir::LoopIdError::UnresolvedLabel)
1255                 }
1256             }
1257             None => {
1258                 self.loop_scopes
1259                     .last()
1260                     .cloned()
1261                     .map(|id| Ok(self.lower_node_id(id)))
1262                     .unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
1263                     .into()
1264             }
1265         };
1266         hir::Destination {
1267             label: self.lower_label(destination.map(|(_, label)| label)),
1268             target_id,
1269         }
1270     }
1271
1272     fn lower_attrs(&mut self, attrs: &[Attribute]) -> hir::HirVec<Attribute> {
1273         attrs
1274             .iter()
1275             .map(|a| self.lower_attr(a))
1276             .collect()
1277     }
1278
1279     fn lower_attr(&mut self, attr: &Attribute) -> Attribute {
1280         // Note that we explicitly do not walk the path. Since we don't really
1281         // lower attributes (we use the AST version) there is nowhere to keep
1282         // the `HirId`s. We don't actually need HIR version of attributes anyway.
1283         Attribute {
1284             id: attr.id,
1285             style: attr.style,
1286             path: attr.path.clone(),
1287             tokens: self.lower_token_stream(attr.tokens.clone()),
1288             is_sugared_doc: attr.is_sugared_doc,
1289             span: attr.span,
1290         }
1291     }
1292
1293     fn lower_token_stream(&mut self, tokens: TokenStream) -> TokenStream {
1294         tokens
1295             .into_trees()
1296             .flat_map(|tree| self.lower_token_tree(tree).into_trees())
1297             .collect()
1298     }
1299
1300     fn lower_token_tree(&mut self, tree: TokenTree) -> TokenStream {
1301         match tree {
1302             TokenTree::Token(span, token) => self.lower_token(token, span),
1303             TokenTree::Delimited(span, delim, tts) => TokenTree::Delimited(
1304                 span,
1305                 delim,
1306                 self.lower_token_stream(tts),
1307             ).into(),
1308         }
1309     }
1310
1311     fn lower_token(&mut self, token: Token, span: Span) -> TokenStream {
1312         match token {
1313             Token::Interpolated(nt) => {
1314                 let tts = nt.to_tokenstream(&self.sess.parse_sess, span);
1315                 self.lower_token_stream(tts)
1316             }
1317             other => TokenTree::Token(span, other).into(),
1318         }
1319     }
1320
1321     fn lower_arm(&mut self, arm: &Arm) -> hir::Arm {
1322         hir::Arm {
1323             hir_id: self.next_id(),
1324             attrs: self.lower_attrs(&arm.attrs),
1325             pats: arm.pats.iter().map(|x| self.lower_pat(x)).collect(),
1326             guard: match arm.guard {
1327                 Some(Guard::If(ref x)) => Some(hir::Guard::If(P(self.lower_expr(x)))),
1328                 _ => None,
1329             },
1330             body: P(self.lower_expr(&arm.body)),
1331             span: arm.span,
1332         }
1333     }
1334
1335     fn lower_ty_binding(&mut self, b: &TypeBinding,
1336                         itctx: ImplTraitContext<'_>) -> hir::TypeBinding {
1337         hir::TypeBinding {
1338             hir_id: self.lower_node_id(b.id),
1339             ident: b.ident,
1340             ty: self.lower_ty(&b.ty, itctx),
1341             span: b.span,
1342         }
1343     }
1344
1345     fn lower_generic_arg(&mut self,
1346                         arg: &ast::GenericArg,
1347                         itctx: ImplTraitContext<'_>)
1348                         -> hir::GenericArg {
1349         match arg {
1350             ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(&lt)),
1351             ast::GenericArg::Type(ty) => GenericArg::Type(self.lower_ty_direct(&ty, itctx)),
1352             ast::GenericArg::Const(ct) => {
1353                 GenericArg::Const(ConstArg {
1354                     value: self.lower_anon_const(&ct),
1355                     span: ct.value.span,
1356                 })
1357             }
1358         }
1359     }
1360
1361     fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext<'_>) -> P<hir::Ty> {
1362         P(self.lower_ty_direct(t, itctx))
1363     }
1364
1365     fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_>) -> hir::Ty {
1366         let kind = match t.node {
1367             TyKind::Infer => hir::TyKind::Infer,
1368             TyKind::Err => hir::TyKind::Err,
1369             TyKind::Slice(ref ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
1370             TyKind::Ptr(ref mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
1371             TyKind::Rptr(ref region, ref mt) => {
1372                 let span = self.sess.source_map().next_point(t.span.shrink_to_lo());
1373                 let lifetime = match *region {
1374                     Some(ref lt) => self.lower_lifetime(lt),
1375                     None => self.elided_ref_lifetime(span),
1376                 };
1377                 hir::TyKind::Rptr(lifetime, self.lower_mt(mt, itctx))
1378             }
1379             TyKind::BareFn(ref f) => self.with_in_scope_lifetime_defs(
1380                 &f.generic_params,
1381                 |this| {
1382                     this.with_anonymous_lifetime_mode(
1383                         AnonymousLifetimeMode::PassThrough,
1384                         |this| {
1385                             hir::TyKind::BareFn(P(hir::BareFnTy {
1386                                 generic_params: this.lower_generic_params(
1387                                     &f.generic_params,
1388                                     &NodeMap::default(),
1389                                     ImplTraitContext::disallowed(),
1390                                 ),
1391                                 unsafety: this.lower_unsafety(f.unsafety),
1392                                 abi: f.abi,
1393                                 decl: this.lower_fn_decl(&f.decl, None, false, None),
1394                                 arg_names: this.lower_fn_args_to_names(&f.decl),
1395                             }))
1396                         },
1397                     )
1398                 },
1399             ),
1400             TyKind::Never => hir::TyKind::Never,
1401             TyKind::Tup(ref tys) => {
1402                 hir::TyKind::Tup(tys.iter().map(|ty| {
1403                     self.lower_ty_direct(ty, itctx.reborrow())
1404                 }).collect())
1405             }
1406             TyKind::Paren(ref ty) => {
1407                 return self.lower_ty_direct(ty, itctx);
1408             }
1409             TyKind::Path(ref qself, ref path) => {
1410                 let id = self.lower_node_id(t.id);
1411                 let qpath = self.lower_qpath(t.id, qself, path, ParamMode::Explicit, itctx);
1412                 let ty = self.ty_path(id, t.span, qpath);
1413                 if let hir::TyKind::TraitObject(..) = ty.node {
1414                     self.maybe_lint_bare_trait(t.span, t.id, qself.is_none() && path.is_global());
1415                 }
1416                 return ty;
1417             }
1418             TyKind::ImplicitSelf => {
1419                 let res = self.expect_full_res(t.id);
1420                 let res = self.lower_res(res);
1421                 hir::TyKind::Path(hir::QPath::Resolved(
1422                     None,
1423                     P(hir::Path {
1424                         res,
1425                         segments: hir_vec![hir::PathSegment::from_ident(
1426                             Ident::with_empty_ctxt(kw::SelfUpper)
1427                         )],
1428                         span: t.span,
1429                     }),
1430                 ))
1431             },
1432             TyKind::Array(ref ty, ref length) => {
1433                 hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_anon_const(length))
1434             }
1435             TyKind::Typeof(ref expr) => {
1436                 hir::TyKind::Typeof(self.lower_anon_const(expr))
1437             }
1438             TyKind::TraitObject(ref bounds, kind) => {
1439                 let mut lifetime_bound = None;
1440                 let bounds = bounds
1441                     .iter()
1442                     .filter_map(|bound| match *bound {
1443                         GenericBound::Trait(ref ty, TraitBoundModifier::None) => {
1444                             Some(self.lower_poly_trait_ref(ty, itctx.reborrow()))
1445                         }
1446                         GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
1447                         GenericBound::Outlives(ref lifetime) => {
1448                             if lifetime_bound.is_none() {
1449                                 lifetime_bound = Some(self.lower_lifetime(lifetime));
1450                             }
1451                             None
1452                         }
1453                     })
1454                     .collect();
1455                 let lifetime_bound =
1456                     lifetime_bound.unwrap_or_else(|| self.elided_dyn_bound(t.span));
1457                 if kind != TraitObjectSyntax::Dyn {
1458                     self.maybe_lint_bare_trait(t.span, t.id, false);
1459                 }
1460                 hir::TyKind::TraitObject(bounds, lifetime_bound)
1461             }
1462             TyKind::ImplTrait(def_node_id, ref bounds) => {
1463                 let span = t.span;
1464                 match itctx {
1465                     ImplTraitContext::Existential(fn_def_id) => {
1466                         self.lower_existential_impl_trait(
1467                             span, fn_def_id, def_node_id,
1468                             |this| this.lower_param_bounds(bounds, itctx),
1469                         )
1470                     }
1471                     ImplTraitContext::Universal(in_band_ty_params) => {
1472                         // Add a definition for the in-band `Param`.
1473                         let def_index = self
1474                             .resolver
1475                             .definitions()
1476                             .opt_def_index(def_node_id)
1477                             .unwrap();
1478
1479                         let hir_bounds = self.lower_param_bounds(
1480                             bounds,
1481                             ImplTraitContext::Universal(in_band_ty_params),
1482                         );
1483                         // Set the name to `impl Bound1 + Bound2`.
1484                         let ident = Ident::from_str(&pprust::ty_to_string(t)).with_span_pos(span);
1485                         in_band_ty_params.push(hir::GenericParam {
1486                             hir_id: self.lower_node_id(def_node_id),
1487                             name: ParamName::Plain(ident),
1488                             pure_wrt_drop: false,
1489                             attrs: hir_vec![],
1490                             bounds: hir_bounds,
1491                             span,
1492                             kind: hir::GenericParamKind::Type {
1493                                 default: None,
1494                                 synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
1495                             }
1496                         });
1497
1498                         hir::TyKind::Path(hir::QPath::Resolved(
1499                             None,
1500                             P(hir::Path {
1501                                 span,
1502                                 res: Res::Def(DefKind::TyParam, DefId::local(def_index)),
1503                                 segments: hir_vec![hir::PathSegment::from_ident(ident)],
1504                             }),
1505                         ))
1506                     }
1507                     ImplTraitContext::Disallowed(pos) => {
1508                         let allowed_in = if self.sess.features_untracked()
1509                                                 .impl_trait_in_bindings {
1510                             "bindings or function and inherent method return types"
1511                         } else {
1512                             "function and inherent method return types"
1513                         };
1514                         let mut err = struct_span_err!(
1515                             self.sess,
1516                             t.span,
1517                             E0562,
1518                             "`impl Trait` not allowed outside of {}",
1519                             allowed_in,
1520                         );
1521                         if pos == ImplTraitPosition::Binding &&
1522                             nightly_options::is_nightly_build() {
1523                             help!(err,
1524                                   "add #![feature(impl_trait_in_bindings)] to the crate attributes \
1525                                    to enable");
1526                         }
1527                         err.emit();
1528                         hir::TyKind::Err
1529                     }
1530                 }
1531             }
1532             TyKind::Mac(_) => panic!("TyMac should have been expanded by now."),
1533             TyKind::CVarArgs => {
1534                 // Create the implicit lifetime of the "spoofed" `VaList`.
1535                 let span = self.sess.source_map().next_point(t.span.shrink_to_lo());
1536                 let lt = self.new_implicit_lifetime(span);
1537                 hir::TyKind::CVarArgs(lt)
1538             },
1539         };
1540
1541         hir::Ty {
1542             node: kind,
1543             span: t.span,
1544             hir_id: self.lower_node_id(t.id),
1545         }
1546     }
1547
1548     fn lower_existential_impl_trait(
1549         &mut self,
1550         span: Span,
1551         fn_def_id: Option<DefId>,
1552         exist_ty_node_id: NodeId,
1553         lower_bounds: impl FnOnce(&mut LoweringContext<'_>) -> hir::GenericBounds,
1554     ) -> hir::TyKind {
1555         // Make sure we know that some funky desugaring has been going on here.
1556         // This is a first: there is code in other places like for loop
1557         // desugaring that explicitly states that we don't want to track that.
1558         // Not tracking it makes lints in rustc and clippy very fragile as
1559         // frequently opened issues show.
1560         let exist_ty_span = self.mark_span_with_reason(
1561             CompilerDesugaringKind::ExistentialReturnType,
1562             span,
1563             None,
1564         );
1565
1566         let exist_ty_def_index = self
1567             .resolver
1568             .definitions()
1569             .opt_def_index(exist_ty_node_id)
1570             .unwrap();
1571
1572         self.allocate_hir_id_counter(exist_ty_node_id);
1573
1574         let hir_bounds = self.with_hir_id_owner(exist_ty_node_id, lower_bounds);
1575
1576         let (lifetimes, lifetime_defs) = self.lifetimes_from_impl_trait_bounds(
1577             exist_ty_node_id,
1578             exist_ty_def_index,
1579             &hir_bounds,
1580         );
1581
1582         self.with_hir_id_owner(exist_ty_node_id, |lctx| {
1583             let exist_ty_item = hir::ExistTy {
1584                 generics: hir::Generics {
1585                     params: lifetime_defs,
1586                     where_clause: hir::WhereClause {
1587                         hir_id: lctx.next_id(),
1588                         predicates: hir_vec![],
1589                     },
1590                     span,
1591                 },
1592                 bounds: hir_bounds,
1593                 impl_trait_fn: fn_def_id,
1594                 origin: hir::ExistTyOrigin::ReturnImplTrait,
1595             };
1596
1597             trace!("exist ty from impl trait def index: {:#?}", exist_ty_def_index);
1598             let exist_ty_id = lctx.generate_existential_type(
1599                 exist_ty_node_id,
1600                 exist_ty_item,
1601                 span,
1602                 exist_ty_span,
1603             );
1604
1605             // `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
1606             hir::TyKind::Def(hir::ItemId { id: exist_ty_id }, lifetimes)
1607         })
1608     }
1609
1610     /// Registers a new existential type with the proper NodeIds and
1611     /// returns the lowered node ID for the existential type.
1612     fn generate_existential_type(
1613         &mut self,
1614         exist_ty_node_id: NodeId,
1615         exist_ty_item: hir::ExistTy,
1616         span: Span,
1617         exist_ty_span: Span,
1618     ) -> hir::HirId {
1619         let exist_ty_item_kind = hir::ItemKind::Existential(exist_ty_item);
1620         let exist_ty_id = self.lower_node_id(exist_ty_node_id);
1621         // Generate an `existential type Foo: Trait;` declaration.
1622         trace!("registering existential type with id {:#?}", exist_ty_id);
1623         let exist_ty_item = hir::Item {
1624             hir_id: exist_ty_id,
1625             ident: Ident::invalid(),
1626             attrs: Default::default(),
1627             node: exist_ty_item_kind,
1628             vis: respan(span.shrink_to_lo(), hir::VisibilityKind::Inherited),
1629             span: exist_ty_span,
1630         };
1631
1632         // Insert the item into the global item list. This usually happens
1633         // automatically for all AST items. But this existential type item
1634         // does not actually exist in the AST.
1635         self.insert_item(exist_ty_item);
1636         exist_ty_id
1637     }
1638
1639     fn lifetimes_from_impl_trait_bounds(
1640         &mut self,
1641         exist_ty_id: NodeId,
1642         parent_index: DefIndex,
1643         bounds: &hir::GenericBounds,
1644     ) -> (HirVec<hir::GenericArg>, HirVec<hir::GenericParam>) {
1645         // This visitor walks over impl trait bounds and creates defs for all lifetimes which
1646         // appear in the bounds, excluding lifetimes that are created within the bounds.
1647         // E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`.
1648         struct ImplTraitLifetimeCollector<'r, 'a: 'r> {
1649             context: &'r mut LoweringContext<'a>,
1650             parent: DefIndex,
1651             exist_ty_id: NodeId,
1652             collect_elided_lifetimes: bool,
1653             currently_bound_lifetimes: Vec<hir::LifetimeName>,
1654             already_defined_lifetimes: FxHashSet<hir::LifetimeName>,
1655             output_lifetimes: Vec<hir::GenericArg>,
1656             output_lifetime_params: Vec<hir::GenericParam>,
1657         }
1658
1659         impl<'r, 'a: 'r, 'v> hir::intravisit::Visitor<'v> for ImplTraitLifetimeCollector<'r, 'a> {
1660             fn nested_visit_map<'this>(
1661                 &'this mut self,
1662             ) -> hir::intravisit::NestedVisitorMap<'this, 'v> {
1663                 hir::intravisit::NestedVisitorMap::None
1664             }
1665
1666             fn visit_generic_args(&mut self, span: Span, parameters: &'v hir::GenericArgs) {
1667                 // Don't collect elided lifetimes used inside of `Fn()` syntax.
1668                 if parameters.parenthesized {
1669                     let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
1670                     self.collect_elided_lifetimes = false;
1671                     hir::intravisit::walk_generic_args(self, span, parameters);
1672                     self.collect_elided_lifetimes = old_collect_elided_lifetimes;
1673                 } else {
1674                     hir::intravisit::walk_generic_args(self, span, parameters);
1675                 }
1676             }
1677
1678             fn visit_ty(&mut self, t: &'v hir::Ty) {
1679                 // Don't collect elided lifetimes used inside of `fn()` syntax.
1680                 if let hir::TyKind::BareFn(_) = t.node {
1681                     let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
1682                     self.collect_elided_lifetimes = false;
1683
1684                     // Record the "stack height" of `for<'a>` lifetime bindings
1685                     // to be able to later fully undo their introduction.
1686                     let old_len = self.currently_bound_lifetimes.len();
1687                     hir::intravisit::walk_ty(self, t);
1688                     self.currently_bound_lifetimes.truncate(old_len);
1689
1690                     self.collect_elided_lifetimes = old_collect_elided_lifetimes;
1691                 } else {
1692                     hir::intravisit::walk_ty(self, t)
1693                 }
1694             }
1695
1696             fn visit_poly_trait_ref(
1697                 &mut self,
1698                 trait_ref: &'v hir::PolyTraitRef,
1699                 modifier: hir::TraitBoundModifier,
1700             ) {
1701                 // Record the "stack height" of `for<'a>` lifetime bindings
1702                 // to be able to later fully undo their introduction.
1703                 let old_len = self.currently_bound_lifetimes.len();
1704                 hir::intravisit::walk_poly_trait_ref(self, trait_ref, modifier);
1705                 self.currently_bound_lifetimes.truncate(old_len);
1706             }
1707
1708             fn visit_generic_param(&mut self, param: &'v hir::GenericParam) {
1709                 // Record the introduction of 'a in `for<'a> ...`.
1710                 if let hir::GenericParamKind::Lifetime { .. } = param.kind {
1711                     // Introduce lifetimes one at a time so that we can handle
1712                     // cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd>`.
1713                     let lt_name = hir::LifetimeName::Param(param.name);
1714                     self.currently_bound_lifetimes.push(lt_name);
1715                 }
1716
1717                 hir::intravisit::walk_generic_param(self, param);
1718             }
1719
1720             fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
1721                 let name = match lifetime.name {
1722                     hir::LifetimeName::Implicit | hir::LifetimeName::Underscore => {
1723                         if self.collect_elided_lifetimes {
1724                             // Use `'_` for both implicit and underscore lifetimes in
1725                             // `abstract type Foo<'_>: SomeTrait<'_>;`.
1726                             hir::LifetimeName::Underscore
1727                         } else {
1728                             return;
1729                         }
1730                     }
1731                     hir::LifetimeName::Param(_) => lifetime.name,
1732                     hir::LifetimeName::Error | hir::LifetimeName::Static => return,
1733                 };
1734
1735                 if !self.currently_bound_lifetimes.contains(&name)
1736                     && !self.already_defined_lifetimes.contains(&name) {
1737                     self.already_defined_lifetimes.insert(name);
1738
1739                     self.output_lifetimes.push(hir::GenericArg::Lifetime(hir::Lifetime {
1740                         hir_id: self.context.next_id(),
1741                         span: lifetime.span,
1742                         name,
1743                     }));
1744
1745                     let def_node_id = self.context.sess.next_node_id();
1746                     let hir_id =
1747                         self.context.lower_node_id_with_owner(def_node_id, self.exist_ty_id);
1748                     self.context.resolver.definitions().create_def_with_parent(
1749                         self.parent,
1750                         def_node_id,
1751                         DefPathData::LifetimeNs(name.ident().as_interned_str()),
1752                         Mark::root(),
1753                         lifetime.span,
1754                     );
1755
1756                     let (name, kind) = match name {
1757                         hir::LifetimeName::Underscore => (
1758                             hir::ParamName::Plain(Ident::with_empty_ctxt(kw::UnderscoreLifetime)),
1759                             hir::LifetimeParamKind::Elided,
1760                         ),
1761                         hir::LifetimeName::Param(param_name) => (
1762                             param_name,
1763                             hir::LifetimeParamKind::Explicit,
1764                         ),
1765                         _ => bug!("expected LifetimeName::Param or ParamName::Plain"),
1766                     };
1767
1768                     self.output_lifetime_params.push(hir::GenericParam {
1769                         hir_id,
1770                         name,
1771                         span: lifetime.span,
1772                         pure_wrt_drop: false,
1773                         attrs: hir_vec![],
1774                         bounds: hir_vec![],
1775                         kind: hir::GenericParamKind::Lifetime { kind }
1776                     });
1777                 }
1778             }
1779         }
1780
1781         let mut lifetime_collector = ImplTraitLifetimeCollector {
1782             context: self,
1783             parent: parent_index,
1784             exist_ty_id,
1785             collect_elided_lifetimes: true,
1786             currently_bound_lifetimes: Vec::new(),
1787             already_defined_lifetimes: FxHashSet::default(),
1788             output_lifetimes: Vec::new(),
1789             output_lifetime_params: Vec::new(),
1790         };
1791
1792         for bound in bounds {
1793             hir::intravisit::walk_param_bound(&mut lifetime_collector, &bound);
1794         }
1795
1796         (
1797             lifetime_collector.output_lifetimes.into(),
1798             lifetime_collector.output_lifetime_params.into(),
1799         )
1800     }
1801
1802     fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod {
1803         hir::ForeignMod {
1804             abi: fm.abi,
1805             items: fm.items
1806                 .iter()
1807                 .map(|x| self.lower_foreign_item(x))
1808                 .collect(),
1809         }
1810     }
1811
1812     fn lower_global_asm(&mut self, ga: &GlobalAsm) -> P<hir::GlobalAsm> {
1813         P(hir::GlobalAsm {
1814             asm: ga.asm,
1815             ctxt: ga.ctxt,
1816         })
1817     }
1818
1819     fn lower_variant(&mut self, v: &Variant) -> hir::Variant {
1820         Spanned {
1821             node: hir::VariantKind {
1822                 ident: v.node.ident,
1823                 id: self.lower_node_id(v.node.id),
1824                 attrs: self.lower_attrs(&v.node.attrs),
1825                 data: self.lower_variant_data(&v.node.data),
1826                 disr_expr: v.node.disr_expr.as_ref().map(|e| self.lower_anon_const(e)),
1827             },
1828             span: v.span,
1829         }
1830     }
1831
1832     fn lower_qpath(
1833         &mut self,
1834         id: NodeId,
1835         qself: &Option<QSelf>,
1836         p: &Path,
1837         param_mode: ParamMode,
1838         mut itctx: ImplTraitContext<'_>,
1839     ) -> hir::QPath {
1840         let qself_position = qself.as_ref().map(|q| q.position);
1841         let qself = qself.as_ref().map(|q| self.lower_ty(&q.ty, itctx.reborrow()));
1842
1843         let partial_res = self.resolver
1844             .get_partial_res(id)
1845             .unwrap_or_else(|| PartialRes::new(Res::Err));
1846
1847         let proj_start = p.segments.len() - partial_res.unresolved_segments();
1848         let path = P(hir::Path {
1849             res: self.lower_res(partial_res.base_res()),
1850             segments: p.segments[..proj_start]
1851                 .iter()
1852                 .enumerate()
1853                 .map(|(i, segment)| {
1854                     let param_mode = match (qself_position, param_mode) {
1855                         (Some(j), ParamMode::Optional) if i < j => {
1856                             // This segment is part of the trait path in a
1857                             // qualified path - one of `a`, `b` or `Trait`
1858                             // in `<X as a::b::Trait>::T::U::method`.
1859                             ParamMode::Explicit
1860                         }
1861                         _ => param_mode,
1862                     };
1863
1864                     // Figure out if this is a type/trait segment,
1865                     // which may need lifetime elision performed.
1866                     let parent_def_id = |this: &mut Self, def_id: DefId| DefId {
1867                         krate: def_id.krate,
1868                         index: this.def_key(def_id).parent.expect("missing parent"),
1869                     };
1870                     let type_def_id = match partial_res.base_res() {
1871                         Res::Def(DefKind::AssocTy, def_id) if i + 2 == proj_start => {
1872                             Some(parent_def_id(self, def_id))
1873                         }
1874                         Res::Def(DefKind::Variant, def_id) if i + 1 == proj_start => {
1875                             Some(parent_def_id(self, def_id))
1876                         }
1877                         Res::Def(DefKind::Struct, def_id)
1878                         | Res::Def(DefKind::Union, def_id)
1879                         | Res::Def(DefKind::Enum, def_id)
1880                         | Res::Def(DefKind::TyAlias, def_id)
1881                         | Res::Def(DefKind::Trait, def_id) if i + 1 == proj_start =>
1882                         {
1883                             Some(def_id)
1884                         }
1885                         _ => None,
1886                     };
1887                     let parenthesized_generic_args = match partial_res.base_res() {
1888                         // `a::b::Trait(Args)`
1889                         Res::Def(DefKind::Trait, _)
1890                             if i + 1 == proj_start => ParenthesizedGenericArgs::Ok,
1891                         // `a::b::Trait(Args)::TraitItem`
1892                         Res::Def(DefKind::Method, _)
1893                         | Res::Def(DefKind::AssocConst, _)
1894                         | Res::Def(DefKind::AssocTy, _)
1895                             if i + 2 == proj_start =>
1896                         {
1897                             ParenthesizedGenericArgs::Ok
1898                         }
1899                         // Avoid duplicated errors.
1900                         Res::Err => ParenthesizedGenericArgs::Ok,
1901                         // An error
1902                         Res::Def(DefKind::Struct, _)
1903                         | Res::Def(DefKind::Enum, _)
1904                         | Res::Def(DefKind::Union, _)
1905                         | Res::Def(DefKind::TyAlias, _)
1906                         | Res::Def(DefKind::Variant, _) if i + 1 == proj_start =>
1907                         {
1908                             ParenthesizedGenericArgs::Err
1909                         }
1910                         // A warning for now, for compatibility reasons
1911                         _ => ParenthesizedGenericArgs::Warn,
1912                     };
1913
1914                     let num_lifetimes = type_def_id.map_or(0, |def_id| {
1915                         if let Some(&n) = self.type_def_lifetime_params.get(&def_id) {
1916                             return n;
1917                         }
1918                         assert!(!def_id.is_local());
1919                         let item_generics =
1920                             self.cstore.item_generics_cloned_untracked(def_id, self.sess);
1921                         let n = item_generics.own_counts().lifetimes;
1922                         self.type_def_lifetime_params.insert(def_id, n);
1923                         n
1924                     });
1925                     self.lower_path_segment(
1926                         p.span,
1927                         segment,
1928                         param_mode,
1929                         num_lifetimes,
1930                         parenthesized_generic_args,
1931                         itctx.reborrow(),
1932                         None,
1933                     )
1934                 })
1935                 .collect(),
1936             span: p.span,
1937         });
1938
1939         // Simple case, either no projections, or only fully-qualified.
1940         // E.g., `std::mem::size_of` or `<I as Iterator>::Item`.
1941         if partial_res.unresolved_segments() == 0 {
1942             return hir::QPath::Resolved(qself, path);
1943         }
1944
1945         // Create the innermost type that we're projecting from.
1946         let mut ty = if path.segments.is_empty() {
1947             // If the base path is empty that means there exists a
1948             // syntactical `Self`, e.g., `&i32` in `<&i32>::clone`.
1949             qself.expect("missing QSelf for <T>::...")
1950         } else {
1951             // Otherwise, the base path is an implicit `Self` type path,
1952             // e.g., `Vec` in `Vec::new` or `<I as Iterator>::Item` in
1953             // `<I as Iterator>::Item::default`.
1954             let new_id = self.next_id();
1955             P(self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path)))
1956         };
1957
1958         // Anything after the base path are associated "extensions",
1959         // out of which all but the last one are associated types,
1960         // e.g., for `std::vec::Vec::<T>::IntoIter::Item::clone`:
1961         // * base path is `std::vec::Vec<T>`
1962         // * "extensions" are `IntoIter`, `Item` and `clone`
1963         // * type nodes are:
1964         //   1. `std::vec::Vec<T>` (created above)
1965         //   2. `<std::vec::Vec<T>>::IntoIter`
1966         //   3. `<<std::vec::Vec<T>>::IntoIter>::Item`
1967         // * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
1968         for (i, segment) in p.segments.iter().enumerate().skip(proj_start) {
1969             let segment = P(self.lower_path_segment(
1970                 p.span,
1971                 segment,
1972                 param_mode,
1973                 0,
1974                 ParenthesizedGenericArgs::Warn,
1975                 itctx.reborrow(),
1976                 None,
1977             ));
1978             let qpath = hir::QPath::TypeRelative(ty, segment);
1979
1980             // It's finished, return the extension of the right node type.
1981             if i == p.segments.len() - 1 {
1982                 return qpath;
1983             }
1984
1985             // Wrap the associated extension in another type node.
1986             let new_id = self.next_id();
1987             ty = P(self.ty_path(new_id, p.span, qpath));
1988         }
1989
1990         // We should've returned in the for loop above.
1991         span_bug!(
1992             p.span,
1993             "lower_qpath: no final extension segment in {}..{}",
1994             proj_start,
1995             p.segments.len()
1996         )
1997     }
1998
1999     fn lower_path_extra(
2000         &mut self,
2001         res: Res,
2002         p: &Path,
2003         param_mode: ParamMode,
2004         explicit_owner: Option<NodeId>,
2005     ) -> hir::Path {
2006         hir::Path {
2007             res,
2008             segments: p.segments
2009                 .iter()
2010                 .map(|segment| {
2011                     self.lower_path_segment(
2012                         p.span,
2013                         segment,
2014                         param_mode,
2015                         0,
2016                         ParenthesizedGenericArgs::Err,
2017                         ImplTraitContext::disallowed(),
2018                         explicit_owner,
2019                     )
2020                 })
2021                 .collect(),
2022             span: p.span,
2023         }
2024     }
2025
2026     fn lower_path(&mut self, id: NodeId, p: &Path, param_mode: ParamMode) -> hir::Path {
2027         let res = self.expect_full_res(id);
2028         let res = self.lower_res(res);
2029         self.lower_path_extra(res, p, param_mode, None)
2030     }
2031
2032     fn lower_path_segment(
2033         &mut self,
2034         path_span: Span,
2035         segment: &PathSegment,
2036         param_mode: ParamMode,
2037         expected_lifetimes: usize,
2038         parenthesized_generic_args: ParenthesizedGenericArgs,
2039         itctx: ImplTraitContext<'_>,
2040         explicit_owner: Option<NodeId>,
2041     ) -> hir::PathSegment {
2042         let (mut generic_args, infer_types) = if let Some(ref generic_args) = segment.args {
2043             let msg = "parenthesized type parameters may only be used with a `Fn` trait";
2044             match **generic_args {
2045                 GenericArgs::AngleBracketed(ref data) => {
2046                     self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
2047                 }
2048                 GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args {
2049                     ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data),
2050                     ParenthesizedGenericArgs::Warn => {
2051                         self.sess.buffer_lint(
2052                             PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
2053                             CRATE_NODE_ID,
2054                             data.span,
2055                             msg.into(),
2056                         );
2057                         (hir::GenericArgs::none(), true)
2058                     }
2059                     ParenthesizedGenericArgs::Err => {
2060                         let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg);
2061                         err.span_label(data.span, "only `Fn` traits may use parentheses");
2062                         if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) {
2063                             // Do not suggest going from `Trait()` to `Trait<>`
2064                             if data.inputs.len() > 0 {
2065                                 err.span_suggestion(
2066                                     data.span,
2067                                     "use angle brackets instead",
2068                                     format!("<{}>", &snippet[1..snippet.len() - 1]),
2069                                     Applicability::MaybeIncorrect,
2070                                 );
2071                             }
2072                         };
2073                         err.emit();
2074                         (self.lower_angle_bracketed_parameter_data(
2075                             &data.as_angle_bracketed_args(),
2076                             param_mode,
2077                             itctx).0,
2078                          false)
2079                     }
2080                 },
2081             }
2082         } else {
2083             self.lower_angle_bracketed_parameter_data(&Default::default(), param_mode, itctx)
2084         };
2085
2086         let has_lifetimes = generic_args.args.iter().any(|arg| match arg {
2087             GenericArg::Lifetime(_) => true,
2088             _ => false,
2089         });
2090         let first_generic_span = generic_args.args.iter().map(|a| a.span())
2091             .chain(generic_args.bindings.iter().map(|b| b.span)).next();
2092         if !generic_args.parenthesized && !has_lifetimes {
2093             generic_args.args =
2094                 self.elided_path_lifetimes(path_span, expected_lifetimes)
2095                     .into_iter()
2096                     .map(|lt| GenericArg::Lifetime(lt))
2097                     .chain(generic_args.args.into_iter())
2098                 .collect();
2099             if expected_lifetimes > 0 && param_mode == ParamMode::Explicit {
2100                 let anon_lt_suggestion = vec!["'_"; expected_lifetimes].join(", ");
2101                 let no_ty_args = generic_args.args.len() == expected_lifetimes;
2102                 let no_bindings = generic_args.bindings.is_empty();
2103                 let (incl_angl_brckt, insertion_span, suggestion) = if no_ty_args && no_bindings {
2104                     // If there are no (non-implicit) generic args or associated-type
2105                     // bindings, our suggestion includes the angle brackets.
2106                     (true, path_span.shrink_to_hi(), format!("<{}>", anon_lt_suggestion))
2107                 } else {
2108                     // Otherwise—sorry, this is kind of gross—we need to infer the
2109                     // place to splice in the `'_, ` from the generics that do exist.
2110                     let first_generic_span = first_generic_span
2111                         .expect("already checked that type args or bindings exist");
2112                     (false, first_generic_span.shrink_to_lo(), format!("{}, ", anon_lt_suggestion))
2113                 };
2114                 match self.anonymous_lifetime_mode {
2115                     // In create-parameter mode we error here because we don't want to support
2116                     // deprecated impl elision in new features like impl elision and `async fn`,
2117                     // both of which work using the `CreateParameter` mode:
2118                     //
2119                     //     impl Foo for std::cell::Ref<u32> // note lack of '_
2120                     //     async fn foo(_: std::cell::Ref<u32>) { ... }
2121                     AnonymousLifetimeMode::CreateParameter => {
2122                         let mut err = struct_span_err!(
2123                             self.sess,
2124                             path_span,
2125                             E0726,
2126                             "implicit elided lifetime not allowed here"
2127                         );
2128                         crate::lint::builtin::add_elided_lifetime_in_path_suggestion(
2129                             &self.sess,
2130                             &mut err,
2131                             expected_lifetimes,
2132                             path_span,
2133                             incl_angl_brckt,
2134                             insertion_span,
2135                             suggestion,
2136                         );
2137                         err.emit();
2138                     }
2139                     AnonymousLifetimeMode::PassThrough |
2140                     AnonymousLifetimeMode::ReportError |
2141                     AnonymousLifetimeMode::Replace(_) => {
2142                         self.sess.buffer_lint_with_diagnostic(
2143                             ELIDED_LIFETIMES_IN_PATHS,
2144                             CRATE_NODE_ID,
2145                             path_span,
2146                             "hidden lifetime parameters in types are deprecated",
2147                             builtin::BuiltinLintDiagnostics::ElidedLifetimesInPaths(
2148                                 expected_lifetimes,
2149                                 path_span,
2150                                 incl_angl_brckt,
2151                                 insertion_span,
2152                                 suggestion,
2153                             )
2154                         );
2155                     }
2156                 }
2157             }
2158         }
2159
2160         let res = self.expect_full_res(segment.id);
2161         let id = if let Some(owner) = explicit_owner {
2162             self.lower_node_id_with_owner(segment.id, owner)
2163         } else {
2164             self.lower_node_id(segment.id)
2165         };
2166         debug!(
2167             "lower_path_segment: ident={:?} original-id={:?} new-id={:?}",
2168             segment.ident, segment.id, id,
2169         );
2170
2171         hir::PathSegment::new(
2172             segment.ident,
2173             Some(id),
2174             Some(self.lower_res(res)),
2175             generic_args,
2176             infer_types,
2177         )
2178     }
2179
2180     fn lower_angle_bracketed_parameter_data(
2181         &mut self,
2182         data: &AngleBracketedArgs,
2183         param_mode: ParamMode,
2184         mut itctx: ImplTraitContext<'_>,
2185     ) -> (hir::GenericArgs, bool) {
2186         let &AngleBracketedArgs { ref args, ref bindings, .. } = data;
2187         let has_types = args.iter().any(|arg| match arg {
2188             ast::GenericArg::Type(_) => true,
2189             _ => false,
2190         });
2191         (hir::GenericArgs {
2192             args: args.iter().map(|a| self.lower_generic_arg(a, itctx.reborrow())).collect(),
2193             bindings: bindings.iter().map(|b| self.lower_ty_binding(b, itctx.reborrow())).collect(),
2194             parenthesized: false,
2195         },
2196         !has_types && param_mode == ParamMode::Optional)
2197     }
2198
2199     fn lower_parenthesized_parameter_data(
2200         &mut self,
2201         data: &ParenthesizedArgs,
2202     ) -> (hir::GenericArgs, bool) {
2203         // Switch to `PassThrough` mode for anonymous lifetimes: this
2204         // means that we permit things like `&Ref<T>`, where `Ref` has
2205         // a hidden lifetime parameter. This is needed for backwards
2206         // compatibility, even in contexts like an impl header where
2207         // we generally don't permit such things (see #51008).
2208         self.with_anonymous_lifetime_mode(
2209             AnonymousLifetimeMode::PassThrough,
2210             |this| {
2211                 let &ParenthesizedArgs { ref inputs, ref output, span } = data;
2212                 let inputs = inputs
2213                     .iter()
2214                     .map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed()))
2215                     .collect();
2216                 let mk_tup = |this: &mut Self, tys, span| {
2217                     hir::Ty { node: hir::TyKind::Tup(tys), hir_id: this.next_id(), span }
2218                 };
2219                 (
2220                     hir::GenericArgs {
2221                         args: hir_vec![GenericArg::Type(mk_tup(this, inputs, span))],
2222                         bindings: hir_vec![
2223                             hir::TypeBinding {
2224                                 hir_id: this.next_id(),
2225                                 ident: Ident::with_empty_ctxt(FN_OUTPUT_NAME),
2226                                 ty: output
2227                                     .as_ref()
2228                                     .map(|ty| this.lower_ty(&ty, ImplTraitContext::disallowed()))
2229                                     .unwrap_or_else(|| P(mk_tup(this, hir::HirVec::new(), span))),
2230                                 span: output.as_ref().map_or(span, |ty| ty.span),
2231                             }
2232                         ],
2233                         parenthesized: true,
2234                     },
2235                     false,
2236                 )
2237             }
2238         )
2239     }
2240
2241     fn lower_local(&mut self, l: &Local) -> (hir::Local, SmallVec<[NodeId; 1]>) {
2242         let mut ids = SmallVec::<[NodeId; 1]>::new();
2243         if self.sess.features_untracked().impl_trait_in_bindings {
2244             if let Some(ref ty) = l.ty {
2245                 let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
2246                 visitor.visit_ty(ty);
2247             }
2248         }
2249         let parent_def_id = DefId::local(self.current_hir_id_owner.last().unwrap().0);
2250         (hir::Local {
2251             hir_id: self.lower_node_id(l.id),
2252             ty: l.ty
2253                 .as_ref()
2254                 .map(|t| self.lower_ty(t,
2255                     if self.sess.features_untracked().impl_trait_in_bindings {
2256                         ImplTraitContext::Existential(Some(parent_def_id))
2257                     } else {
2258                         ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
2259                     }
2260                 )),
2261             pat: self.lower_pat(&l.pat),
2262             init: l.init.as_ref().map(|e| P(self.lower_expr(e))),
2263             span: l.span,
2264             attrs: l.attrs.clone(),
2265             source: hir::LocalSource::Normal,
2266         }, ids)
2267     }
2268
2269     fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability {
2270         match m {
2271             Mutability::Mutable => hir::MutMutable,
2272             Mutability::Immutable => hir::MutImmutable,
2273         }
2274     }
2275
2276     fn lower_args(&mut self, decl: Option<&FnDecl>) -> HirVec<hir::Arg> {
2277         decl.map_or(hir_vec![], |decl| decl.inputs.iter().map(|x| self.lower_arg(x)).collect())
2278     }
2279
2280     fn lower_arg(&mut self, arg: &Arg) -> hir::Arg {
2281         hir::Arg {
2282             hir_id: self.lower_node_id(arg.id),
2283             pat: self.lower_pat(&arg.pat),
2284             source: hir::ArgSource::Normal,
2285         }
2286     }
2287
2288     fn lower_fn_args_to_names(&mut self, decl: &FnDecl) -> hir::HirVec<Ident> {
2289         decl.inputs
2290             .iter()
2291             .map(|arg| match arg.pat.node {
2292                 PatKind::Ident(_, ident, _) => ident,
2293                 _ => Ident::new(kw::Invalid, arg.pat.span),
2294             })
2295             .collect()
2296     }
2297
2298     // Lowers a function declaration.
2299     //
2300     // decl: the unlowered (ast) function declaration.
2301     // fn_def_id: if `Some`, impl Trait arguments are lowered into generic parameters on the
2302     //      given DefId, otherwise impl Trait is disallowed. Must be `Some` if
2303     //      make_ret_async is also `Some`.
2304     // impl_trait_return_allow: determines whether impl Trait can be used in return position.
2305     //      This guards against trait declarations and implementations where impl Trait is
2306     //      disallowed.
2307     // make_ret_async: if `Some`, converts `-> T` into `-> impl Future<Output = T>` in the
2308     //      return type. This is used for `async fn` declarations. The `NodeId` is the id of the
2309     //      return type impl Trait item.
2310     fn lower_fn_decl(
2311         &mut self,
2312         decl: &FnDecl,
2313         mut in_band_ty_params: Option<(DefId, &mut Vec<hir::GenericParam>)>,
2314         impl_trait_return_allow: bool,
2315         make_ret_async: Option<NodeId>,
2316     ) -> P<hir::FnDecl> {
2317         let lt_mode = if make_ret_async.is_some() {
2318             // In `async fn`, argument-position elided lifetimes
2319             // must be transformed into fresh generic parameters so that
2320             // they can be applied to the existential return type.
2321             AnonymousLifetimeMode::CreateParameter
2322         } else {
2323             self.anonymous_lifetime_mode
2324         };
2325
2326         // Remember how many lifetimes were already around so that we can
2327         // only look at the lifetime parameters introduced by the arguments.
2328         let lifetime_count_before_args = self.lifetimes_to_define.len();
2329         let inputs = self.with_anonymous_lifetime_mode(lt_mode, |this| {
2330             decl.inputs
2331                 .iter()
2332                 .map(|arg| {
2333                     if let Some((_, ibty)) = &mut in_band_ty_params {
2334                         this.lower_ty_direct(&arg.ty, ImplTraitContext::Universal(ibty))
2335                     } else {
2336                         this.lower_ty_direct(&arg.ty, ImplTraitContext::disallowed())
2337                     }
2338                 })
2339                 .collect::<HirVec<_>>()
2340         });
2341
2342         let output = if let Some(ret_id) = make_ret_async {
2343             // Calculate the `LtReplacement` to use for any return-position elided
2344             // lifetimes based on the elided lifetime parameters introduced in the args.
2345             let lt_replacement = get_elided_lt_replacement(
2346                 &self.lifetimes_to_define[lifetime_count_before_args..]
2347             );
2348             self.lower_async_fn_ret_ty(
2349                 &decl.output,
2350                 in_band_ty_params.expect("make_ret_async but no fn_def_id").0,
2351                 ret_id,
2352                 lt_replacement,
2353             )
2354         } else {
2355             match decl.output {
2356                 FunctionRetTy::Ty(ref ty) => match in_band_ty_params {
2357                     Some((def_id, _)) if impl_trait_return_allow => {
2358                         hir::Return(self.lower_ty(ty,
2359                             ImplTraitContext::Existential(Some(def_id))))
2360                     }
2361                     _ => {
2362                         hir::Return(self.lower_ty(ty, ImplTraitContext::disallowed()))
2363                     }
2364                 },
2365                 FunctionRetTy::Default(span) => hir::DefaultReturn(span),
2366             }
2367         };
2368
2369         P(hir::FnDecl {
2370             inputs,
2371             output,
2372             c_variadic: decl.c_variadic,
2373             implicit_self: decl.inputs.get(0).map_or(
2374                 hir::ImplicitSelfKind::None,
2375                 |arg| {
2376                     let is_mutable_pat = match arg.pat.node {
2377                         PatKind::Ident(BindingMode::ByValue(mt), _, _) |
2378                         PatKind::Ident(BindingMode::ByRef(mt), _, _) =>
2379                             mt == Mutability::Mutable,
2380                         _ => false,
2381                     };
2382
2383                     match arg.ty.node {
2384                         TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,
2385                         TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
2386                         // Given we are only considering `ImplicitSelf` types, we needn't consider
2387                         // the case where we have a mutable pattern to a reference as that would
2388                         // no longer be an `ImplicitSelf`.
2389                         TyKind::Rptr(_, ref mt) if mt.ty.node.is_implicit_self() &&
2390                             mt.mutbl == ast::Mutability::Mutable =>
2391                                 hir::ImplicitSelfKind::MutRef,
2392                         TyKind::Rptr(_, ref mt) if mt.ty.node.is_implicit_self() =>
2393                             hir::ImplicitSelfKind::ImmRef,
2394                         _ => hir::ImplicitSelfKind::None,
2395                     }
2396                 },
2397             ),
2398         })
2399     }
2400
2401     // Transform `-> T` for `async fn` into -> ExistTy { .. }
2402     // combined with the following definition of `ExistTy`:
2403     //
2404     // existential type ExistTy<generics_from_parent_fn>: Future<Output = T>;
2405     //
2406     // inputs: lowered types of arguments to the function. Used to collect lifetimes.
2407     // output: unlowered output type (`T` in `-> T`)
2408     // fn_def_id: DefId of the parent function. Used to create child impl trait definition.
2409     // exist_ty_node_id: NodeId of the existential type that should be created.
2410     // elided_lt_replacement: replacement for elided lifetimes in the return type
2411     fn lower_async_fn_ret_ty(
2412         &mut self,
2413         output: &FunctionRetTy,
2414         fn_def_id: DefId,
2415         exist_ty_node_id: NodeId,
2416         elided_lt_replacement: LtReplacement,
2417     ) -> hir::FunctionRetTy {
2418         let span = output.span();
2419
2420         let exist_ty_span = self.mark_span_with_reason(
2421             CompilerDesugaringKind::Async,
2422             span,
2423             None,
2424         );
2425
2426         let exist_ty_def_index = self
2427             .resolver
2428             .definitions()
2429             .opt_def_index(exist_ty_node_id)
2430             .unwrap();
2431
2432         self.allocate_hir_id_counter(exist_ty_node_id);
2433
2434         let (exist_ty_id, lifetime_params) = self.with_hir_id_owner(exist_ty_node_id, |this| {
2435             let future_bound = this.with_anonymous_lifetime_mode(
2436                 AnonymousLifetimeMode::Replace(elided_lt_replacement),
2437                 |this| this.lower_async_fn_output_type_to_future_bound(
2438                     output,
2439                     fn_def_id,
2440                     span,
2441                 ),
2442             );
2443
2444             // Calculate all the lifetimes that should be captured
2445             // by the existential type. This should include all in-scope
2446             // lifetime parameters, including those defined in-band.
2447             //
2448             // Note: this must be done after lowering the output type,
2449             // as the output type may introduce new in-band lifetimes.
2450             let lifetime_params: Vec<(Span, ParamName)> =
2451                 this.in_scope_lifetimes
2452                     .iter().cloned()
2453                     .map(|ident| (ident.span, ParamName::Plain(ident)))
2454                     .chain(this.lifetimes_to_define.iter().cloned())
2455                     .collect();
2456
2457             let generic_params =
2458                 lifetime_params
2459                     .iter().cloned()
2460                     .map(|(span, hir_name)| {
2461                         this.lifetime_to_generic_param(span, hir_name, exist_ty_def_index)
2462                     })
2463                     .collect();
2464
2465             let exist_ty_item = hir::ExistTy {
2466                 generics: hir::Generics {
2467                     params: generic_params,
2468                     where_clause: hir::WhereClause {
2469                         hir_id: this.next_id(),
2470                         predicates: hir_vec![],
2471                     },
2472                     span,
2473                 },
2474                 bounds: hir_vec![future_bound],
2475                 impl_trait_fn: Some(fn_def_id),
2476                 origin: hir::ExistTyOrigin::AsyncFn,
2477             };
2478
2479             trace!("exist ty from async fn def index: {:#?}", exist_ty_def_index);
2480             let exist_ty_id = this.generate_existential_type(
2481                 exist_ty_node_id,
2482                 exist_ty_item,
2483                 span,
2484                 exist_ty_span,
2485             );
2486
2487             (exist_ty_id, lifetime_params)
2488         });
2489
2490         let generic_args =
2491             lifetime_params
2492                 .iter().cloned()
2493                 .map(|(span, hir_name)| {
2494                     GenericArg::Lifetime(hir::Lifetime {
2495                         hir_id: self.next_id(),
2496                         span,
2497                         name: hir::LifetimeName::Param(hir_name),
2498                     })
2499                 })
2500                 .collect();
2501
2502         let exist_ty_ref = hir::TyKind::Def(hir::ItemId { id: exist_ty_id }, generic_args);
2503
2504         hir::FunctionRetTy::Return(P(hir::Ty {
2505             node: exist_ty_ref,
2506             span,
2507             hir_id: self.next_id(),
2508         }))
2509     }
2510
2511     /// Turns `-> T` into `Future<Output = T>`
2512     fn lower_async_fn_output_type_to_future_bound(
2513         &mut self,
2514         output: &FunctionRetTy,
2515         fn_def_id: DefId,
2516         span: Span,
2517     ) -> hir::GenericBound {
2518         // Compute the `T` in `Future<Output = T>` from the return type.
2519         let output_ty = match output {
2520             FunctionRetTy::Ty(ty) => {
2521                 self.lower_ty(ty, ImplTraitContext::Existential(Some(fn_def_id)))
2522             }
2523             FunctionRetTy::Default(ret_ty_span) => {
2524                 P(hir::Ty {
2525                     hir_id: self.next_id(),
2526                     node: hir::TyKind::Tup(hir_vec![]),
2527                     span: *ret_ty_span,
2528                 })
2529             }
2530         };
2531
2532         // "<Output = T>"
2533         let future_params = P(hir::GenericArgs {
2534             args: hir_vec![],
2535             bindings: hir_vec![hir::TypeBinding {
2536                 ident: Ident::with_empty_ctxt(FN_OUTPUT_NAME),
2537                 ty: output_ty,
2538                 hir_id: self.next_id(),
2539                 span,
2540             }],
2541             parenthesized: false,
2542         });
2543
2544         // ::std::future::Future<future_params>
2545         let future_path =
2546             self.std_path(span, &[sym::future, sym::Future], Some(future_params), false);
2547
2548         hir::GenericBound::Trait(
2549             hir::PolyTraitRef {
2550                 trait_ref: hir::TraitRef {
2551                     path: future_path,
2552                     hir_ref_id: self.next_id(),
2553                 },
2554                 bound_generic_params: hir_vec![],
2555                 span,
2556             },
2557             hir::TraitBoundModifier::None,
2558         )
2559     }
2560
2561     fn lower_param_bound(
2562         &mut self,
2563         tpb: &GenericBound,
2564         itctx: ImplTraitContext<'_>,
2565     ) -> hir::GenericBound {
2566         match *tpb {
2567             GenericBound::Trait(ref ty, modifier) => {
2568                 hir::GenericBound::Trait(
2569                     self.lower_poly_trait_ref(ty, itctx),
2570                     self.lower_trait_bound_modifier(modifier),
2571                 )
2572             }
2573             GenericBound::Outlives(ref lifetime) => {
2574                 hir::GenericBound::Outlives(self.lower_lifetime(lifetime))
2575             }
2576         }
2577     }
2578
2579     fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
2580         let span = l.ident.span;
2581         match l.ident {
2582             ident if ident.name == kw::StaticLifetime =>
2583                 self.new_named_lifetime(l.id, span, hir::LifetimeName::Static),
2584             ident if ident.name == kw::UnderscoreLifetime =>
2585                 match self.anonymous_lifetime_mode {
2586                     AnonymousLifetimeMode::CreateParameter => {
2587                         let fresh_name = self.collect_fresh_in_band_lifetime(span);
2588                         self.new_named_lifetime(l.id, span, hir::LifetimeName::Param(fresh_name))
2589                     }
2590
2591                     AnonymousLifetimeMode::PassThrough => {
2592                         self.new_named_lifetime(l.id, span, hir::LifetimeName::Underscore)
2593                     }
2594
2595                     AnonymousLifetimeMode::ReportError => self.new_error_lifetime(Some(l.id), span),
2596
2597                     AnonymousLifetimeMode::Replace(replacement) => {
2598                         let hir_id = self.lower_node_id(l.id);
2599                         self.replace_elided_lifetime(hir_id, span, replacement)
2600                     }
2601                 },
2602             ident => {
2603                 self.maybe_collect_in_band_lifetime(ident);
2604                 let param_name = ParamName::Plain(ident);
2605                 self.new_named_lifetime(l.id, span, hir::LifetimeName::Param(param_name))
2606             }
2607         }
2608     }
2609
2610     fn new_named_lifetime(
2611         &mut self,
2612         id: NodeId,
2613         span: Span,
2614         name: hir::LifetimeName,
2615     ) -> hir::Lifetime {
2616         hir::Lifetime {
2617             hir_id: self.lower_node_id(id),
2618             span,
2619             name: name,
2620         }
2621     }
2622
2623     /// Replace a return-position elided lifetime with the elided lifetime
2624     /// from the arguments.
2625     fn replace_elided_lifetime(
2626         &mut self,
2627         hir_id: hir::HirId,
2628         span: Span,
2629         replacement: LtReplacement,
2630     ) -> hir::Lifetime {
2631         let multiple_or_none = match replacement {
2632             LtReplacement::Some(name) => {
2633                 return hir::Lifetime {
2634                     hir_id,
2635                     span,
2636                     name: hir::LifetimeName::Param(name),
2637                 };
2638             }
2639             LtReplacement::MultipleLifetimes => "multiple",
2640             LtReplacement::NoLifetimes => "none",
2641         };
2642
2643         let mut err = crate::middle::resolve_lifetime::report_missing_lifetime_specifiers(
2644             self.sess,
2645             span,
2646             1,
2647         );
2648         err.note(&format!(
2649             "return-position elided lifetimes require exactly one \
2650              input-position elided lifetime, found {}.", multiple_or_none));
2651         err.emit();
2652
2653         hir::Lifetime { hir_id, span, name: hir::LifetimeName::Error }
2654     }
2655
2656     fn lower_generic_params(
2657         &mut self,
2658         params: &[GenericParam],
2659         add_bounds: &NodeMap<Vec<GenericBound>>,
2660         mut itctx: ImplTraitContext<'_>,
2661     ) -> hir::HirVec<hir::GenericParam> {
2662         params.iter().map(|param| {
2663             self.lower_generic_param(param, add_bounds, itctx.reborrow())
2664         }).collect()
2665     }
2666
2667     fn lower_generic_param(&mut self,
2668                            param: &GenericParam,
2669                            add_bounds: &NodeMap<Vec<GenericBound>>,
2670                            mut itctx: ImplTraitContext<'_>)
2671                            -> hir::GenericParam {
2672         let mut bounds = self.with_anonymous_lifetime_mode(
2673             AnonymousLifetimeMode::ReportError,
2674             |this| this.lower_param_bounds(&param.bounds, itctx.reborrow()),
2675         );
2676
2677         let (name, kind) = match param.kind {
2678             GenericParamKind::Lifetime => {
2679                 let was_collecting_in_band = self.is_collecting_in_band_lifetimes;
2680                 self.is_collecting_in_band_lifetimes = false;
2681
2682                 let lt = self.with_anonymous_lifetime_mode(
2683                     AnonymousLifetimeMode::ReportError,
2684                     |this| this.lower_lifetime(&Lifetime { id: param.id, ident: param.ident }),
2685                 );
2686                 let param_name = match lt.name {
2687                     hir::LifetimeName::Param(param_name) => param_name,
2688                     hir::LifetimeName::Implicit
2689                         | hir::LifetimeName::Underscore
2690                         | hir::LifetimeName::Static => hir::ParamName::Plain(lt.name.ident()),
2691                     hir::LifetimeName::Error => ParamName::Error,
2692                 };
2693
2694                 let kind = hir::GenericParamKind::Lifetime {
2695                     kind: hir::LifetimeParamKind::Explicit
2696                 };
2697
2698                 self.is_collecting_in_band_lifetimes = was_collecting_in_band;
2699
2700                 (param_name, kind)
2701             }
2702             GenericParamKind::Type { ref default, .. } => {
2703                 // Don't expose `Self` (recovered "keyword used as ident" parse error).
2704                 // `rustc::ty` expects `Self` to be only used for a trait's `Self`.
2705                 // Instead, use `gensym("Self")` to create a distinct name that looks the same.
2706                 let ident = if param.ident.name == kw::SelfUpper {
2707                     param.ident.gensym()
2708                 } else {
2709                     param.ident
2710                 };
2711
2712                 let add_bounds = add_bounds.get(&param.id).map_or(&[][..], |x| &x);
2713                 if !add_bounds.is_empty() {
2714                     let params = self.lower_param_bounds(add_bounds, itctx.reborrow()).into_iter();
2715                     bounds = bounds.into_iter()
2716                                    .chain(params)
2717                                    .collect();
2718                 }
2719
2720                 let kind = hir::GenericParamKind::Type {
2721                     default: default.as_ref().map(|x| {
2722                         self.lower_ty(x, ImplTraitContext::disallowed())
2723                     }),
2724                     synthetic: param.attrs.iter()
2725                                           .filter(|attr| attr.check_name(sym::rustc_synthetic))
2726                                           .map(|_| hir::SyntheticTyParamKind::ImplTrait)
2727                                           .next(),
2728                 };
2729
2730                 (hir::ParamName::Plain(ident), kind)
2731             }
2732             GenericParamKind::Const { ref ty } => {
2733                 (hir::ParamName::Plain(param.ident), hir::GenericParamKind::Const {
2734                     ty: self.lower_ty(&ty, ImplTraitContext::disallowed()),
2735                 })
2736             }
2737         };
2738
2739         hir::GenericParam {
2740             hir_id: self.lower_node_id(param.id),
2741             name,
2742             span: param.ident.span,
2743             pure_wrt_drop: attr::contains_name(&param.attrs, sym::may_dangle),
2744             attrs: self.lower_attrs(&param.attrs),
2745             bounds,
2746             kind,
2747         }
2748     }
2749
2750     fn lower_generics(
2751         &mut self,
2752         generics: &Generics,
2753         itctx: ImplTraitContext<'_>)
2754         -> hir::Generics
2755     {
2756         // Collect `?Trait` bounds in where clause and move them to parameter definitions.
2757         // FIXME: this could probably be done with less rightward drift. Also looks like two control
2758         //        paths where report_error is called are also the only paths that advance to after
2759         //        the match statement, so the error reporting could probably just be moved there.
2760         let mut add_bounds: NodeMap<Vec<_>> = Default::default();
2761         for pred in &generics.where_clause.predicates {
2762             if let WherePredicate::BoundPredicate(ref bound_pred) = *pred {
2763                 'next_bound: for bound in &bound_pred.bounds {
2764                     if let GenericBound::Trait(_, TraitBoundModifier::Maybe) = *bound {
2765                         let report_error = |this: &mut Self| {
2766                             this.diagnostic().span_err(
2767                                 bound_pred.bounded_ty.span,
2768                                 "`?Trait` bounds are only permitted at the \
2769                                  point where a type parameter is declared",
2770                             );
2771                         };
2772                         // Check if the where clause type is a plain type parameter.
2773                         match bound_pred.bounded_ty.node {
2774                             TyKind::Path(None, ref path)
2775                                 if path.segments.len() == 1
2776                                     && bound_pred.bound_generic_params.is_empty() =>
2777                             {
2778                                 if let Some(Res::Def(DefKind::TyParam, def_id)) = self.resolver
2779                                     .get_partial_res(bound_pred.bounded_ty.id)
2780                                     .map(|d| d.base_res())
2781                                 {
2782                                     if let Some(node_id) =
2783                                         self.resolver.definitions().as_local_node_id(def_id)
2784                                     {
2785                                         for param in &generics.params {
2786                                             match param.kind {
2787                                                 GenericParamKind::Type { .. } => {
2788                                                     if node_id == param.id {
2789                                                         add_bounds.entry(param.id)
2790                                                             .or_default()
2791                                                             .push(bound.clone());
2792                                                         continue 'next_bound;
2793                                                     }
2794                                                 }
2795                                                 _ => {}
2796                                             }
2797                                         }
2798                                     }
2799                                 }
2800                                 report_error(self)
2801                             }
2802                             _ => report_error(self),
2803                         }
2804                     }
2805                 }
2806             }
2807         }
2808
2809         hir::Generics {
2810             params: self.lower_generic_params(&generics.params, &add_bounds, itctx),
2811             where_clause: self.lower_where_clause(&generics.where_clause),
2812             span: generics.span,
2813         }
2814     }
2815
2816     fn lower_where_clause(&mut self, wc: &WhereClause) -> hir::WhereClause {
2817         self.with_anonymous_lifetime_mode(
2818             AnonymousLifetimeMode::ReportError,
2819             |this| {
2820                 hir::WhereClause {
2821                     hir_id: this.lower_node_id(wc.id),
2822                     predicates: wc.predicates
2823                         .iter()
2824                         .map(|predicate| this.lower_where_predicate(predicate))
2825                         .collect(),
2826                 }
2827             },
2828         )
2829     }
2830
2831     fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate {
2832         match *pred {
2833             WherePredicate::BoundPredicate(WhereBoundPredicate {
2834                 ref bound_generic_params,
2835                 ref bounded_ty,
2836                 ref bounds,
2837                 span,
2838             }) => {
2839                 self.with_in_scope_lifetime_defs(
2840                     &bound_generic_params,
2841                     |this| {
2842                         hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
2843                             bound_generic_params: this.lower_generic_params(
2844                                 bound_generic_params,
2845                                 &NodeMap::default(),
2846                                 ImplTraitContext::disallowed(),
2847                             ),
2848                             bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::disallowed()),
2849                             bounds: bounds
2850                                 .iter()
2851                                 .filter_map(|bound| match *bound {
2852                                     // Ignore `?Trait` bounds.
2853                                     // They were copied into type parameters already.
2854                                     GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
2855                                     _ => Some(this.lower_param_bound(
2856                                         bound,
2857                                         ImplTraitContext::disallowed(),
2858                                     )),
2859                                 })
2860                                 .collect(),
2861                             span,
2862                         })
2863                     },
2864                 )
2865             }
2866             WherePredicate::RegionPredicate(WhereRegionPredicate {
2867                 ref lifetime,
2868                 ref bounds,
2869                 span,
2870             }) => hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
2871                 span,
2872                 lifetime: self.lower_lifetime(lifetime),
2873                 bounds: self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
2874             }),
2875             WherePredicate::EqPredicate(WhereEqPredicate {
2876                 id,
2877                 ref lhs_ty,
2878                 ref rhs_ty,
2879                 span,
2880             }) => {
2881                 hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
2882                     hir_id: self.lower_node_id(id),
2883                     lhs_ty: self.lower_ty(lhs_ty, ImplTraitContext::disallowed()),
2884                     rhs_ty: self.lower_ty(rhs_ty, ImplTraitContext::disallowed()),
2885                     span,
2886                 })
2887             },
2888         }
2889     }
2890
2891     fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData {
2892         match *vdata {
2893             VariantData::Struct(ref fields, recovered) => hir::VariantData::Struct(
2894                 fields.iter().enumerate().map(|f| self.lower_struct_field(f)).collect(),
2895                 recovered,
2896             ),
2897             VariantData::Tuple(ref fields, id) => {
2898                 hir::VariantData::Tuple(
2899                     fields
2900                         .iter()
2901                         .enumerate()
2902                         .map(|f| self.lower_struct_field(f))
2903                         .collect(),
2904                     self.lower_node_id(id),
2905                 )
2906             },
2907             VariantData::Unit(id) => {
2908                 hir::VariantData::Unit(self.lower_node_id(id))
2909             },
2910         }
2911     }
2912
2913     fn lower_trait_ref(&mut self, p: &TraitRef, itctx: ImplTraitContext<'_>) -> hir::TraitRef {
2914         let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
2915             hir::QPath::Resolved(None, path) => path.and_then(|path| path),
2916             qpath => bug!("lower_trait_ref: unexpected QPath `{:?}`", qpath),
2917         };
2918         hir::TraitRef {
2919             path,
2920             hir_ref_id: self.lower_node_id(p.ref_id),
2921         }
2922     }
2923
2924     fn lower_poly_trait_ref(
2925         &mut self,
2926         p: &PolyTraitRef,
2927         mut itctx: ImplTraitContext<'_>,
2928     ) -> hir::PolyTraitRef {
2929         let bound_generic_params = self.lower_generic_params(
2930             &p.bound_generic_params,
2931             &NodeMap::default(),
2932             itctx.reborrow(),
2933         );
2934         let trait_ref = self.with_parent_impl_lifetime_defs(
2935             &bound_generic_params,
2936             |this| this.lower_trait_ref(&p.trait_ref, itctx),
2937         );
2938
2939         hir::PolyTraitRef {
2940             bound_generic_params,
2941             trait_ref,
2942             span: p.span,
2943         }
2944     }
2945
2946     fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::StructField {
2947         hir::StructField {
2948             span: f.span,
2949             hir_id: self.lower_node_id(f.id),
2950             ident: match f.ident {
2951                 Some(ident) => ident,
2952                 // FIXME(jseyfried): positional field hygiene
2953                 None => Ident::new(sym::integer(index), f.span),
2954             },
2955             vis: self.lower_visibility(&f.vis, None),
2956             ty: self.lower_ty(&f.ty, ImplTraitContext::disallowed()),
2957             attrs: self.lower_attrs(&f.attrs),
2958         }
2959     }
2960
2961     fn lower_field(&mut self, f: &Field) -> hir::Field {
2962         hir::Field {
2963             hir_id: self.next_id(),
2964             ident: f.ident,
2965             expr: P(self.lower_expr(&f.expr)),
2966             span: f.span,
2967             is_shorthand: f.is_shorthand,
2968         }
2969     }
2970
2971     fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext<'_>) -> hir::MutTy {
2972         hir::MutTy {
2973             ty: self.lower_ty(&mt.ty, itctx),
2974             mutbl: self.lower_mutability(mt.mutbl),
2975         }
2976     }
2977
2978     fn lower_param_bounds(&mut self, bounds: &[GenericBound], mut itctx: ImplTraitContext<'_>)
2979         -> hir::GenericBounds {
2980         bounds.iter().map(|bound| self.lower_param_bound(bound, itctx.reborrow())).collect()
2981     }
2982
2983     fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> P<hir::Block> {
2984         let mut expr = None;
2985
2986         let mut stmts = vec![];
2987
2988         for (index, stmt) in b.stmts.iter().enumerate() {
2989             if index == b.stmts.len() - 1 {
2990                 if let StmtKind::Expr(ref e) = stmt.node {
2991                     expr = Some(P(self.lower_expr(e)));
2992                 } else {
2993                     stmts.extend(self.lower_stmt(stmt));
2994                 }
2995             } else {
2996                 stmts.extend(self.lower_stmt(stmt));
2997             }
2998         }
2999
3000         P(hir::Block {
3001             hir_id: self.lower_node_id(b.id),
3002             stmts: stmts.into(),
3003             expr,
3004             rules: self.lower_block_check_mode(&b.rules),
3005             span: b.span,
3006             targeted_by_break,
3007         })
3008     }
3009
3010     fn lower_async_body(
3011         &mut self,
3012         decl: &FnDecl,
3013         asyncness: IsAsync,
3014         body: &Block,
3015     ) -> hir::BodyId {
3016         self.lower_body(Some(&decl), |this| {
3017             if let IsAsync::Async { closure_id, .. } = asyncness {
3018                 let async_expr = this.make_async_expr(
3019                     CaptureBy::Value, closure_id, None, body.span,
3020                     |this| {
3021                         let body = this.lower_block(&body, false);
3022                         this.expr_block(body, ThinVec::new())
3023                     });
3024                 this.expr(body.span, async_expr, ThinVec::new())
3025             } else {
3026                 let body = this.lower_block(body, false);
3027                 this.expr_block(body, ThinVec::new())
3028             }
3029         })
3030     }
3031
3032     fn lower_item_kind(
3033         &mut self,
3034         id: NodeId,
3035         ident: &mut Ident,
3036         attrs: &hir::HirVec<Attribute>,
3037         vis: &mut hir::Visibility,
3038         i: &ItemKind,
3039     ) -> hir::ItemKind {
3040         match *i {
3041             ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(orig_name),
3042             ItemKind::Use(ref use_tree) => {
3043                 // Start with an empty prefix
3044                 let prefix = Path {
3045                     segments: vec![],
3046                     span: use_tree.span,
3047                 };
3048
3049                 self.lower_use_tree(use_tree, &prefix, id, vis, ident, attrs)
3050             }
3051             ItemKind::Static(ref t, m, ref e) => {
3052                 let value = self.lower_body(None, |this| this.lower_expr(e));
3053                 hir::ItemKind::Static(
3054                     self.lower_ty(
3055                         t,
3056                         if self.sess.features_untracked().impl_trait_in_bindings {
3057                             ImplTraitContext::Existential(None)
3058                         } else {
3059                             ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
3060                         }
3061                     ),
3062                     self.lower_mutability(m),
3063                     value,
3064                 )
3065             }
3066             ItemKind::Const(ref t, ref e) => {
3067                 let value = self.lower_body(None, |this| this.lower_expr(e));
3068                 hir::ItemKind::Const(
3069                     self.lower_ty(
3070                         t,
3071                         if self.sess.features_untracked().impl_trait_in_bindings {
3072                             ImplTraitContext::Existential(None)
3073                         } else {
3074                             ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
3075                         }
3076                     ),
3077                     value
3078                 )
3079             }
3080             ItemKind::Fn(ref decl, header, ref generics, ref body) => {
3081                 let fn_def_id = self.resolver.definitions().local_def_id(id);
3082                 self.with_new_scopes(|this| {
3083                     // Note: we don't need to change the return type from `T` to
3084                     // `impl Future<Output = T>` here because lower_body
3085                     // only cares about the input argument patterns in the function
3086                     // declaration (decl), not the return types.
3087                     let body_id = this.lower_async_body(decl, header.asyncness.node, body);
3088                     let (generics, fn_decl) = this.add_in_band_defs(
3089                         generics,
3090                         fn_def_id,
3091                         AnonymousLifetimeMode::PassThrough,
3092                         |this, idty| this.lower_fn_decl(
3093                             decl,
3094                             Some((fn_def_id, idty)),
3095                             true,
3096                             header.asyncness.node.opt_return_id()
3097                         ),
3098                     );
3099                     this.current_item = Some(ident.span);
3100
3101                     hir::ItemKind::Fn(
3102                         fn_decl,
3103                         this.lower_fn_header(header),
3104                         generics,
3105                         body_id,
3106                     )
3107                 })
3108             }
3109             ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
3110             ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)),
3111             ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)),
3112             ItemKind::Ty(ref t, ref generics) => hir::ItemKind::Ty(
3113                 self.lower_ty(t, ImplTraitContext::disallowed()),
3114                 self.lower_generics(generics, ImplTraitContext::disallowed()),
3115             ),
3116             ItemKind::Existential(ref b, ref generics) => hir::ItemKind::Existential(hir::ExistTy {
3117                 generics: self.lower_generics(generics, ImplTraitContext::disallowed()),
3118                 bounds: self.lower_param_bounds(b, ImplTraitContext::disallowed()),
3119                 impl_trait_fn: None,
3120                 origin: hir::ExistTyOrigin::ExistentialType,
3121             }),
3122             ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemKind::Enum(
3123                 hir::EnumDef {
3124                     variants: enum_definition
3125                         .variants
3126                         .iter()
3127                         .map(|x| self.lower_variant(x))
3128                         .collect(),
3129                 },
3130                 self.lower_generics(generics, ImplTraitContext::disallowed()),
3131             ),
3132             ItemKind::Struct(ref struct_def, ref generics) => {
3133                 let struct_def = self.lower_variant_data(struct_def);
3134                 hir::ItemKind::Struct(
3135                     struct_def,
3136                     self.lower_generics(generics, ImplTraitContext::disallowed()),
3137                 )
3138             }
3139             ItemKind::Union(ref vdata, ref generics) => {
3140                 let vdata = self.lower_variant_data(vdata);
3141                 hir::ItemKind::Union(
3142                     vdata,
3143                     self.lower_generics(generics, ImplTraitContext::disallowed()),
3144                 )
3145             }
3146             ItemKind::Impl(
3147                 unsafety,
3148                 polarity,
3149                 defaultness,
3150                 ref ast_generics,
3151                 ref trait_ref,
3152                 ref ty,
3153                 ref impl_items,
3154             ) => {
3155                 let def_id = self.resolver.definitions().local_def_id(id);
3156
3157                 // Lower the "impl header" first. This ordering is important
3158                 // for in-band lifetimes! Consider `'a` here:
3159                 //
3160                 //     impl Foo<'a> for u32 {
3161                 //         fn method(&'a self) { .. }
3162                 //     }
3163                 //
3164                 // Because we start by lowering the `Foo<'a> for u32`
3165                 // part, we will add `'a` to the list of generics on
3166                 // the impl. When we then encounter it later in the
3167                 // method, it will not be considered an in-band
3168                 // lifetime to be added, but rather a reference to a
3169                 // parent lifetime.
3170                 let lowered_trait_impl_id = self.lower_node_id(id);
3171                 let (generics, (trait_ref, lowered_ty)) = self.add_in_band_defs(
3172                     ast_generics,
3173                     def_id,
3174                     AnonymousLifetimeMode::CreateParameter,
3175                     |this, _| {
3176                         let trait_ref = trait_ref.as_ref().map(|trait_ref| {
3177                             this.lower_trait_ref(trait_ref, ImplTraitContext::disallowed())
3178                         });
3179
3180                         if let Some(ref trait_ref) = trait_ref {
3181                             if let Res::Def(DefKind::Trait, def_id) = trait_ref.path.res {
3182                                 this.trait_impls.entry(def_id).or_default().push(
3183                                     lowered_trait_impl_id);
3184                             }
3185                         }
3186
3187                         let lowered_ty = this.lower_ty(ty, ImplTraitContext::disallowed());
3188
3189                         (trait_ref, lowered_ty)
3190                     },
3191                 );
3192
3193                 let new_impl_items = self.with_in_scope_lifetime_defs(
3194                     &ast_generics.params,
3195                     |this| {
3196                         impl_items
3197                             .iter()
3198                             .map(|item| this.lower_impl_item_ref(item))
3199                             .collect()
3200                     },
3201                 );
3202
3203                 hir::ItemKind::Impl(
3204                     self.lower_unsafety(unsafety),
3205                     self.lower_impl_polarity(polarity),
3206                     self.lower_defaultness(defaultness, true /* [1] */),
3207                     generics,
3208                     trait_ref,
3209                     lowered_ty,
3210                     new_impl_items,
3211                 )
3212             }
3213             ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => {
3214                 let bounds = self.lower_param_bounds(bounds, ImplTraitContext::disallowed());
3215                 let items = items
3216                     .iter()
3217                     .map(|item| self.lower_trait_item_ref(item))
3218                     .collect();
3219                 hir::ItemKind::Trait(
3220                     self.lower_is_auto(is_auto),
3221                     self.lower_unsafety(unsafety),
3222                     self.lower_generics(generics, ImplTraitContext::disallowed()),
3223                     bounds,
3224                     items,
3225                 )
3226             }
3227             ItemKind::TraitAlias(ref generics, ref bounds) => hir::ItemKind::TraitAlias(
3228                 self.lower_generics(generics, ImplTraitContext::disallowed()),
3229                 self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
3230             ),
3231             ItemKind::MacroDef(..) | ItemKind::Mac(..) => panic!("Shouldn't still be around"),
3232         }
3233
3234         // [1] `defaultness.has_value()` is never called for an `impl`, always `true` in order to
3235         //     not cause an assertion failure inside the `lower_defaultness` function.
3236     }
3237
3238     fn lower_use_tree(
3239         &mut self,
3240         tree: &UseTree,
3241         prefix: &Path,
3242         id: NodeId,
3243         vis: &mut hir::Visibility,
3244         ident: &mut Ident,
3245         attrs: &hir::HirVec<Attribute>,
3246     ) -> hir::ItemKind {
3247         debug!("lower_use_tree(tree={:?})", tree);
3248         debug!("lower_use_tree: vis = {:?}", vis);
3249
3250         let path = &tree.prefix;
3251         let segments = prefix
3252             .segments
3253             .iter()
3254             .chain(path.segments.iter())
3255             .cloned()
3256             .collect();
3257
3258         match tree.kind {
3259             UseTreeKind::Simple(rename, id1, id2) => {
3260                 *ident = tree.ident();
3261
3262                 // First, apply the prefix to the path.
3263                 let mut path = Path {
3264                     segments,
3265                     span: path.span,
3266                 };
3267
3268                 // Correctly resolve `self` imports.
3269                 if path.segments.len() > 1
3270                     && path.segments.last().unwrap().ident.name == kw::SelfLower
3271                 {
3272                     let _ = path.segments.pop();
3273                     if rename.is_none() {
3274                         *ident = path.segments.last().unwrap().ident;
3275                     }
3276                 }
3277
3278                 let mut resolutions = self.expect_full_res_from_use(id);
3279                 // We want to return *something* from this function, so hold onto the first item
3280                 // for later.
3281                 let ret_res = self.lower_res(resolutions.next().unwrap_or(Res::Err));
3282
3283                 // Here, we are looping over namespaces, if they exist for the definition
3284                 // being imported. We only handle type and value namespaces because we
3285                 // won't be dealing with macros in the rest of the compiler.
3286                 // Essentially a single `use` which imports two names is desugared into
3287                 // two imports.
3288                 for (res, &new_node_id) in resolutions.zip([id1, id2].iter()) {
3289                     let vis = vis.clone();
3290                     let ident = ident.clone();
3291                     let mut path = path.clone();
3292                     for seg in &mut path.segments {
3293                         seg.id = self.sess.next_node_id();
3294                     }
3295                     let span = path.span;
3296
3297                     self.with_hir_id_owner(new_node_id, |this| {
3298                         let new_id = this.lower_node_id(new_node_id);
3299                         let res = this.lower_res(res);
3300                         let path =
3301                             this.lower_path_extra(res, &path, ParamMode::Explicit, None);
3302                         let item = hir::ItemKind::Use(P(path), hir::UseKind::Single);
3303                         let vis_kind = match vis.node {
3304                             hir::VisibilityKind::Public => hir::VisibilityKind::Public,
3305                             hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
3306                             hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
3307                             hir::VisibilityKind::Restricted { ref path, hir_id: _ } => {
3308                                 let path = this.renumber_segment_ids(path);
3309                                 hir::VisibilityKind::Restricted {
3310                                     path,
3311                                     hir_id: this.next_id(),
3312                                 }
3313                             }
3314                         };
3315                         let vis = respan(vis.span, vis_kind);
3316
3317                         this.insert_item(
3318                             hir::Item {
3319                                 hir_id: new_id,
3320                                 ident,
3321                                 attrs: attrs.clone(),
3322                                 node: item,
3323                                 vis,
3324                                 span,
3325                             },
3326                         );
3327                     });
3328                 }
3329
3330                 let path =
3331                     P(self.lower_path_extra(ret_res, &path, ParamMode::Explicit, None));
3332                 hir::ItemKind::Use(path, hir::UseKind::Single)
3333             }
3334             UseTreeKind::Glob => {
3335                 let path = P(self.lower_path(
3336                     id,
3337                     &Path {
3338                         segments,
3339                         span: path.span,
3340                     },
3341                     ParamMode::Explicit,
3342                 ));
3343                 hir::ItemKind::Use(path, hir::UseKind::Glob)
3344             }
3345             UseTreeKind::Nested(ref trees) => {
3346                 // Nested imports are desugared into simple imports.
3347                 // So, if we start with
3348                 //
3349                 // ```
3350                 // pub(x) use foo::{a, b};
3351                 // ```
3352                 //
3353                 // we will create three items:
3354                 //
3355                 // ```
3356                 // pub(x) use foo::a;
3357                 // pub(x) use foo::b;
3358                 // pub(x) use foo::{}; // <-- this is called the `ListStem`
3359                 // ```
3360                 //
3361                 // The first two are produced by recursively invoking
3362                 // `lower_use_tree` (and indeed there may be things
3363                 // like `use foo::{a::{b, c}}` and so forth).  They
3364                 // wind up being directly added to
3365                 // `self.items`. However, the structure of this
3366                 // function also requires us to return one item, and
3367                 // for that we return the `{}` import (called the
3368                 // `ListStem`).
3369
3370                 let prefix = Path {
3371                     segments,
3372                     span: prefix.span.to(path.span),
3373                 };
3374
3375                 // Add all the nested `PathListItem`s to the HIR.
3376                 for &(ref use_tree, id) in trees {
3377                     let new_hir_id = self.lower_node_id(id);
3378
3379                     let mut vis = vis.clone();
3380                     let mut ident = ident.clone();
3381                     let mut prefix = prefix.clone();
3382
3383                     // Give the segments new node-ids since they are being cloned.
3384                     for seg in &mut prefix.segments {
3385                         seg.id = self.sess.next_node_id();
3386                     }
3387
3388                     // Each `use` import is an item and thus are owners of the
3389                     // names in the path. Up to this point the nested import is
3390                     // the current owner, since we want each desugared import to
3391                     // own its own names, we have to adjust the owner before
3392                     // lowering the rest of the import.
3393                     self.with_hir_id_owner(id, |this| {
3394                         let item = this.lower_use_tree(use_tree,
3395                                                        &prefix,
3396                                                        id,
3397                                                        &mut vis,
3398                                                        &mut ident,
3399                                                        attrs);
3400
3401                         let vis_kind = match vis.node {
3402                             hir::VisibilityKind::Public => hir::VisibilityKind::Public,
3403                             hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
3404                             hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
3405                             hir::VisibilityKind::Restricted { ref path, hir_id: _ } => {
3406                                 let path = this.renumber_segment_ids(path);
3407                                 hir::VisibilityKind::Restricted {
3408                                     path: path,
3409                                     hir_id: this.next_id(),
3410                                 }
3411                             }
3412                         };
3413                         let vis = respan(vis.span, vis_kind);
3414
3415                         this.insert_item(
3416                             hir::Item {
3417                                 hir_id: new_hir_id,
3418                                 ident,
3419                                 attrs: attrs.clone(),
3420                                 node: item,
3421                                 vis,
3422                                 span: use_tree.span,
3423                             },
3424                         );
3425                     });
3426                 }
3427
3428                 // Subtle and a bit hacky: we lower the privacy level
3429                 // of the list stem to "private" most of the time, but
3430                 // not for "restricted" paths. The key thing is that
3431                 // we don't want it to stay as `pub` (with no caveats)
3432                 // because that affects rustdoc and also the lints
3433                 // about `pub` items. But we can't *always* make it
3434                 // private -- particularly not for restricted paths --
3435                 // because it contains node-ids that would then be
3436                 // unused, failing the check that HirIds are "densely
3437                 // assigned".
3438                 match vis.node {
3439                     hir::VisibilityKind::Public |
3440                     hir::VisibilityKind::Crate(_) |
3441                     hir::VisibilityKind::Inherited => {
3442                         *vis = respan(prefix.span.shrink_to_lo(), hir::VisibilityKind::Inherited);
3443                     }
3444                     hir::VisibilityKind::Restricted { .. } => {
3445                         // Do nothing here, as described in the comment on the match.
3446                     }
3447                 }
3448
3449                 let res = self.expect_full_res_from_use(id).next().unwrap_or(Res::Err);
3450                 let res = self.lower_res(res);
3451                 let path = P(self.lower_path_extra(res, &prefix, ParamMode::Explicit, None));
3452                 hir::ItemKind::Use(path, hir::UseKind::ListStem)
3453             }
3454         }
3455     }
3456
3457     /// Paths like the visibility path in `pub(super) use foo::{bar, baz}` are repeated
3458     /// many times in the HIR tree; for each occurrence, we need to assign distinct
3459     /// `NodeId`s. (See, e.g., #56128.)
3460     fn renumber_segment_ids(&mut self, path: &P<hir::Path>) -> P<hir::Path> {
3461         debug!("renumber_segment_ids(path = {:?})", path);
3462         let mut path = path.clone();
3463         for seg in path.segments.iter_mut() {
3464             if seg.hir_id.is_some() {
3465                 seg.hir_id = Some(self.next_id());
3466             }
3467         }
3468         path
3469     }
3470
3471     fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
3472         let trait_item_def_id = self.resolver.definitions().local_def_id(i.id);
3473
3474         let (generics, node) = match i.node {
3475             TraitItemKind::Const(ref ty, ref default) => (
3476                 self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
3477                 hir::TraitItemKind::Const(
3478                     self.lower_ty(ty, ImplTraitContext::disallowed()),
3479                     default
3480                         .as_ref()
3481                         .map(|x| self.lower_body(None, |this| this.lower_expr(x))),
3482                 ),
3483             ),
3484             TraitItemKind::Method(ref sig, None) => {
3485                 let names = self.lower_fn_args_to_names(&sig.decl);
3486                 let (generics, sig) = self.lower_method_sig(
3487                     &i.generics,
3488                     sig,
3489                     trait_item_def_id,
3490                     false,
3491                     None,
3492                 );
3493                 (generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Required(names)))
3494             }
3495             TraitItemKind::Method(ref sig, Some(ref body)) => {
3496                 let body_id = self.lower_body(Some(&sig.decl), |this| {
3497                     let body = this.lower_block(body, false);
3498                     this.expr_block(body, ThinVec::new())
3499                 });
3500                 let (generics, sig) = self.lower_method_sig(
3501                     &i.generics,
3502                     sig,
3503                     trait_item_def_id,
3504                     false,
3505                     None,
3506                 );
3507                 (generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Provided(body_id)))
3508             }
3509             TraitItemKind::Type(ref bounds, ref default) => (
3510                 self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
3511                 hir::TraitItemKind::Type(
3512                     self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
3513                     default
3514                         .as_ref()
3515                         .map(|x| self.lower_ty(x, ImplTraitContext::disallowed())),
3516                 ),
3517             ),
3518             TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"),
3519         };
3520
3521         hir::TraitItem {
3522             hir_id: self.lower_node_id(i.id),
3523             ident: i.ident,
3524             attrs: self.lower_attrs(&i.attrs),
3525             generics,
3526             node,
3527             span: i.span,
3528         }
3529     }
3530
3531     fn lower_trait_item_ref(&mut self, i: &TraitItem) -> hir::TraitItemRef {
3532         let (kind, has_default) = match i.node {
3533             TraitItemKind::Const(_, ref default) => {
3534                 (hir::AssocItemKind::Const, default.is_some())
3535             }
3536             TraitItemKind::Type(_, ref default) => {
3537                 (hir::AssocItemKind::Type, default.is_some())
3538             }
3539             TraitItemKind::Method(ref sig, ref default) => (
3540                 hir::AssocItemKind::Method {
3541                     has_self: sig.decl.has_self(),
3542                 },
3543                 default.is_some(),
3544             ),
3545             TraitItemKind::Macro(..) => unimplemented!(),
3546         };
3547         hir::TraitItemRef {
3548             id: hir::TraitItemId { hir_id: self.lower_node_id(i.id) },
3549             ident: i.ident,
3550             span: i.span,
3551             defaultness: self.lower_defaultness(Defaultness::Default, has_default),
3552             kind,
3553         }
3554     }
3555
3556     fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
3557         let impl_item_def_id = self.resolver.definitions().local_def_id(i.id);
3558
3559         let (generics, node) = match i.node {
3560             ImplItemKind::Const(ref ty, ref expr) => {
3561                 let body_id = self.lower_body(None, |this| this.lower_expr(expr));
3562                 (
3563                     self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
3564                     hir::ImplItemKind::Const(
3565                         self.lower_ty(ty, ImplTraitContext::disallowed()),
3566                         body_id,
3567                     ),
3568                 )
3569             }
3570             ImplItemKind::Method(ref sig, ref body) => {
3571                 let body_id = self.lower_async_body(&sig.decl, sig.header.asyncness.node, body);
3572                 let impl_trait_return_allow = !self.is_in_trait_impl;
3573                 let (generics, sig) = self.lower_method_sig(
3574                     &i.generics,
3575                     sig,
3576                     impl_item_def_id,
3577                     impl_trait_return_allow,
3578                     sig.header.asyncness.node.opt_return_id(),
3579                 );
3580                 self.current_item = Some(i.span);
3581
3582                 (generics, hir::ImplItemKind::Method(sig, body_id))
3583             }
3584             ImplItemKind::Type(ref ty) => (
3585                 self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
3586                 hir::ImplItemKind::Type(self.lower_ty(ty, ImplTraitContext::disallowed())),
3587             ),
3588             ImplItemKind::Existential(ref bounds) => (
3589                 self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
3590                 hir::ImplItemKind::Existential(
3591                     self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
3592                 ),
3593             ),
3594             ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
3595         };
3596
3597         hir::ImplItem {
3598             hir_id: self.lower_node_id(i.id),
3599             ident: i.ident,
3600             attrs: self.lower_attrs(&i.attrs),
3601             generics,
3602             vis: self.lower_visibility(&i.vis, None),
3603             defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
3604             node,
3605             span: i.span,
3606         }
3607
3608         // [1] since `default impl` is not yet implemented, this is always true in impls
3609     }
3610
3611     fn lower_impl_item_ref(&mut self, i: &ImplItem) -> hir::ImplItemRef {
3612         hir::ImplItemRef {
3613             id: hir::ImplItemId { hir_id: self.lower_node_id(i.id) },
3614             ident: i.ident,
3615             span: i.span,
3616             vis: self.lower_visibility(&i.vis, Some(i.id)),
3617             defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
3618             kind: match i.node {
3619                 ImplItemKind::Const(..) => hir::AssocItemKind::Const,
3620                 ImplItemKind::Type(..) => hir::AssocItemKind::Type,
3621                 ImplItemKind::Existential(..) => hir::AssocItemKind::Existential,
3622                 ImplItemKind::Method(ref sig, _) => hir::AssocItemKind::Method {
3623                     has_self: sig.decl.has_self(),
3624                 },
3625                 ImplItemKind::Macro(..) => unimplemented!(),
3626             },
3627         }
3628
3629         // [1] since `default impl` is not yet implemented, this is always true in impls
3630     }
3631
3632     fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
3633         hir::Mod {
3634             inner: m.inner,
3635             item_ids: m.items.iter().flat_map(|x| self.lower_item_id(x)).collect(),
3636         }
3637     }
3638
3639     fn lower_item_id(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {
3640         let node_ids = match i.node {
3641             ItemKind::Use(ref use_tree) => {
3642                 let mut vec = smallvec![i.id];
3643                 self.lower_item_id_use_tree(use_tree, i.id, &mut vec);
3644                 vec
3645             }
3646             ItemKind::MacroDef(..) => SmallVec::new(),
3647             ItemKind::Fn(..) |
3648             ItemKind::Impl(.., None, _, _) => smallvec![i.id],
3649             ItemKind::Static(ref ty, ..) => {
3650                 let mut ids = smallvec![i.id];
3651                 if self.sess.features_untracked().impl_trait_in_bindings {
3652                     let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
3653                     visitor.visit_ty(ty);
3654                 }
3655                 ids
3656             },
3657             ItemKind::Const(ref ty, ..) => {
3658                 let mut ids = smallvec![i.id];
3659                 if self.sess.features_untracked().impl_trait_in_bindings {
3660                     let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
3661                     visitor.visit_ty(ty);
3662                 }
3663                 ids
3664             },
3665             _ => smallvec![i.id],
3666         };
3667
3668         node_ids.into_iter().map(|node_id| hir::ItemId {
3669             id: self.allocate_hir_id_counter(node_id)
3670         }).collect()
3671     }
3672
3673     fn lower_item_id_use_tree(&mut self,
3674                               tree: &UseTree,
3675                               base_id: NodeId,
3676                               vec: &mut SmallVec<[NodeId; 1]>)
3677     {
3678         match tree.kind {
3679             UseTreeKind::Nested(ref nested_vec) => for &(ref nested, id) in nested_vec {
3680                 vec.push(id);
3681                 self.lower_item_id_use_tree(nested, id, vec);
3682             },
3683             UseTreeKind::Glob => {}
3684             UseTreeKind::Simple(_, id1, id2) => {
3685                 for (_, &id) in self.expect_full_res_from_use(base_id)
3686                                     .skip(1)
3687                                     .zip([id1, id2].iter())
3688                 {
3689                     vec.push(id);
3690                 }
3691             },
3692         }
3693     }
3694
3695     pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item> {
3696         let mut ident = i.ident;
3697         let mut vis = self.lower_visibility(&i.vis, None);
3698         let attrs = self.lower_attrs(&i.attrs);
3699         if let ItemKind::MacroDef(ref def) = i.node {
3700             if !def.legacy || attr::contains_name(&i.attrs, sym::macro_export) ||
3701                               attr::contains_name(&i.attrs, sym::rustc_doc_only_macro) {
3702                 let body = self.lower_token_stream(def.stream());
3703                 let hir_id = self.lower_node_id(i.id);
3704                 self.exported_macros.push(hir::MacroDef {
3705                     name: ident.name,
3706                     vis,
3707                     attrs,
3708                     hir_id,
3709                     span: i.span,
3710                     body,
3711                     legacy: def.legacy,
3712                 });
3713             }
3714             return None;
3715         }
3716
3717         let node = self.lower_item_kind(i.id, &mut ident, &attrs, &mut vis, &i.node);
3718
3719         Some(hir::Item {
3720             hir_id: self.lower_node_id(i.id),
3721             ident,
3722             attrs,
3723             node,
3724             vis,
3725             span: i.span,
3726         })
3727     }
3728
3729     fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
3730         let def_id = self.resolver.definitions().local_def_id(i.id);
3731         hir::ForeignItem {
3732             hir_id: self.lower_node_id(i.id),
3733             ident: i.ident,
3734             attrs: self.lower_attrs(&i.attrs),
3735             node: match i.node {
3736                 ForeignItemKind::Fn(ref fdec, ref generics) => {
3737                     let (generics, (fn_dec, fn_args)) = self.add_in_band_defs(
3738                         generics,
3739                         def_id,
3740                         AnonymousLifetimeMode::PassThrough,
3741                         |this, _| {
3742                             (
3743                                 // Disallow impl Trait in foreign items
3744                                 this.lower_fn_decl(fdec, None, false, None),
3745                                 this.lower_fn_args_to_names(fdec),
3746                             )
3747                         },
3748                     );
3749
3750                     hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
3751                 }
3752                 ForeignItemKind::Static(ref t, m) => {
3753                     hir::ForeignItemKind::Static(
3754                         self.lower_ty(t, ImplTraitContext::disallowed()), self.lower_mutability(m))
3755                 }
3756                 ForeignItemKind::Ty => hir::ForeignItemKind::Type,
3757                 ForeignItemKind::Macro(_) => panic!("shouldn't exist here"),
3758             },
3759             vis: self.lower_visibility(&i.vis, None),
3760             span: i.span,
3761         }
3762     }
3763
3764     fn lower_method_sig(
3765         &mut self,
3766         generics: &Generics,
3767         sig: &MethodSig,
3768         fn_def_id: DefId,
3769         impl_trait_return_allow: bool,
3770         is_async: Option<NodeId>,
3771     ) -> (hir::Generics, hir::MethodSig) {
3772         let header = self.lower_fn_header(sig.header);
3773         let (generics, decl) = self.add_in_band_defs(
3774             generics,
3775             fn_def_id,
3776             AnonymousLifetimeMode::PassThrough,
3777             |this, idty| this.lower_fn_decl(
3778                 &sig.decl,
3779                 Some((fn_def_id, idty)),
3780                 impl_trait_return_allow,
3781                 is_async,
3782             ),
3783         );
3784         (generics, hir::MethodSig { header, decl })
3785     }
3786
3787     fn lower_is_auto(&mut self, a: IsAuto) -> hir::IsAuto {
3788         match a {
3789             IsAuto::Yes => hir::IsAuto::Yes,
3790             IsAuto::No => hir::IsAuto::No,
3791         }
3792     }
3793
3794     fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
3795         hir::FnHeader {
3796             unsafety: self.lower_unsafety(h.unsafety),
3797             asyncness: self.lower_asyncness(h.asyncness.node),
3798             constness: self.lower_constness(h.constness),
3799             abi: h.abi,
3800         }
3801     }
3802
3803     fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
3804         match u {
3805             Unsafety::Unsafe => hir::Unsafety::Unsafe,
3806             Unsafety::Normal => hir::Unsafety::Normal,
3807         }
3808     }
3809
3810     fn lower_constness(&mut self, c: Spanned<Constness>) -> hir::Constness {
3811         match c.node {
3812             Constness::Const => hir::Constness::Const,
3813             Constness::NotConst => hir::Constness::NotConst,
3814         }
3815     }
3816
3817     fn lower_asyncness(&mut self, a: IsAsync) -> hir::IsAsync {
3818         match a {
3819             IsAsync::Async { .. } => hir::IsAsync::Async,
3820             IsAsync::NotAsync => hir::IsAsync::NotAsync,
3821         }
3822     }
3823
3824     fn lower_unop(&mut self, u: UnOp) -> hir::UnOp {
3825         match u {
3826             UnOp::Deref => hir::UnDeref,
3827             UnOp::Not => hir::UnNot,
3828             UnOp::Neg => hir::UnNeg,
3829         }
3830     }
3831
3832     fn lower_binop(&mut self, b: BinOp) -> hir::BinOp {
3833         Spanned {
3834             node: match b.node {
3835                 BinOpKind::Add => hir::BinOpKind::Add,
3836                 BinOpKind::Sub => hir::BinOpKind::Sub,
3837                 BinOpKind::Mul => hir::BinOpKind::Mul,
3838                 BinOpKind::Div => hir::BinOpKind::Div,
3839                 BinOpKind::Rem => hir::BinOpKind::Rem,
3840                 BinOpKind::And => hir::BinOpKind::And,
3841                 BinOpKind::Or => hir::BinOpKind::Or,
3842                 BinOpKind::BitXor => hir::BinOpKind::BitXor,
3843                 BinOpKind::BitAnd => hir::BinOpKind::BitAnd,
3844                 BinOpKind::BitOr => hir::BinOpKind::BitOr,
3845                 BinOpKind::Shl => hir::BinOpKind::Shl,
3846                 BinOpKind::Shr => hir::BinOpKind::Shr,
3847                 BinOpKind::Eq => hir::BinOpKind::Eq,
3848                 BinOpKind::Lt => hir::BinOpKind::Lt,
3849                 BinOpKind::Le => hir::BinOpKind::Le,
3850                 BinOpKind::Ne => hir::BinOpKind::Ne,
3851                 BinOpKind::Ge => hir::BinOpKind::Ge,
3852                 BinOpKind::Gt => hir::BinOpKind::Gt,
3853             },
3854             span: b.span,
3855         }
3856     }
3857
3858     fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
3859         let node = match p.node {
3860             PatKind::Wild => hir::PatKind::Wild,
3861             PatKind::Ident(ref binding_mode, ident, ref sub) => {
3862                 match self.resolver.get_partial_res(p.id).map(|d| d.base_res()) {
3863                     // `None` can occur in body-less function signatures
3864                     res @ None | res @ Some(Res::Local(_)) => {
3865                         let canonical_id = match res {
3866                             Some(Res::Local(id)) => id,
3867                             _ => p.id,
3868                         };
3869
3870                         hir::PatKind::Binding(
3871                             self.lower_binding_mode(binding_mode),
3872                             self.lower_node_id(canonical_id),
3873                             ident,
3874                             sub.as_ref().map(|x| self.lower_pat(x)),
3875                         )
3876                     }
3877                     Some(res) => hir::PatKind::Path(hir::QPath::Resolved(
3878                         None,
3879                         P(hir::Path {
3880                             span: ident.span,
3881                             res: self.lower_res(res),
3882                             segments: hir_vec![hir::PathSegment::from_ident(ident)],
3883                         }),
3884                     )),
3885                 }
3886             }
3887             PatKind::Lit(ref e) => hir::PatKind::Lit(P(self.lower_expr(e))),
3888             PatKind::TupleStruct(ref path, ref pats, ddpos) => {
3889                 let qpath = self.lower_qpath(
3890                     p.id,
3891                     &None,
3892                     path,
3893                     ParamMode::Optional,
3894                     ImplTraitContext::disallowed(),
3895                 );
3896                 hir::PatKind::TupleStruct(
3897                     qpath,
3898                     pats.iter().map(|x| self.lower_pat(x)).collect(),
3899                     ddpos,
3900                 )
3901             }
3902             PatKind::Path(ref qself, ref path) => {
3903                 let qpath = self.lower_qpath(
3904                     p.id,
3905                     qself,
3906                     path,
3907                     ParamMode::Optional,
3908                     ImplTraitContext::disallowed(),
3909                 );
3910                 hir::PatKind::Path(qpath)
3911             }
3912             PatKind::Struct(ref path, ref fields, etc) => {
3913                 let qpath = self.lower_qpath(
3914                     p.id,
3915                     &None,
3916                     path,
3917                     ParamMode::Optional,
3918                     ImplTraitContext::disallowed(),
3919                 );
3920
3921                 let fs = fields
3922                     .iter()
3923                     .map(|f| {
3924                         Spanned {
3925                             span: f.span,
3926                             node: hir::FieldPat {
3927                                 hir_id: self.next_id(),
3928                                 ident: f.node.ident,
3929                                 pat: self.lower_pat(&f.node.pat),
3930                                 is_shorthand: f.node.is_shorthand,
3931                             },
3932                         }
3933                     })
3934                     .collect();
3935                 hir::PatKind::Struct(qpath, fs, etc)
3936             }
3937             PatKind::Tuple(ref elts, ddpos) => {
3938                 hir::PatKind::Tuple(elts.iter().map(|x| self.lower_pat(x)).collect(), ddpos)
3939             }
3940             PatKind::Box(ref inner) => hir::PatKind::Box(self.lower_pat(inner)),
3941             PatKind::Ref(ref inner, mutbl) => {
3942                 hir::PatKind::Ref(self.lower_pat(inner), self.lower_mutability(mutbl))
3943             }
3944             PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => hir::PatKind::Range(
3945                 P(self.lower_expr(e1)),
3946                 P(self.lower_expr(e2)),
3947                 self.lower_range_end(end),
3948             ),
3949             PatKind::Slice(ref before, ref slice, ref after) => hir::PatKind::Slice(
3950                 before.iter().map(|x| self.lower_pat(x)).collect(),
3951                 slice.as_ref().map(|x| self.lower_pat(x)),
3952                 after.iter().map(|x| self.lower_pat(x)).collect(),
3953             ),
3954             PatKind::Paren(ref inner) => return self.lower_pat(inner),
3955             PatKind::Mac(_) => panic!("Shouldn't exist here"),
3956         };
3957
3958         P(hir::Pat {
3959             hir_id: self.lower_node_id(p.id),
3960             node,
3961             span: p.span,
3962         })
3963     }
3964
3965     fn lower_range_end(&mut self, e: &RangeEnd) -> hir::RangeEnd {
3966         match *e {
3967             RangeEnd::Included(_) => hir::RangeEnd::Included,
3968             RangeEnd::Excluded => hir::RangeEnd::Excluded,
3969         }
3970     }
3971
3972     fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
3973         self.with_new_scopes(|this| {
3974             hir::AnonConst {
3975                 hir_id: this.lower_node_id(c.id),
3976                 body: this.lower_body(None, |this| this.lower_expr(&c.value)),
3977             }
3978         })
3979     }
3980
3981     fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
3982         let kind = match e.node {
3983             ExprKind::Box(ref inner) => hir::ExprKind::Box(P(self.lower_expr(inner))),
3984             ExprKind::Array(ref exprs) => {
3985                 hir::ExprKind::Array(exprs.iter().map(|x| self.lower_expr(x)).collect())
3986             }
3987             ExprKind::Repeat(ref expr, ref count) => {
3988                 let expr = P(self.lower_expr(expr));
3989                 let count = self.lower_anon_const(count);
3990                 hir::ExprKind::Repeat(expr, count)
3991             }
3992             ExprKind::Tup(ref elts) => {
3993                 hir::ExprKind::Tup(elts.iter().map(|x| self.lower_expr(x)).collect())
3994             }
3995             ExprKind::Call(ref f, ref args) => {
3996                 let f = P(self.lower_expr(f));
3997                 hir::ExprKind::Call(f, args.iter().map(|x| self.lower_expr(x)).collect())
3998             }
3999             ExprKind::MethodCall(ref seg, ref args) => {
4000                 let hir_seg = P(self.lower_path_segment(
4001                     e.span,
4002                     seg,
4003                     ParamMode::Optional,
4004                     0,
4005                     ParenthesizedGenericArgs::Err,
4006                     ImplTraitContext::disallowed(),
4007                     None,
4008                 ));
4009                 let args = args.iter().map(|x| self.lower_expr(x)).collect();
4010                 hir::ExprKind::MethodCall(hir_seg, seg.ident.span, args)
4011             }
4012             ExprKind::Binary(binop, ref lhs, ref rhs) => {
4013                 let binop = self.lower_binop(binop);
4014                 let lhs = P(self.lower_expr(lhs));
4015                 let rhs = P(self.lower_expr(rhs));
4016                 hir::ExprKind::Binary(binop, lhs, rhs)
4017             }
4018             ExprKind::Unary(op, ref ohs) => {
4019                 let op = self.lower_unop(op);
4020                 let ohs = P(self.lower_expr(ohs));
4021                 hir::ExprKind::Unary(op, ohs)
4022             }
4023             ExprKind::Lit(ref l) => hir::ExprKind::Lit(respan(l.span, l.node.clone())),
4024             ExprKind::Cast(ref expr, ref ty) => {
4025                 let expr = P(self.lower_expr(expr));
4026                 hir::ExprKind::Cast(expr, self.lower_ty(ty, ImplTraitContext::disallowed()))
4027             }
4028             ExprKind::Type(ref expr, ref ty) => {
4029                 let expr = P(self.lower_expr(expr));
4030                 hir::ExprKind::Type(expr, self.lower_ty(ty, ImplTraitContext::disallowed()))
4031             }
4032             ExprKind::AddrOf(m, ref ohs) => {
4033                 let m = self.lower_mutability(m);
4034                 let ohs = P(self.lower_expr(ohs));
4035                 hir::ExprKind::AddrOf(m, ohs)
4036             }
4037             // More complicated than you might expect because the else branch
4038             // might be `if let`.
4039             ExprKind::If(ref cond, ref then, ref else_opt) => {
4040                 // `true => then`:
4041                 let then_pat = self.pat_bool(e.span, true);
4042                 let then_blk = self.lower_block(then, false);
4043                 let then_expr = self.expr_block(then_blk, ThinVec::new());
4044                 let then_arm = self.arm(hir_vec![then_pat], P(then_expr));
4045
4046                 // `_ => else_block` where `else_block` is `{}` if there's `None`:
4047                 let else_pat = self.pat_wild(e.span);
4048                 let else_expr = match else_opt {
4049                     None => self.expr_block_empty(e.span),
4050                     Some(els) => match els.node {
4051                         ExprKind::IfLet(..) => {
4052                             // Wrap the `if let` expr in a block.
4053                             let els = self.lower_expr(els);
4054                             let blk = self.block_all(els.span, hir_vec![], Some(P(els)));
4055                             self.expr_block(P(blk), ThinVec::new())
4056                         }
4057                         _ => self.lower_expr(els),
4058                     }
4059                 };
4060                 let else_arm = self.arm(hir_vec![else_pat], P(else_expr));
4061
4062                 // Lower condition:
4063                 let span_block = self.mark_span_with_reason(IfTemporary, cond.span, None);
4064                 let cond = self.lower_expr(cond);
4065                 // Wrap in a construct equivalent to `{ let _t = $cond; _t }` to preserve drop
4066                 // semantics since `if cond { ... }` don't let temporaries live outside of `cond`.
4067                 let cond = self.expr_drop_temps(span_block, P(cond), ThinVec::new());
4068
4069                 hir::ExprKind::Match(
4070                     P(cond),
4071                     vec![then_arm, else_arm].into(),
4072                     hir::MatchSource::IfDesugar {
4073                         contains_else_clause: else_opt.is_some()
4074                     },
4075                 )
4076             }
4077             ExprKind::While(ref cond, ref body, opt_label) => self.with_loop_scope(e.id, |this| {
4078                 hir::ExprKind::While(
4079                     this.with_loop_condition_scope(|this| P(this.lower_expr(cond))),
4080                     this.lower_block(body, false),
4081                     this.lower_label(opt_label),
4082                 )
4083             }),
4084             ExprKind::Loop(ref body, opt_label) => self.with_loop_scope(e.id, |this| {
4085                 hir::ExprKind::Loop(
4086                     this.lower_block(body, false),
4087                     this.lower_label(opt_label),
4088                     hir::LoopSource::Loop,
4089                 )
4090             }),
4091             ExprKind::TryBlock(ref body) => {
4092                 self.with_catch_scope(body.id, |this| {
4093                     let unstable_span = this.mark_span_with_reason(
4094                         CompilerDesugaringKind::TryBlock,
4095                         body.span,
4096                         Some(vec![sym::try_trait].into()),
4097                     );
4098                     let mut block = this.lower_block(body, true).into_inner();
4099                     let tail = block.expr.take().map_or_else(
4100                         || {
4101                             let span = this.sess.source_map().end_point(unstable_span);
4102                             hir::Expr {
4103                                 span,
4104                                 node: hir::ExprKind::Tup(hir_vec![]),
4105                                 attrs: ThinVec::new(),
4106                                 hir_id: this.next_id(),
4107                             }
4108                         },
4109                         |x: P<hir::Expr>| x.into_inner(),
4110                     );
4111                     block.expr = Some(this.wrap_in_try_constructor(
4112                         sym::from_ok, tail, unstable_span));
4113                     hir::ExprKind::Block(P(block), None)
4114                 })
4115             }
4116             ExprKind::Match(ref expr, ref arms) => hir::ExprKind::Match(
4117                 P(self.lower_expr(expr)),
4118                 arms.iter().map(|x| self.lower_arm(x)).collect(),
4119                 hir::MatchSource::Normal,
4120             ),
4121             ExprKind::Async(capture_clause, closure_node_id, ref block) => {
4122                 self.make_async_expr(capture_clause, closure_node_id, None, block.span, |this| {
4123                     this.with_new_scopes(|this| {
4124                         let block = this.lower_block(block, false);
4125                         this.expr_block(block, ThinVec::new())
4126                     })
4127                 })
4128             }
4129             ExprKind::Await(_origin, ref expr) => self.lower_await(e.span, expr),
4130             ExprKind::Closure(
4131                 capture_clause, asyncness, movability, ref decl, ref body, fn_decl_span
4132             ) => {
4133                 if let IsAsync::Async { closure_id, .. } = asyncness {
4134                     let outer_decl = FnDecl {
4135                         inputs: decl.inputs.clone(),
4136                         output: FunctionRetTy::Default(fn_decl_span),
4137                         c_variadic: false,
4138                     };
4139                     // We need to lower the declaration outside the new scope, because we
4140                     // have to conserve the state of being inside a loop condition for the
4141                     // closure argument types.
4142                     let fn_decl = self.lower_fn_decl(&outer_decl, None, false, None);
4143
4144                     self.with_new_scopes(|this| {
4145                         // FIXME(cramertj): allow `async` non-`move` closures with arguments.
4146                         if capture_clause == CaptureBy::Ref &&
4147                             !decl.inputs.is_empty()
4148                         {
4149                             struct_span_err!(
4150                                 this.sess,
4151                                 fn_decl_span,
4152                                 E0708,
4153                                 "`async` non-`move` closures with arguments \
4154                                 are not currently supported",
4155                             )
4156                                 .help("consider using `let` statements to manually capture \
4157                                        variables by reference before entering an \
4158                                        `async move` closure")
4159                                 .emit();
4160                         }
4161
4162                         // Transform `async |x: u8| -> X { ... }` into
4163                         // `|x: u8| future_from_generator(|| -> X { ... })`.
4164                         let body_id = this.lower_body(Some(&outer_decl), |this| {
4165                             let async_ret_ty = if let FunctionRetTy::Ty(ty) = &decl.output {
4166                                 Some(&**ty)
4167                             } else { None };
4168                             let async_body = this.make_async_expr(
4169                                 capture_clause, closure_id, async_ret_ty, body.span,
4170                                 |this| {
4171                                     this.with_new_scopes(|this| this.lower_expr(body))
4172                                 });
4173                             this.expr(fn_decl_span, async_body, ThinVec::new())
4174                         });
4175                         hir::ExprKind::Closure(
4176                             this.lower_capture_clause(capture_clause),
4177                             fn_decl,
4178                             body_id,
4179                             fn_decl_span,
4180                             None,
4181                         )
4182                     })
4183                 } else {
4184                     // Lower outside new scope to preserve `is_in_loop_condition`.
4185                     let fn_decl = self.lower_fn_decl(decl, None, false, None);
4186
4187                     self.with_new_scopes(|this| {
4188                         this.current_item = Some(fn_decl_span);
4189                         let mut is_generator = false;
4190                         let body_id = this.lower_body(Some(decl), |this| {
4191                             let e = this.lower_expr(body);
4192                             is_generator = this.is_generator;
4193                             e
4194                         });
4195                         let generator_option = if is_generator {
4196                             if !decl.inputs.is_empty() {
4197                                 span_err!(
4198                                     this.sess,
4199                                     fn_decl_span,
4200                                     E0628,
4201                                     "generators cannot have explicit arguments"
4202                                 );
4203                                 this.sess.abort_if_errors();
4204                             }
4205                             Some(match movability {
4206                                 Movability::Movable => hir::GeneratorMovability::Movable,
4207                                 Movability::Static => hir::GeneratorMovability::Static,
4208                             })
4209                         } else {
4210                             if movability == Movability::Static {
4211                                 span_err!(
4212                                     this.sess,
4213                                     fn_decl_span,
4214                                     E0697,
4215                                     "closures cannot be static"
4216                                 );
4217                             }
4218                             None
4219                         };
4220                         hir::ExprKind::Closure(
4221                             this.lower_capture_clause(capture_clause),
4222                             fn_decl,
4223                             body_id,
4224                             fn_decl_span,
4225                             generator_option,
4226                         )
4227                     })
4228                 }
4229             }
4230             ExprKind::Block(ref blk, opt_label) => {
4231                 hir::ExprKind::Block(self.lower_block(blk,
4232                                                       opt_label.is_some()),
4233                                                       self.lower_label(opt_label))
4234             }
4235             ExprKind::Assign(ref el, ref er) => {
4236                 hir::ExprKind::Assign(P(self.lower_expr(el)), P(self.lower_expr(er)))
4237             }
4238             ExprKind::AssignOp(op, ref el, ref er) => hir::ExprKind::AssignOp(
4239                 self.lower_binop(op),
4240                 P(self.lower_expr(el)),
4241                 P(self.lower_expr(er)),
4242             ),
4243             ExprKind::Field(ref el, ident) => hir::ExprKind::Field(P(self.lower_expr(el)), ident),
4244             ExprKind::Index(ref el, ref er) => {
4245                 hir::ExprKind::Index(P(self.lower_expr(el)), P(self.lower_expr(er)))
4246             }
4247             // Desugar `<start>..=<end>` into `std::ops::RangeInclusive::new(<start>, <end>)`.
4248             ExprKind::Range(Some(ref e1), Some(ref e2), RangeLimits::Closed) => {
4249                 let id = self.next_id();
4250                 let e1 = self.lower_expr(e1);
4251                 let e2 = self.lower_expr(e2);
4252                 self.expr_call_std_assoc_fn(
4253                     id,
4254                     e.span,
4255                     &[sym::ops, sym::RangeInclusive],
4256                     "new",
4257                     hir_vec![e1, e2],
4258                 )
4259             }
4260             ExprKind::Range(ref e1, ref e2, lims) => {
4261                 use syntax::ast::RangeLimits::*;
4262
4263                 let path = match (e1, e2, lims) {
4264                     (&None, &None, HalfOpen) => sym::RangeFull,
4265                     (&Some(..), &None, HalfOpen) => sym::RangeFrom,
4266                     (&None, &Some(..), HalfOpen) => sym::RangeTo,
4267                     (&Some(..), &Some(..), HalfOpen) => sym::Range,
4268                     (&None, &Some(..), Closed) => sym::RangeToInclusive,
4269                     (&Some(..), &Some(..), Closed) => unreachable!(),
4270                     (_, &None, Closed) => self.diagnostic()
4271                         .span_fatal(e.span, "inclusive range with no end")
4272                         .raise(),
4273                 };
4274
4275                 let fields = e1.iter()
4276                     .map(|e| ("start", e))
4277                     .chain(e2.iter().map(|e| ("end", e)))
4278                     .map(|(s, e)| {
4279                         let expr = P(self.lower_expr(&e));
4280                         let ident = Ident::new(Symbol::intern(s), e.span);
4281                         self.field(ident, expr, e.span)
4282                     })
4283                     .collect::<P<[hir::Field]>>();
4284
4285                 let is_unit = fields.is_empty();
4286                 let struct_path = [sym::ops, path];
4287                 let struct_path = self.std_path(e.span, &struct_path, None, is_unit);
4288                 let struct_path = hir::QPath::Resolved(None, P(struct_path));
4289
4290                 return hir::Expr {
4291                     hir_id: self.lower_node_id(e.id),
4292                     node: if is_unit {
4293                         hir::ExprKind::Path(struct_path)
4294                     } else {
4295                         hir::ExprKind::Struct(P(struct_path), fields, None)
4296                     },
4297                     span: e.span,
4298                     attrs: e.attrs.clone(),
4299                 };
4300             }
4301             ExprKind::Path(ref qself, ref path) => {
4302                 let qpath = self.lower_qpath(
4303                     e.id,
4304                     qself,
4305                     path,
4306                     ParamMode::Optional,
4307                     ImplTraitContext::disallowed(),
4308                 );
4309                 hir::ExprKind::Path(qpath)
4310             }
4311             ExprKind::Break(opt_label, ref opt_expr) => {
4312                 let destination = if self.is_in_loop_condition && opt_label.is_none() {
4313                     hir::Destination {
4314                         label: None,
4315                         target_id: Err(hir::LoopIdError::UnlabeledCfInWhileCondition).into(),
4316                     }
4317                 } else {
4318                     self.lower_loop_destination(opt_label.map(|label| (e.id, label)))
4319                 };
4320                 hir::ExprKind::Break(
4321                     destination,
4322                     opt_expr.as_ref().map(|x| P(self.lower_expr(x))),
4323                 )
4324             }
4325             ExprKind::Continue(opt_label) => {
4326                 hir::ExprKind::Continue(if self.is_in_loop_condition && opt_label.is_none() {
4327                     hir::Destination {
4328                         label: None,
4329                         target_id: Err(hir::LoopIdError::UnlabeledCfInWhileCondition).into(),
4330                     }
4331                 } else {
4332                     self.lower_loop_destination(opt_label.map(|label| (e.id, label)))
4333                 })
4334             }
4335             ExprKind::Ret(ref e) => hir::ExprKind::Ret(e.as_ref().map(|x| P(self.lower_expr(x)))),
4336             ExprKind::InlineAsm(ref asm) => {
4337                 let hir_asm = hir::InlineAsm {
4338                     inputs: asm.inputs.iter().map(|&(ref c, _)| c.clone()).collect(),
4339                     outputs: asm.outputs
4340                         .iter()
4341                         .map(|out| hir::InlineAsmOutput {
4342                             constraint: out.constraint.clone(),
4343                             is_rw: out.is_rw,
4344                             is_indirect: out.is_indirect,
4345                             span: out.expr.span,
4346                         })
4347                         .collect(),
4348                     asm: asm.asm.clone(),
4349                     asm_str_style: asm.asm_str_style,
4350                     clobbers: asm.clobbers.clone().into(),
4351                     volatile: asm.volatile,
4352                     alignstack: asm.alignstack,
4353                     dialect: asm.dialect,
4354                     ctxt: asm.ctxt,
4355                 };
4356                 let outputs = asm.outputs
4357                     .iter()
4358                     .map(|out| self.lower_expr(&out.expr))
4359                     .collect();
4360                 let inputs = asm.inputs
4361                     .iter()
4362                     .map(|&(_, ref input)| self.lower_expr(input))
4363                     .collect();
4364                 hir::ExprKind::InlineAsm(P(hir_asm), outputs, inputs)
4365             }
4366             ExprKind::Struct(ref path, ref fields, ref maybe_expr) => hir::ExprKind::Struct(
4367                 P(self.lower_qpath(
4368                     e.id,
4369                     &None,
4370                     path,
4371                     ParamMode::Optional,
4372                     ImplTraitContext::disallowed(),
4373                 )),
4374                 fields.iter().map(|x| self.lower_field(x)).collect(),
4375                 maybe_expr.as_ref().map(|x| P(self.lower_expr(x))),
4376             ),
4377             ExprKind::Paren(ref ex) => {
4378                 let mut ex = self.lower_expr(ex);
4379                 // Include parens in span, but only if it is a super-span.
4380                 if e.span.contains(ex.span) {
4381                     ex.span = e.span;
4382                 }
4383                 // Merge attributes into the inner expression.
4384                 let mut attrs = e.attrs.clone();
4385                 attrs.extend::<Vec<_>>(ex.attrs.into());
4386                 ex.attrs = attrs;
4387                 return ex;
4388             }
4389
4390             ExprKind::Yield(ref opt_expr) => {
4391                 self.is_generator = true;
4392                 let expr = opt_expr
4393                     .as_ref()
4394                     .map(|x| self.lower_expr(x))
4395                     .unwrap_or_else(|| self.expr_unit(e.span));
4396                 hir::ExprKind::Yield(P(expr))
4397             }
4398
4399             ExprKind::Err => hir::ExprKind::Err,
4400
4401             // Desugar `ExprIfLet`
4402             // from: `if let <pat> = <sub_expr> <body> [<else_opt>]`
4403             ExprKind::IfLet(ref pats, ref sub_expr, ref body, ref else_opt) => {
4404                 // to:
4405                 //
4406                 //   match <sub_expr> {
4407                 //     <pat> => <body>,
4408                 //     _ => [<else_opt> | ()]
4409                 //   }
4410
4411                 let mut arms = vec![];
4412
4413                 // `<pat> => <body>`
4414                 {
4415                     let body = self.lower_block(body, false);
4416                     let body_expr = P(self.expr_block(body, ThinVec::new()));
4417                     let pats = pats.iter().map(|pat| self.lower_pat(pat)).collect();
4418                     arms.push(self.arm(pats, body_expr));
4419                 }
4420
4421                 // _ => [<else_opt>|{}]
4422                 {
4423                     let wildcard_arm: Option<&Expr> = else_opt.as_ref().map(|p| &**p);
4424                     let wildcard_pattern = self.pat_wild(e.span);
4425                     let body = if let Some(else_expr) = wildcard_arm {
4426                         self.lower_expr(else_expr)
4427                     } else {
4428                         self.expr_block_empty(e.span)
4429                     };
4430                     arms.push(self.arm(hir_vec![wildcard_pattern], P(body)));
4431                 }
4432
4433                 let contains_else_clause = else_opt.is_some();
4434
4435                 let sub_expr = P(self.lower_expr(sub_expr));
4436
4437                 hir::ExprKind::Match(
4438                     sub_expr,
4439                     arms.into(),
4440                     hir::MatchSource::IfLetDesugar {
4441                         contains_else_clause,
4442                     },
4443                 )
4444             }
4445
4446             // Desugar `ExprWhileLet`
4447             // from: `[opt_ident]: while let <pat> = <sub_expr> <body>`
4448             ExprKind::WhileLet(ref pats, ref sub_expr, ref body, opt_label) => {
4449                 // to:
4450                 //
4451                 //   [opt_ident]: loop {
4452                 //     match <sub_expr> {
4453                 //       <pat> => <body>,
4454                 //       _ => break
4455                 //     }
4456                 //   }
4457
4458                 // Note that the block AND the condition are evaluated in the loop scope.
4459                 // This is done to allow `break` from inside the condition of the loop.
4460                 let (body, break_expr, sub_expr) = self.with_loop_scope(e.id, |this| {
4461                     (
4462                         this.lower_block(body, false),
4463                         this.expr_break(e.span, ThinVec::new()),
4464                         this.with_loop_condition_scope(|this| P(this.lower_expr(sub_expr))),
4465                     )
4466                 });
4467
4468                 // `<pat> => <body>`
4469                 let pat_arm = {
4470                     let body_expr = P(self.expr_block(body, ThinVec::new()));
4471                     let pats = pats.iter().map(|pat| self.lower_pat(pat)).collect();
4472                     self.arm(pats, body_expr)
4473                 };
4474
4475                 // `_ => break`
4476                 let break_arm = {
4477                     let pat_under = self.pat_wild(e.span);
4478                     self.arm(hir_vec![pat_under], break_expr)
4479                 };
4480
4481                 // `match <sub_expr> { ... }`
4482                 let arms = hir_vec![pat_arm, break_arm];
4483                 let match_expr = self.expr(
4484                     sub_expr.span,
4485                     hir::ExprKind::Match(sub_expr, arms, hir::MatchSource::WhileLetDesugar),
4486                     ThinVec::new(),
4487                 );
4488
4489                 // `[opt_ident]: loop { ... }`
4490                 let loop_block = P(self.block_expr(P(match_expr)));
4491                 let loop_expr = hir::ExprKind::Loop(
4492                     loop_block,
4493                     self.lower_label(opt_label),
4494                     hir::LoopSource::WhileLet,
4495                 );
4496                 // Add attributes to the outer returned expr node.
4497                 loop_expr
4498             }
4499
4500             // Desugar `ExprForLoop`
4501             // from: `[opt_ident]: for <pat> in <head> <body>`
4502             ExprKind::ForLoop(ref pat, ref head, ref body, opt_label) => {
4503                 // to:
4504                 //
4505                 //   {
4506                 //     let result = match ::std::iter::IntoIterator::into_iter(<head>) {
4507                 //       mut iter => {
4508                 //         [opt_ident]: loop {
4509                 //           let mut __next;
4510                 //           match ::std::iter::Iterator::next(&mut iter) {
4511                 //             ::std::option::Option::Some(val) => __next = val,
4512                 //             ::std::option::Option::None => break
4513                 //           };
4514                 //           let <pat> = __next;
4515                 //           StmtKind::Expr(<body>);
4516                 //         }
4517                 //       }
4518                 //     };
4519                 //     result
4520                 //   }
4521
4522                 // expand <head>
4523                 let mut head = self.lower_expr(head);
4524                 let head_sp = head.span;
4525                 let desugared_span = self.mark_span_with_reason(
4526                     CompilerDesugaringKind::ForLoop,
4527                     head_sp,
4528                     None,
4529                 );
4530                 head.span = desugared_span;
4531
4532                 let iter = Ident::with_empty_ctxt(sym::iter);
4533
4534                 let next_ident = Ident::with_empty_ctxt(sym::__next);
4535                 let (next_pat, next_pat_hid) = self.pat_ident_binding_mode(
4536                     desugared_span,
4537                     next_ident,
4538                     hir::BindingAnnotation::Mutable,
4539                 );
4540
4541                 // `::std::option::Option::Some(val) => __next = val`
4542                 let pat_arm = {
4543                     let val_ident = Ident::with_empty_ctxt(sym::val);
4544                     let (val_pat, val_pat_hid) = self.pat_ident(pat.span, val_ident);
4545                     let val_expr = P(self.expr_ident(pat.span, val_ident, val_pat_hid));
4546                     let next_expr = P(self.expr_ident(pat.span, next_ident, next_pat_hid));
4547                     let assign = P(self.expr(
4548                         pat.span,
4549                         hir::ExprKind::Assign(next_expr, val_expr),
4550                         ThinVec::new(),
4551                     ));
4552                     let some_pat = self.pat_some(pat.span, val_pat);
4553                     self.arm(hir_vec![some_pat], assign)
4554                 };
4555
4556                 // `::std::option::Option::None => break`
4557                 let break_arm = {
4558                     let break_expr =
4559                         self.with_loop_scope(e.id, |this| this.expr_break(e.span, ThinVec::new()));
4560                     let pat = self.pat_none(e.span);
4561                     self.arm(hir_vec![pat], break_expr)
4562                 };
4563
4564                 // `mut iter`
4565                 let (iter_pat, iter_pat_nid) = self.pat_ident_binding_mode(
4566                     desugared_span,
4567                     iter,
4568                     hir::BindingAnnotation::Mutable
4569                 );
4570
4571                 // `match ::std::iter::Iterator::next(&mut iter) { ... }`
4572                 let match_expr = {
4573                     let iter = P(self.expr_ident(head_sp, iter, iter_pat_nid));
4574                     let ref_mut_iter = self.expr_mut_addr_of(head_sp, iter);
4575                     let next_path = &[sym::iter, sym::Iterator, sym::next];
4576                     let next_expr = P(self.expr_call_std_path(
4577                         head_sp,
4578                         next_path,
4579                         hir_vec![ref_mut_iter],
4580                     ));
4581                     let arms = hir_vec![pat_arm, break_arm];
4582
4583                     P(self.expr(
4584                         head_sp,
4585                         hir::ExprKind::Match(
4586                             next_expr,
4587                             arms,
4588                             hir::MatchSource::ForLoopDesugar
4589                         ),
4590                         ThinVec::new(),
4591                     ))
4592                 };
4593                 let match_stmt = self.stmt(head_sp, hir::StmtKind::Expr(match_expr));
4594
4595                 let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat_hid));
4596
4597                 // `let mut __next`
4598                 let next_let = self.stmt_let_pat(
4599                     desugared_span,
4600                     None,
4601                     next_pat,
4602                     hir::LocalSource::ForLoopDesugar,
4603                 );
4604
4605                 // `let <pat> = __next`
4606                 let pat = self.lower_pat(pat);
4607                 let pat_let = self.stmt_let_pat(
4608                     head_sp,
4609                     Some(next_expr),
4610                     pat,
4611                     hir::LocalSource::ForLoopDesugar,
4612                 );
4613
4614                 let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false));
4615                 let body_expr = P(self.expr_block(body_block, ThinVec::new()));
4616                 let body_stmt = self.stmt(body.span, hir::StmtKind::Expr(body_expr));
4617
4618                 let loop_block = P(self.block_all(
4619                     e.span,
4620                     hir_vec![next_let, match_stmt, pat_let, body_stmt],
4621                     None,
4622                 ));
4623
4624                 // `[opt_ident]: loop { ... }`
4625                 let loop_expr = hir::ExprKind::Loop(
4626                     loop_block,
4627                     self.lower_label(opt_label),
4628                     hir::LoopSource::ForLoop,
4629                 );
4630                 let loop_expr = P(hir::Expr {
4631                     hir_id: self.lower_node_id(e.id),
4632                     node: loop_expr,
4633                     span: e.span,
4634                     attrs: ThinVec::new(),
4635                 });
4636
4637                 // `mut iter => { ... }`
4638                 let iter_arm = self.arm(hir_vec![iter_pat], loop_expr);
4639
4640                 // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
4641                 let into_iter_expr = {
4642                     let into_iter_path =
4643                         &[sym::iter, sym::IntoIterator, sym::into_iter];
4644                     P(self.expr_call_std_path(
4645                         head_sp,
4646                         into_iter_path,
4647                         hir_vec![head],
4648                     ))
4649                 };
4650
4651                 let match_expr = P(self.expr_match(
4652                     head_sp,
4653                     into_iter_expr,
4654                     hir_vec![iter_arm],
4655                     hir::MatchSource::ForLoopDesugar,
4656                 ));
4657
4658                 // This is effectively `{ let _result = ...; _result }`.
4659                 // The construct was introduced in #21984.
4660                 // FIXME(60253): Is this still necessary?
4661                 // Also, add the attributes to the outer returned expr node.
4662                 return self.expr_drop_temps(head_sp, match_expr, e.attrs.clone())
4663             }
4664
4665             // Desugar `ExprKind::Try`
4666             // from: `<expr>?`
4667             ExprKind::Try(ref sub_expr) => {
4668                 // into:
4669                 //
4670                 // match Try::into_result(<expr>) {
4671                 //     Ok(val) => #[allow(unreachable_code)] val,
4672                 //     Err(err) => #[allow(unreachable_code)]
4673                 //                 // If there is an enclosing `catch {...}`
4674                 //                 break 'catch_target Try::from_error(From::from(err)),
4675                 //                 // Otherwise
4676                 //                 return Try::from_error(From::from(err)),
4677                 // }
4678
4679                 let unstable_span = self.mark_span_with_reason(
4680                     CompilerDesugaringKind::QuestionMark,
4681                     e.span,
4682                     Some(vec![sym::try_trait].into()),
4683                 );
4684                 let try_span = self.sess.source_map().end_point(e.span);
4685                 let try_span = self.mark_span_with_reason(
4686                     CompilerDesugaringKind::QuestionMark,
4687                     try_span,
4688                     Some(vec![sym::try_trait].into()),
4689                 );
4690
4691                 // `Try::into_result(<expr>)`
4692                 let discr = {
4693                     // expand <expr>
4694                     let sub_expr = self.lower_expr(sub_expr);
4695
4696                     let path = &[sym::ops, sym::Try, sym::into_result];
4697                     P(self.expr_call_std_path(
4698                         unstable_span,
4699                         path,
4700                         hir_vec![sub_expr],
4701                     ))
4702                 };
4703
4704                 // `#[allow(unreachable_code)]`
4705                 let attr = {
4706                     // `allow(unreachable_code)`
4707                     let allow = {
4708                         let allow_ident = Ident::with_empty_ctxt(sym::allow).with_span_pos(e.span);
4709                         let uc_ident = Ident::with_empty_ctxt(sym::unreachable_code)
4710                             .with_span_pos(e.span);
4711                         let uc_nested = attr::mk_nested_word_item(uc_ident);
4712                         attr::mk_list_item(e.span, allow_ident, vec![uc_nested])
4713                     };
4714                     attr::mk_spanned_attr_outer(e.span, attr::mk_attr_id(), allow)
4715                 };
4716                 let attrs = vec![attr];
4717
4718                 // `Ok(val) => #[allow(unreachable_code)] val,`
4719                 let ok_arm = {
4720                     let val_ident = Ident::with_empty_ctxt(sym::val);
4721                     let (val_pat, val_pat_nid) = self.pat_ident(e.span, val_ident);
4722                     let val_expr = P(self.expr_ident_with_attrs(
4723                         e.span,
4724                         val_ident,
4725                         val_pat_nid,
4726                         ThinVec::from(attrs.clone()),
4727                     ));
4728                     let ok_pat = self.pat_ok(e.span, val_pat);
4729
4730                     self.arm(hir_vec![ok_pat], val_expr)
4731                 };
4732
4733                 // `Err(err) => #[allow(unreachable_code)]
4734                 //              return Try::from_error(From::from(err)),`
4735                 let err_arm = {
4736                     let err_ident = Ident::with_empty_ctxt(sym::err);
4737                     let (err_local, err_local_nid) = self.pat_ident(try_span, err_ident);
4738                     let from_expr = {
4739                         let from_path = &[sym::convert, sym::From, sym::from];
4740                         let err_expr = self.expr_ident(try_span, err_ident, err_local_nid);
4741                         self.expr_call_std_path(try_span, from_path, hir_vec![err_expr])
4742                     };
4743                     let from_err_expr =
4744                         self.wrap_in_try_constructor(sym::from_error, from_expr, unstable_span);
4745                     let thin_attrs = ThinVec::from(attrs);
4746                     let catch_scope = self.catch_scopes.last().map(|x| *x);
4747                     let ret_expr = if let Some(catch_node) = catch_scope {
4748                         let target_id = Ok(self.lower_node_id(catch_node));
4749                         P(self.expr(
4750                             try_span,
4751                             hir::ExprKind::Break(
4752                                 hir::Destination {
4753                                     label: None,
4754                                     target_id,
4755                                 },
4756                                 Some(from_err_expr),
4757                             ),
4758                             thin_attrs,
4759                         ))
4760                     } else {
4761                         P(self.expr(try_span, hir::ExprKind::Ret(Some(from_err_expr)), thin_attrs))
4762                     };
4763
4764                     let err_pat = self.pat_err(try_span, err_local);
4765                     self.arm(hir_vec![err_pat], ret_expr)
4766                 };
4767
4768                 hir::ExprKind::Match(
4769                     discr,
4770                     hir_vec![err_arm, ok_arm],
4771                     hir::MatchSource::TryDesugar,
4772                 )
4773             }
4774
4775             ExprKind::Mac(_) => panic!("Shouldn't exist here"),
4776         };
4777
4778         hir::Expr {
4779             hir_id: self.lower_node_id(e.id),
4780             node: kind,
4781             span: e.span,
4782             attrs: e.attrs.clone(),
4783         }
4784     }
4785
4786     fn lower_stmt(&mut self, s: &Stmt) -> SmallVec<[hir::Stmt; 1]> {
4787         smallvec![match s.node {
4788             StmtKind::Local(ref l) => {
4789                 let (l, item_ids) = self.lower_local(l);
4790                 let mut ids: SmallVec<[hir::Stmt; 1]> = item_ids
4791                     .into_iter()
4792                     .map(|item_id| {
4793                         let item_id = hir::ItemId { id: self.lower_node_id(item_id) };
4794                         self.stmt(s.span, hir::StmtKind::Item(item_id))
4795                     })
4796                     .collect();
4797                 ids.push({
4798                     hir::Stmt {
4799                         hir_id: self.lower_node_id(s.id),
4800                         node: hir::StmtKind::Local(P(l)),
4801                         span: s.span,
4802                     }
4803                 });
4804                 return ids;
4805             },
4806             StmtKind::Item(ref it) => {
4807                 // Can only use the ID once.
4808                 let mut id = Some(s.id);
4809                 return self.lower_item_id(it)
4810                     .into_iter()
4811                     .map(|item_id| {
4812                         let hir_id = id.take()
4813                           .map(|id| self.lower_node_id(id))
4814                           .unwrap_or_else(|| self.next_id());
4815
4816                         hir::Stmt {
4817                             hir_id,
4818                             node: hir::StmtKind::Item(item_id),
4819                             span: s.span,
4820                         }
4821                     })
4822                     .collect();
4823             }
4824             StmtKind::Expr(ref e) => {
4825                 hir::Stmt {
4826                     hir_id: self.lower_node_id(s.id),
4827                     node: hir::StmtKind::Expr(P(self.lower_expr(e))),
4828                     span: s.span,
4829                 }
4830             },
4831             StmtKind::Semi(ref e) => {
4832                 hir::Stmt {
4833                     hir_id: self.lower_node_id(s.id),
4834                     node: hir::StmtKind::Semi(P(self.lower_expr(e))),
4835                     span: s.span,
4836                 }
4837             },
4838             StmtKind::Mac(..) => panic!("Shouldn't exist here"),
4839         }]
4840     }
4841
4842     fn lower_capture_clause(&mut self, c: CaptureBy) -> hir::CaptureClause {
4843         match c {
4844             CaptureBy::Value => hir::CaptureByValue,
4845             CaptureBy::Ref => hir::CaptureByRef,
4846         }
4847     }
4848
4849     /// If an `explicit_owner` is given, this method allocates the `HirId` in
4850     /// the address space of that item instead of the item currently being
4851     /// lowered. This can happen during `lower_impl_item_ref()` where we need to
4852     /// lower a `Visibility` value although we haven't lowered the owning
4853     /// `ImplItem` in question yet.
4854     fn lower_visibility(
4855         &mut self,
4856         v: &Visibility,
4857         explicit_owner: Option<NodeId>,
4858     ) -> hir::Visibility {
4859         let node = match v.node {
4860             VisibilityKind::Public => hir::VisibilityKind::Public,
4861             VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
4862             VisibilityKind::Restricted { ref path, id } => {
4863                 debug!("lower_visibility: restricted path id = {:?}", id);
4864                 let lowered_id = if let Some(owner) = explicit_owner {
4865                     self.lower_node_id_with_owner(id, owner)
4866                 } else {
4867                     self.lower_node_id(id)
4868                 };
4869                 let res = self.expect_full_res(id);
4870                 let res = self.lower_res(res);
4871                 hir::VisibilityKind::Restricted {
4872                     path: P(self.lower_path_extra(
4873                         res,
4874                         path,
4875                         ParamMode::Explicit,
4876                         explicit_owner,
4877                     )),
4878                     hir_id: lowered_id,
4879                 }
4880             },
4881             VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
4882         };
4883         respan(v.span, node)
4884     }
4885
4886     fn lower_defaultness(&self, d: Defaultness, has_value: bool) -> hir::Defaultness {
4887         match d {
4888             Defaultness::Default => hir::Defaultness::Default {
4889                 has_value: has_value,
4890             },
4891             Defaultness::Final => {
4892                 assert!(has_value);
4893                 hir::Defaultness::Final
4894             }
4895         }
4896     }
4897
4898     fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode {
4899         match *b {
4900             BlockCheckMode::Default => hir::DefaultBlock,
4901             BlockCheckMode::Unsafe(u) => hir::UnsafeBlock(self.lower_unsafe_source(u)),
4902         }
4903     }
4904
4905     fn lower_binding_mode(&mut self, b: &BindingMode) -> hir::BindingAnnotation {
4906         match *b {
4907             BindingMode::ByValue(Mutability::Immutable) => hir::BindingAnnotation::Unannotated,
4908             BindingMode::ByRef(Mutability::Immutable) => hir::BindingAnnotation::Ref,
4909             BindingMode::ByValue(Mutability::Mutable) => hir::BindingAnnotation::Mutable,
4910             BindingMode::ByRef(Mutability::Mutable) => hir::BindingAnnotation::RefMut,
4911         }
4912     }
4913
4914     fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
4915         match u {
4916             CompilerGenerated => hir::CompilerGenerated,
4917             UserProvided => hir::UserProvided,
4918         }
4919     }
4920
4921     fn lower_impl_polarity(&mut self, i: ImplPolarity) -> hir::ImplPolarity {
4922         match i {
4923             ImplPolarity::Positive => hir::ImplPolarity::Positive,
4924             ImplPolarity::Negative => hir::ImplPolarity::Negative,
4925         }
4926     }
4927
4928     fn lower_trait_bound_modifier(&mut self, f: TraitBoundModifier) -> hir::TraitBoundModifier {
4929         match f {
4930             TraitBoundModifier::None => hir::TraitBoundModifier::None,
4931             TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe,
4932         }
4933     }
4934
4935     // Helper methods for building HIR.
4936
4937     fn arm(&mut self, pats: hir::HirVec<P<hir::Pat>>, expr: P<hir::Expr>) -> hir::Arm {
4938         hir::Arm {
4939             hir_id: self.next_id(),
4940             attrs: hir_vec![],
4941             pats,
4942             guard: None,
4943             span: expr.span,
4944             body: expr,
4945         }
4946     }
4947
4948     fn field(&mut self, ident: Ident, expr: P<hir::Expr>, span: Span) -> hir::Field {
4949         hir::Field {
4950             hir_id: self.next_id(),
4951             ident,
4952             span,
4953             expr,
4954             is_shorthand: false,
4955         }
4956     }
4957
4958     fn expr_break(&mut self, span: Span, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
4959         let expr_break = hir::ExprKind::Break(self.lower_loop_destination(None), None);
4960         P(self.expr(span, expr_break, attrs))
4961     }
4962
4963     fn expr_call(
4964         &mut self,
4965         span: Span,
4966         e: P<hir::Expr>,
4967         args: hir::HirVec<hir::Expr>,
4968     ) -> hir::Expr {
4969         self.expr(span, hir::ExprKind::Call(e, args), ThinVec::new())
4970     }
4971
4972     // Note: associated functions must use `expr_call_std_path`.
4973     fn expr_call_std_path(
4974         &mut self,
4975         span: Span,
4976         path_components: &[Symbol],
4977         args: hir::HirVec<hir::Expr>,
4978     ) -> hir::Expr {
4979         let path = P(self.expr_std_path(span, path_components, None, ThinVec::new()));
4980         self.expr_call(span, path, args)
4981     }
4982
4983     // Create an expression calling an associated function of an std type.
4984     //
4985     // Associated functions cannot be resolved through the normal `std_path` function,
4986     // as they are resolved differently and so cannot use `expr_call_std_path`.
4987     //
4988     // This function accepts the path component (`ty_path_components`) separately from
4989     // the name of the associated function (`assoc_fn_name`) in order to facilitate
4990     // separate resolution of the type and creation of a path referring to its associated
4991     // function.
4992     fn expr_call_std_assoc_fn(
4993         &mut self,
4994         ty_path_id: hir::HirId,
4995         span: Span,
4996         ty_path_components: &[Symbol],
4997         assoc_fn_name: &str,
4998         args: hir::HirVec<hir::Expr>,
4999     ) -> hir::ExprKind {
5000         let ty_path = P(self.std_path(span, ty_path_components, None, false));
5001         let ty = P(self.ty_path(ty_path_id, span, hir::QPath::Resolved(None, ty_path)));
5002         let fn_seg = P(hir::PathSegment::from_ident(Ident::from_str(assoc_fn_name)));
5003         let fn_path = hir::QPath::TypeRelative(ty, fn_seg);
5004         let fn_expr = P(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new()));
5005         hir::ExprKind::Call(fn_expr, args)
5006     }
5007
5008     fn expr_ident(&mut self, span: Span, ident: Ident, binding: hir::HirId) -> hir::Expr {
5009         self.expr_ident_with_attrs(span, ident, binding, ThinVec::new())
5010     }
5011
5012     fn expr_ident_with_attrs(
5013         &mut self,
5014         span: Span,
5015         ident: Ident,
5016         binding: hir::HirId,
5017         attrs: ThinVec<Attribute>,
5018     ) -> hir::Expr {
5019         let expr_path = hir::ExprKind::Path(hir::QPath::Resolved(
5020             None,
5021             P(hir::Path {
5022                 span,
5023                 res: Res::Local(binding),
5024                 segments: hir_vec![hir::PathSegment::from_ident(ident)],
5025             }),
5026         ));
5027
5028         self.expr(span, expr_path, attrs)
5029     }
5030
5031     fn expr_mut_addr_of(&mut self, span: Span, e: P<hir::Expr>) -> hir::Expr {
5032         self.expr(span, hir::ExprKind::AddrOf(hir::MutMutable, e), ThinVec::new())
5033     }
5034
5035     fn expr_std_path(
5036         &mut self,
5037         span: Span,
5038         components: &[Symbol],
5039         params: Option<P<hir::GenericArgs>>,
5040         attrs: ThinVec<Attribute>,
5041     ) -> hir::Expr {
5042         let path = self.std_path(span, components, params, true);
5043         self.expr(
5044             span,
5045             hir::ExprKind::Path(hir::QPath::Resolved(None, P(path))),
5046             attrs,
5047         )
5048     }
5049
5050     /// Wrap the given `expr` in a terminating scope using `hir::ExprKind::DropTemps`.
5051     ///
5052     /// In terms of drop order, it has the same effect as wrapping `expr` in
5053     /// `{ let _t = $expr; _t }` but should provide better compile-time performance.
5054     ///
5055     /// The drop order can be important in e.g. `if expr { .. }`.
5056     fn expr_drop_temps(
5057         &mut self,
5058         span: Span,
5059         expr: P<hir::Expr>,
5060         attrs: ThinVec<Attribute>
5061     ) -> hir::Expr {
5062         self.expr(span, hir::ExprKind::DropTemps(expr), attrs)
5063     }
5064
5065     fn expr_match(
5066         &mut self,
5067         span: Span,
5068         arg: P<hir::Expr>,
5069         arms: hir::HirVec<hir::Arm>,
5070         source: hir::MatchSource,
5071     ) -> hir::Expr {
5072         self.expr(span, hir::ExprKind::Match(arg, arms, source), ThinVec::new())
5073     }
5074
5075     fn expr_block(&mut self, b: P<hir::Block>, attrs: ThinVec<Attribute>) -> hir::Expr {
5076         self.expr(b.span, hir::ExprKind::Block(b, None), attrs)
5077     }
5078
5079     fn expr_unit(&mut self, sp: Span) -> hir::Expr {
5080         self.expr_tuple(sp, hir_vec![])
5081     }
5082
5083     fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec<hir::Expr>) -> hir::Expr {
5084         self.expr(sp, hir::ExprKind::Tup(exprs), ThinVec::new())
5085     }
5086
5087     fn expr(&mut self, span: Span, node: hir::ExprKind, attrs: ThinVec<Attribute>) -> hir::Expr {
5088         hir::Expr {
5089             hir_id: self.next_id(),
5090             node,
5091             span,
5092             attrs,
5093         }
5094     }
5095
5096     fn stmt(&mut self, span: Span, node: hir::StmtKind) -> hir::Stmt {
5097         hir::Stmt { span, node, hir_id: self.next_id() }
5098     }
5099
5100     fn stmt_let_pat(
5101         &mut self,
5102         span: Span,
5103         init: Option<P<hir::Expr>>,
5104         pat: P<hir::Pat>,
5105         source: hir::LocalSource,
5106     ) -> hir::Stmt {
5107         let local = hir::Local {
5108             pat,
5109             ty: None,
5110             init,
5111             hir_id: self.next_id(),
5112             span,
5113             source,
5114             attrs: ThinVec::new()
5115         };
5116         self.stmt(span, hir::StmtKind::Local(P(local)))
5117     }
5118
5119     fn expr_block_empty(&mut self, span: Span) -> hir::Expr {
5120         let blk = self.block_all(span, hir_vec![], None);
5121         self.expr_block(P(blk), ThinVec::new())
5122     }
5123
5124     fn block_expr(&mut self, expr: P<hir::Expr>) -> hir::Block {
5125         self.block_all(expr.span, hir::HirVec::new(), Some(expr))
5126     }
5127
5128     fn block_all(
5129         &mut self,
5130         span: Span,
5131         stmts: hir::HirVec<hir::Stmt>,
5132         expr: Option<P<hir::Expr>>,
5133     ) -> hir::Block {
5134         hir::Block {
5135             stmts,
5136             expr,
5137             hir_id: self.next_id(),
5138             rules: hir::DefaultBlock,
5139             span,
5140             targeted_by_break: false,
5141         }
5142     }
5143
5144     fn expr_unsafe(&mut self, expr: P<hir::Expr>) -> hir::Expr {
5145         let hir_id = self.next_id();
5146         let span = expr.span;
5147         self.expr(
5148             span,
5149             hir::ExprKind::Block(P(hir::Block {
5150                 stmts: hir_vec![],
5151                 expr: Some(expr),
5152                 hir_id,
5153                 rules: hir::UnsafeBlock(hir::CompilerGenerated),
5154                 span,
5155                 targeted_by_break: false,
5156             }), None),
5157             ThinVec::new(),
5158         )
5159     }
5160
5161     /// Constructs a `true` or `false` literal pattern.
5162     fn pat_bool(&mut self, span: Span, val: bool) -> P<hir::Pat> {
5163         let lit = Spanned { span, node: LitKind::Bool(val) };
5164         let expr = self.expr(span, hir::ExprKind::Lit(lit), ThinVec::new());
5165         self.pat(span, hir::PatKind::Lit(P(expr)))
5166     }
5167
5168     fn pat_ok(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
5169         self.pat_std_enum(span, &[sym::result, sym::Result, sym::Ok], hir_vec![pat])
5170     }
5171
5172     fn pat_err(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
5173         self.pat_std_enum(span, &[sym::result, sym::Result, sym::Err], hir_vec![pat])
5174     }
5175
5176     fn pat_some(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
5177         self.pat_std_enum(span, &[sym::option, sym::Option, sym::Some], hir_vec![pat])
5178     }
5179
5180     fn pat_none(&mut self, span: Span) -> P<hir::Pat> {
5181         self.pat_std_enum(span, &[sym::option, sym::Option, sym::None], hir_vec![])
5182     }
5183
5184     fn pat_std_enum(
5185         &mut self,
5186         span: Span,
5187         components: &[Symbol],
5188         subpats: hir::HirVec<P<hir::Pat>>,
5189     ) -> P<hir::Pat> {
5190         let path = self.std_path(span, components, None, true);
5191         let qpath = hir::QPath::Resolved(None, P(path));
5192         let pt = if subpats.is_empty() {
5193             hir::PatKind::Path(qpath)
5194         } else {
5195             hir::PatKind::TupleStruct(qpath, subpats, None)
5196         };
5197         self.pat(span, pt)
5198     }
5199
5200     fn pat_ident(&mut self, span: Span, ident: Ident) -> (P<hir::Pat>, hir::HirId) {
5201         self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::Unannotated)
5202     }
5203
5204     fn pat_ident_binding_mode(
5205         &mut self,
5206         span: Span,
5207         ident: Ident,
5208         bm: hir::BindingAnnotation,
5209     ) -> (P<hir::Pat>, hir::HirId) {
5210         let hir_id = self.next_id();
5211
5212         (
5213             P(hir::Pat {
5214                 hir_id,
5215                 node: hir::PatKind::Binding(bm, hir_id, ident.with_span_pos(span), None),
5216                 span,
5217             }),
5218             hir_id
5219         )
5220     }
5221
5222     fn pat_wild(&mut self, span: Span) -> P<hir::Pat> {
5223         self.pat(span, hir::PatKind::Wild)
5224     }
5225
5226     fn pat(&mut self, span: Span, pat: hir::PatKind) -> P<hir::Pat> {
5227         P(hir::Pat {
5228             hir_id: self.next_id(),
5229             node: pat,
5230             span,
5231         })
5232     }
5233
5234     /// Given suffix ["b","c","d"], returns path `::std::b::c::d` when
5235     /// `fld.cx.use_std`, and `::core::b::c::d` otherwise.
5236     /// The path is also resolved according to `is_value`.
5237     fn std_path(
5238         &mut self,
5239         span: Span,
5240         components: &[Symbol],
5241         params: Option<P<hir::GenericArgs>>,
5242         is_value: bool,
5243     ) -> hir::Path {
5244         let mut path = self.resolver
5245             .resolve_str_path(span, self.crate_root, components, is_value);
5246         path.segments.last_mut().unwrap().args = params;
5247
5248         for seg in path.segments.iter_mut() {
5249             if seg.hir_id.is_some() {
5250                 seg.hir_id = Some(self.next_id());
5251             }
5252         }
5253         path
5254     }
5255
5256     fn ty_path(&mut self, mut hir_id: hir::HirId, span: Span, qpath: hir::QPath) -> hir::Ty {
5257         let node = match qpath {
5258             hir::QPath::Resolved(None, path) => {
5259                 // Turn trait object paths into `TyKind::TraitObject` instead.
5260                 match path.res {
5261                     Res::Def(DefKind::Trait, _) | Res::Def(DefKind::TraitAlias, _) => {
5262                         let principal = hir::PolyTraitRef {
5263                             bound_generic_params: hir::HirVec::new(),
5264                             trait_ref: hir::TraitRef {
5265                                 path: path.and_then(|path| path),
5266                                 hir_ref_id: hir_id,
5267                             },
5268                             span,
5269                         };
5270
5271                         // The original ID is taken by the `PolyTraitRef`,
5272                         // so the `Ty` itself needs a different one.
5273                         hir_id = self.next_id();
5274                         hir::TyKind::TraitObject(hir_vec![principal], self.elided_dyn_bound(span))
5275                     }
5276                     _ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
5277                 }
5278             }
5279             _ => hir::TyKind::Path(qpath),
5280         };
5281         hir::Ty {
5282             hir_id,
5283             node,
5284             span,
5285         }
5286     }
5287
5288     /// Invoked to create the lifetime argument for a type `&T`
5289     /// with no explicit lifetime.
5290     fn elided_ref_lifetime(&mut self, span: Span) -> hir::Lifetime {
5291         match self.anonymous_lifetime_mode {
5292             // Intercept when we are in an impl header or async fn and introduce an in-band
5293             // lifetime.
5294             // Hence `impl Foo for &u32` becomes `impl<'f> Foo for &'f u32` for some fresh
5295             // `'f`.
5296             AnonymousLifetimeMode::CreateParameter => {
5297                 let fresh_name = self.collect_fresh_in_band_lifetime(span);
5298                 hir::Lifetime {
5299                     hir_id: self.next_id(),
5300                     span,
5301                     name: hir::LifetimeName::Param(fresh_name),
5302                 }
5303             }
5304
5305             AnonymousLifetimeMode::ReportError => self.new_error_lifetime(None, span),
5306
5307             AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span),
5308
5309             AnonymousLifetimeMode::Replace(replacement) => {
5310                 self.new_replacement_lifetime(replacement, span)
5311             }
5312         }
5313     }
5314
5315     /// Report an error on illegal use of `'_` or a `&T` with no explicit lifetime;
5316     /// return a "error lifetime".
5317     fn new_error_lifetime(&mut self, id: Option<NodeId>, span: Span) -> hir::Lifetime {
5318         let (id, msg, label) = match id {
5319             Some(id) => (id, "`'_` cannot be used here", "`'_` is a reserved lifetime name"),
5320
5321             None => (
5322                 self.sess.next_node_id(),
5323                 "`&` without an explicit lifetime name cannot be used here",
5324                 "explicit lifetime name needed here",
5325             ),
5326         };
5327
5328         let mut err = struct_span_err!(
5329             self.sess,
5330             span,
5331             E0637,
5332             "{}",
5333             msg,
5334         );
5335         err.span_label(span, label);
5336         err.emit();
5337
5338         self.new_named_lifetime(id, span, hir::LifetimeName::Error)
5339     }
5340
5341     /// Invoked to create the lifetime argument(s) for a path like
5342     /// `std::cell::Ref<T>`; note that implicit lifetimes in these
5343     /// sorts of cases are deprecated. This may therefore report a warning or an
5344     /// error, depending on the mode.
5345     fn elided_path_lifetimes(&mut self, span: Span, count: usize) -> P<[hir::Lifetime]> {
5346         (0..count)
5347             .map(|_| self.elided_path_lifetime(span))
5348             .collect()
5349     }
5350
5351     fn elided_path_lifetime(&mut self, span: Span) -> hir::Lifetime {
5352         match self.anonymous_lifetime_mode {
5353             AnonymousLifetimeMode::CreateParameter => {
5354                 // We should have emitted E0726 when processing this path above
5355                 self.sess.delay_span_bug(
5356                     span,
5357                     "expected 'implicit elided lifetime not allowed' error",
5358                 );
5359                 let id = self.sess.next_node_id();
5360                 self.new_named_lifetime(id, span, hir::LifetimeName::Error)
5361             }
5362             // This is the normal case.
5363             AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span),
5364
5365             AnonymousLifetimeMode::Replace(replacement) => {
5366                 self.new_replacement_lifetime(replacement, span)
5367             }
5368
5369             AnonymousLifetimeMode::ReportError => self.new_error_lifetime(None, span),
5370         }
5371     }
5372
5373     /// Invoked to create the lifetime argument(s) for an elided trait object
5374     /// bound, like the bound in `Box<dyn Debug>`. This method is not invoked
5375     /// when the bound is written, even if it is written with `'_` like in
5376     /// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked.
5377     fn elided_dyn_bound(&mut self, span: Span) -> hir::Lifetime {
5378         match self.anonymous_lifetime_mode {
5379             // NB. We intentionally ignore the create-parameter mode here.
5380             // and instead "pass through" to resolve-lifetimes, which will apply
5381             // the object-lifetime-defaulting rules. Elided object lifetime defaults
5382             // do not act like other elided lifetimes. In other words, given this:
5383             //
5384             //     impl Foo for Box<dyn Debug>
5385             //
5386             // we do not introduce a fresh `'_` to serve as the bound, but instead
5387             // ultimately translate to the equivalent of:
5388             //
5389             //     impl Foo for Box<dyn Debug + 'static>
5390             //
5391             // `resolve_lifetime` has the code to make that happen.
5392             AnonymousLifetimeMode::CreateParameter => {}
5393
5394             AnonymousLifetimeMode::ReportError => {
5395                 // ReportError applies to explicit use of `'_`.
5396             }
5397
5398             // This is the normal case.
5399             AnonymousLifetimeMode::PassThrough => {}
5400
5401             // We don't need to do any replacement here as this lifetime
5402             // doesn't refer to an elided lifetime elsewhere in the function
5403             // signature.
5404             AnonymousLifetimeMode::Replace(_) => {}
5405         }
5406
5407         self.new_implicit_lifetime(span)
5408     }
5409
5410     fn new_replacement_lifetime(
5411         &mut self,
5412         replacement: LtReplacement,
5413         span: Span,
5414     ) -> hir::Lifetime {
5415         let hir_id = self.next_id();
5416         self.replace_elided_lifetime(hir_id, span, replacement)
5417     }
5418
5419     fn new_implicit_lifetime(&mut self, span: Span) -> hir::Lifetime {
5420         hir::Lifetime {
5421             hir_id: self.next_id(),
5422             span,
5423             name: hir::LifetimeName::Implicit,
5424         }
5425     }
5426
5427     fn maybe_lint_bare_trait(&self, span: Span, id: NodeId, is_global: bool) {
5428         self.sess.buffer_lint_with_diagnostic(
5429             builtin::BARE_TRAIT_OBJECTS,
5430             id,
5431             span,
5432             "trait objects without an explicit `dyn` are deprecated",
5433             builtin::BuiltinLintDiagnostics::BareTraitObject(span, is_global),
5434         )
5435     }
5436
5437     fn wrap_in_try_constructor(
5438         &mut self,
5439         method: Symbol,
5440         e: hir::Expr,
5441         unstable_span: Span,
5442     ) -> P<hir::Expr> {
5443         let path = &[sym::ops, sym::Try, method];
5444         let from_err = P(self.expr_std_path(unstable_span, path, None,
5445                                             ThinVec::new()));
5446         P(self.expr_call(e.span, from_err, hir_vec![e]))
5447     }
5448
5449     fn lower_await(
5450         &mut self,
5451         await_span: Span,
5452         expr: &ast::Expr,
5453     ) -> hir::ExprKind {
5454         // to:
5455         //
5456         // {
5457         //     let mut pinned = <expr>;
5458         //     loop {
5459         //         match ::std::future::poll_with_tls_context(unsafe {
5460         //             ::std::pin::Pin::new_unchecked(&mut pinned)
5461         //         }) {
5462         //             ::std::task::Poll::Ready(result) => break result,
5463         //             ::std::task::Poll::Pending => {},
5464         //         }
5465         //         yield ();
5466         //     }
5467         // }
5468         if !self.is_async_body {
5469             let mut err = struct_span_err!(
5470                 self.sess,
5471                 await_span,
5472                 E0728,
5473                 "`await` is only allowed inside `async` functions and blocks"
5474             );
5475             err.span_label(await_span, "only allowed inside `async` functions and blocks");
5476             if let Some(item_sp) = self.current_item {
5477                 err.span_label(item_sp, "this is not `async`");
5478             }
5479             err.emit();
5480             return hir::ExprKind::Err;
5481         }
5482         let span = self.mark_span_with_reason(
5483             CompilerDesugaringKind::Await,
5484             await_span,
5485             None,
5486         );
5487         let gen_future_span = self.mark_span_with_reason(
5488             CompilerDesugaringKind::Await,
5489             await_span,
5490             Some(vec![sym::gen_future].into()),
5491         );
5492
5493         // let mut pinned = <expr>;
5494         let expr = P(self.lower_expr(expr));
5495         let pinned_ident = Ident::with_empty_ctxt(sym::pinned);
5496         let (pinned_pat, pinned_pat_hid) = self.pat_ident_binding_mode(
5497             span,
5498             pinned_ident,
5499             hir::BindingAnnotation::Mutable,
5500         );
5501         let pinned_let = self.stmt_let_pat(
5502             span,
5503             Some(expr),
5504             pinned_pat,
5505             hir::LocalSource::AwaitDesugar,
5506         );
5507
5508         // ::std::future::poll_with_tls_context(unsafe {
5509         //     ::std::pin::Pin::new_unchecked(&mut pinned)
5510         // })`
5511         let poll_expr = {
5512             let pinned = P(self.expr_ident(span, pinned_ident, pinned_pat_hid));
5513             let ref_mut_pinned = self.expr_mut_addr_of(span, pinned);
5514             let pin_ty_id = self.next_id();
5515             let new_unchecked_expr_kind = self.expr_call_std_assoc_fn(
5516                 pin_ty_id,
5517                 span,
5518                 &[sym::pin, sym::Pin],
5519                 "new_unchecked",
5520                 hir_vec![ref_mut_pinned],
5521             );
5522             let new_unchecked = P(self.expr(span, new_unchecked_expr_kind, ThinVec::new()));
5523             let unsafe_expr = self.expr_unsafe(new_unchecked);
5524             P(self.expr_call_std_path(
5525                 gen_future_span,
5526                 &[sym::future, sym::poll_with_tls_context],
5527                 hir_vec![unsafe_expr],
5528             ))
5529         };
5530
5531         // `::std::task::Poll::Ready(result) => break result`
5532         let loop_node_id = self.sess.next_node_id();
5533         let loop_hir_id = self.lower_node_id(loop_node_id);
5534         let ready_arm = {
5535             let x_ident = Ident::with_empty_ctxt(sym::result);
5536             let (x_pat, x_pat_hid) = self.pat_ident(span, x_ident);
5537             let x_expr = P(self.expr_ident(span, x_ident, x_pat_hid));
5538             let ready_pat = self.pat_std_enum(
5539                 span,
5540                 &[sym::task, sym::Poll, sym::Ready],
5541                 hir_vec![x_pat],
5542             );
5543             let break_x = self.with_loop_scope(loop_node_id, |this| {
5544                 let expr_break = hir::ExprKind::Break(
5545                     this.lower_loop_destination(None),
5546                     Some(x_expr),
5547                 );
5548                 P(this.expr(await_span, expr_break, ThinVec::new()))
5549             });
5550             self.arm(hir_vec![ready_pat], break_x)
5551         };
5552
5553         // `::std::task::Poll::Pending => {}`
5554         let pending_arm = {
5555             let pending_pat = self.pat_std_enum(
5556                 span,
5557                 &[sym::task, sym::Poll, sym::Pending],
5558                 hir_vec![],
5559             );
5560             let empty_block = P(self.expr_block_empty(span));
5561             self.arm(hir_vec![pending_pat], empty_block)
5562         };
5563
5564         let match_stmt = {
5565             let match_expr = P(self.expr_match(
5566                 span,
5567                 poll_expr,
5568                 hir_vec![ready_arm, pending_arm],
5569                 hir::MatchSource::AwaitDesugar,
5570             ));
5571             self.stmt(span, hir::StmtKind::Expr(match_expr))
5572         };
5573
5574         let yield_stmt = {
5575             let unit = self.expr_unit(span);
5576             let yield_expr = P(self.expr(
5577                 span,
5578                 hir::ExprKind::Yield(P(unit)),
5579                 ThinVec::new(),
5580             ));
5581             self.stmt(span, hir::StmtKind::Expr(yield_expr))
5582         };
5583
5584         let loop_block = P(self.block_all(
5585             span,
5586             hir_vec![match_stmt, yield_stmt],
5587             None,
5588         ));
5589
5590         let loop_expr = P(hir::Expr {
5591             hir_id: loop_hir_id,
5592             node: hir::ExprKind::Loop(
5593                 loop_block,
5594                 None,
5595                 hir::LoopSource::Loop,
5596             ),
5597             span,
5598             attrs: ThinVec::new(),
5599         });
5600
5601         hir::ExprKind::Block(
5602             P(self.block_all(span, hir_vec![pinned_let], Some(loop_expr))),
5603             None,
5604         )
5605     }
5606 }
5607
5608 fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body>) -> Vec<hir::BodyId> {
5609     // Sorting by span ensures that we get things in order within a
5610     // file, and also puts the files in a sensible order.
5611     let mut body_ids: Vec<_> = bodies.keys().cloned().collect();
5612     body_ids.sort_by_key(|b| bodies[b].value.span);
5613     body_ids
5614 }
5615
5616 /// Checks if the specified expression is a built-in range literal.
5617 /// (See: `LoweringContext::lower_expr()`).
5618 pub fn is_range_literal(sess: &Session, expr: &hir::Expr) -> bool {
5619     use hir::{Path, QPath, ExprKind, TyKind};
5620
5621     // Returns whether the given path represents a (desugared) range,
5622     // either in std or core, i.e. has either a `::std::ops::Range` or
5623     // `::core::ops::Range` prefix.
5624     fn is_range_path(path: &Path) -> bool {
5625         let segs: Vec<_> = path.segments.iter().map(|seg| seg.ident.as_str().to_string()).collect();
5626         let segs: Vec<_> = segs.iter().map(|seg| &**seg).collect();
5627
5628         // "{{root}}" is the equivalent of `::` prefix in `Path`.
5629         if let ["{{root}}", std_core, "ops", range] = segs.as_slice() {
5630             (*std_core == "std" || *std_core == "core") && range.starts_with("Range")
5631         } else {
5632             false
5633         }
5634     };
5635
5636     // Check whether a span corresponding to a range expression is a
5637     // range literal, rather than an explicit struct or `new()` call.
5638     fn is_lit(sess: &Session, span: &Span) -> bool {
5639         let source_map = sess.source_map();
5640         let end_point = source_map.end_point(*span);
5641
5642         if let Ok(end_string) = source_map.span_to_snippet(end_point) {
5643             !(end_string.ends_with("}") || end_string.ends_with(")"))
5644         } else {
5645             false
5646         }
5647     };
5648
5649     match expr.node {
5650         // All built-in range literals but `..=` and `..` desugar to `Struct`s.
5651         ExprKind::Struct(ref qpath, _, _) => {
5652             if let QPath::Resolved(None, ref path) = **qpath {
5653                 return is_range_path(&path) && is_lit(sess, &expr.span);
5654             }
5655         }
5656
5657         // `..` desugars to its struct path.
5658         ExprKind::Path(QPath::Resolved(None, ref path)) => {
5659             return is_range_path(&path) && is_lit(sess, &expr.span);
5660         }
5661
5662         // `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
5663         ExprKind::Call(ref func, _) => {
5664             if let ExprKind::Path(QPath::TypeRelative(ref ty, ref segment)) = func.node {
5665                 if let TyKind::Path(QPath::Resolved(None, ref path)) = ty.node {
5666                     let new_call = segment.ident.as_str() == "new";
5667                     return is_range_path(&path) && is_lit(sess, &expr.span) && new_call;
5668                 }
5669             }
5670         }
5671
5672         _ => {}
5673     }
5674
5675     false
5676 }