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