lib.rs 114.6 KB
Newer Older
1 2 3 4 5
//! Lowers the AST to the HIR.
//!
//! Since the AST and HIR are fairly similar, this is mostly a simple procedure,
//! much like a fold. Where lowering involves a bit more work things get more
//! interesting and there are some invariants you should know about. These mostly
A
Alexander Regueiro 已提交
6
//! concern spans and IDs.
7 8 9
//!
//! Spans are assigned to AST nodes during parsing and then are modified during
//! expansion to indicate the origin of a node and the process it went through
A
Alexander Regueiro 已提交
10
//! being expanded. IDs are assigned to AST nodes just before lowering.
11
//!
A
Alexander Regueiro 已提交
12
//! For the simpler lowering steps, IDs and spans should be preserved. Unlike
13 14
//! expansion we do not preserve the process of lowering in the spans, so spans
//! should not be modified here. When creating a new node (as opposed to
P
pierwill 已提交
15
//! "folding" an existing one), create a new ID using `next_id()`.
16
//!
A
Alexander Regueiro 已提交
17
//! You must ensure that IDs are unique. That means that you should only use the
18
//! ID from an AST node in a single HIR node (you can assume that AST node-IDs
A
Alexander Regueiro 已提交
19 20
//! are unique). Every new node must have a unique ID. Avoid cloning HIR nodes.
//! If you do, you must then set the new node's ID to a fresh one.
21 22
//!
//! Spans are used for error messages and for tools to map semantics back to
A
Alexander Regueiro 已提交
23
//! source code. It is therefore not as important with spans as IDs to be strict
24 25 26 27 28
//! about use (you can't break the compiler by screwing up a span). Obviously, a
//! HIR node can only have a single span. But multiple nodes can have the same
//! span and spans don't need to be kept in order, etc. Where code is preserved
//! by lowering, it should have the same span as in the AST. Where HIR nodes are
//! new it is probably best to give a span for the whole AST node being lowered.
P
pierwill 已提交
29
//! All nodes should have real spans; don't use dummy spans. Tools are likely to
30 31
//! get confused if the spans from leaf AST nodes occur in multiple places
//! in the HIR, especially for multiple identifiers.
32

33
#![feature(crate_visibility_modifier)]
M
mark 已提交
34
#![cfg_attr(bootstrap, feature(or_patterns))]
35
#![feature(box_patterns)]
J
Josh Stone 已提交
36
#![feature(iter_zip)]
37
#![recursion_limit = "256"]
38

39
use rustc_ast::node_id::NodeMap;
40
use rustc_ast::token::{self, DelimToken, Nonterminal, Token};
41
use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, DelimSpan, TokenStream, TokenTree};
42 43
use rustc_ast::visit::{self, AssocCtxt, Visitor};
use rustc_ast::walk_list;
U
Ujjwal Sharma 已提交
44
use rustc_ast::{self as ast, *};
45
use rustc_ast_pretty::pprust;
46
use rustc_data_structures::captures::Captures;
T
Taiki Endo 已提交
47
use rustc_data_structures::fx::FxHashSet;
48
use rustc_data_structures::sync::Lrc;
49
use rustc_errors::struct_span_err;
50 51
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
52
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, CRATE_DEF_ID};
53
use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
54
use rustc_hir::intravisit;
55
use rustc_hir::{ConstArg, GenericArg, ParamName};
56
use rustc_index::vec::{Idx, IndexVec};
57 58
use rustc_session::lint::builtin::{BARE_TRAIT_OBJECTS, MISSING_ABI};
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
M
Mazdak Farrokhzad 已提交
59
use rustc_session::parse::ParseSess;
60
use rustc_session::Session;
61
use rustc_span::hygiene::ExpnId;
62
use rustc_span::source_map::{respan, DesugaringKind};
63
use rustc_span::symbol::{kw, sym, Ident, Symbol};
64
use rustc_span::Span;
65
use rustc_target::spec::abi::Abi;
66

67 68 69
use smallvec::{smallvec, SmallVec};
use std::collections::BTreeMap;
use std::mem;
B
bishtpawan 已提交
70
use tracing::{debug, trace};
71

C
Camille GILLOT 已提交
72
macro_rules! arena_vec {
C
Camille GILLOT 已提交
73 74 75 76
    ($this:expr; $($x:expr),*) => ({
        let a = [$($x),*];
        $this.arena.alloc_from_iter(std::array::IntoIter::new(a))
    });
C
Camille GILLOT 已提交
77 78 79 80
}

mod expr;
mod item;
81
mod pat;
82
mod path;
C
Camille GILLOT 已提交
83

84 85
const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF;

86
rustc_hir::arena_types!(rustc_arena::declare_arena, [], 'tcx);
87

88
struct LoweringContext<'a, 'hir: 'a> {
89
    /// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.
90
    sess: &'a Session,
B
bjorn3 已提交
91

92
    resolver: &'a mut dyn ResolverAstLowering,
93

94 95
    /// HACK(Centril): there is a cyclic dependency between the parser and lowering
    /// if we don't have this function pointer. To avoid that dependency so that
M
Mazdak Farrokhzad 已提交
96
    /// librustc_middle is independent of the parser, we use dynamic dispatch here.
97
    nt_to_tokenstream: NtToTokenstream,
98

P
pierwill 已提交
99
    /// Used to allocate HIR nodes.
C
Camille GILLOT 已提交
100 101
    arena: &'hir Arena<'hir>,

102
    /// The items being lowered are collected here.
103
    items: BTreeMap<hir::ItemId, hir::Item<'hir>>,
104

C
Camille GILLOT 已提交
105
    trait_items: BTreeMap<hir::TraitItemId, hir::TraitItem<'hir>>,
C
Camille GILLOT 已提交
106
    impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem<'hir>>,
107
    foreign_items: BTreeMap<hir::ForeignItemId, hir::ForeignItem<'hir>>,
C
Camille GILLOT 已提交
108
    bodies: BTreeMap<hir::BodyId, hir::Body<'hir>>,
C
Camille GILLOT 已提交
109
    exported_macros: Vec<hir::MacroDef<'hir>>,
110
    non_exported_macro_attrs: Vec<ast::Attribute>,
111

112
    trait_impls: BTreeMap<DefId, Vec<LocalDefId>>,
113

114
    modules: BTreeMap<LocalDefId, hir::ModuleItems>,
115

116
    generator_kind: Option<hir::GeneratorKind>,
J
John Kåre Alsaker 已提交
117

118
    attrs: BTreeMap<hir::HirId, &'hir [Attribute]>,
119

120 121 122 123
    /// When inside an `async` context, this is the `HirId` of the
    /// `task_context` local bound to the resume argument of the generator.
    task_context: Option<hir::HirId>,

124 125
    /// Used to get the current `fn`'s def span to point to when using `await`
    /// outside of an `async fn`.
126
    current_item: Option<Span>,
127

128
    catch_scopes: Vec<NodeId>,
129
    loop_scopes: Vec<NodeId>,
130
    is_in_loop_condition: bool,
131
    is_in_trait_impl: bool,
132
    is_in_dyn_type: bool,
133

P
pierwill 已提交
134
    /// What to do when we encounter an "anonymous lifetime
135 136 137 138 139
    /// reference". The term "anonymous" is meant to encompass both
    /// `'_` lifetimes as well as fully elided cases where nothing is
    /// written at all (e.g., `&T` or `std::cell::Ref<T>`).
    anonymous_lifetime_mode: AnonymousLifetimeMode,

140 141 142 143 144 145 146
    /// Used to create lifetime definitions from in-band lifetime usages.
    /// e.g., `fn foo(x: &'x u8) -> &'x u8` to `fn foo<'x>(x: &'x u8) -> &'x u8`
    /// When a named lifetime is encountered in a function or impl header and
    /// has not been defined
    /// (i.e., it doesn't appear in the in_scope_lifetimes list), it is added
    /// to this list. The results of this list are then added to the list of
    /// lifetime definitions in the corresponding impl or function generics.
147
    lifetimes_to_define: Vec<(Span, ParamName)>,
148

149
    /// `true` if in-band lifetimes are being collected. This is used to
150 151 152
    /// indicate whether or not we're in a place where new lifetimes will result
    /// in in-band lifetime definitions, such a function or an impl header,
    /// including implicit lifetimes from `impl_header_lifetime_elision`.
153
    is_collecting_in_band_lifetimes: bool,
154

155
    /// Currently in-scope lifetimes defined in impl headers, fn headers, or HRTB.
D
Dániel Buga 已提交
156
    /// When `is_collecting_in_band_lifetimes` is true, each lifetime is checked
157 158
    /// against this list to see if it is already in-scope, or if a definition
    /// needs to be created for it.
N
Niko Matsakis 已提交
159
    ///
160
    /// We always store a `normalize_to_macros_2_0()` version of the param-name in this
N
Niko Matsakis 已提交
161
    /// vector.
162
    in_scope_lifetimes: Vec<ParamName>,
163

164
    current_module: LocalDefId,
165

166
    type_def_lifetime_params: DefIdMap<usize>,
167

168
    current_hir_id_owner: Vec<(LocalDefId, u32)>,
169
    item_local_id_counters: NodeMap<u32>,
170
    node_id_to_hir_id: IndexVec<NodeId, Option<hir::HirId>>,
171 172 173

    allow_try_trait: Option<Lrc<[Symbol]>>,
    allow_gen_future: Option<Lrc<[Symbol]>>,
174 175
}

176
pub trait ResolverAstLowering {
177 178
    fn def_key(&mut self, id: DefId) -> DefKey;

179
    fn item_generics_num_lifetimes(&self, def: DefId, sess: &Session) -> usize;
180

181
    fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option<Vec<usize>>;
182

183
    /// Obtains resolution for a `NodeId` with a single resolution.
184
    fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes>;
185

186
    /// Obtains per-namespace resolutions for `use` statement with the given `NodeId`.
187
    fn get_import_res(&mut self, id: NodeId) -> PerNS<Option<Res<NodeId>>>;
188

189
    /// Obtains resolution for a label with the given `NodeId`.
V
Vadim Petrochenkov 已提交
190
    fn get_label_res(&mut self, id: NodeId) -> Option<NodeId>;
191

192 193
    /// We must keep the set of definitions up to date as we add nodes that weren't in the AST.
    /// This should only return `None` during testing.
194
    fn definitions(&mut self) -> &mut Definitions;
M
Manish Goregaokar 已提交
195

196
    fn lint_buffer(&mut self) -> &mut LintBuffer;
M
Mark Rousskov 已提交
197 198

    fn next_node_id(&mut self) -> NodeId;
M
marmeladema 已提交
199 200

    fn trait_map(&self) -> &NodeMap<Vec<hir::TraitCandidate>>;
201 202 203 204 205

    fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId>;

    fn local_def_id(&self, node: NodeId) -> LocalDefId;

206
    fn create_def(
207 208 209 210 211 212 213
        &mut self,
        parent: LocalDefId,
        node_id: ast::NodeId,
        data: DefPathData,
        expn_id: ExpnId,
        span: Span,
    ) -> LocalDefId;
N
Nick Cameron 已提交
214 215
}

216
type NtToTokenstream = fn(&Nonterminal, &ParseSess, CanSynthesizeMissingTokens) -> TokenStream;
217

218 219
/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
/// and if so, what meaning it has.
220
#[derive(Debug)]
C
Camille GILLOT 已提交
221
enum ImplTraitContext<'b, 'a> {
222 223 224
    /// Treat `impl Trait` as shorthand for a new universal generic parameter.
    /// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually
    /// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.
225
    ///
226
    /// Newly generated parameters should be inserted into the given `Vec`.
227
    Universal(&'b mut Vec<hir::GenericParam<'a>>, LocalDefId),
228

V
varkor 已提交
229
    /// Treat `impl Trait` as shorthand for a new opaque type.
230
    /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
V
varkor 已提交
231
    /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
232
    ///
233 234 235 236 237 238 239 240 241 242 243
    ReturnPositionOpaqueTy {
        /// `DefId` for the parent function, used to look up necessary
        /// information later.
        fn_def_id: DefId,
        /// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
        origin: hir::OpaqueTyOrigin,
    },
    /// Impl trait in type aliases, consts and statics.
    OtherOpaqueTy {
        /// Set of lifetimes that this opaque type can capture, if it uses
        /// them. This includes lifetimes bound since we entered this context.
P
pierwill 已提交
244
        /// For example:
245
        ///
P
pierwill 已提交
246
        /// ```
247
        /// type A<'b> = impl for<'a> Trait<'a, Out = impl Sized + 'a>;
P
pierwill 已提交
248
        /// ```
249
        ///
P
pierwill 已提交
250
        /// Here the inner opaque type captures `'a` because it uses it. It doesn't
251 252 253 254 255 256 257 258
        /// need to capture `'b` because it already inherits the lifetime
        /// parameter from `A`.
        // FIXME(impl_trait): but `required_region_bounds` will ICE later
        // anyway.
        capturable_lifetimes: &'b mut FxHashSet<hir::LifetimeName>,
        /// Origin: Either OpaqueTyOrigin::Misc or OpaqueTyOrigin::Binding,
        origin: hir::OpaqueTyOrigin,
    },
259
    /// `impl Trait` is not accepted in this position.
260 261 262
    Disallowed(ImplTraitPosition),
}

A
Alexander Regueiro 已提交
263
/// Position in which `impl Trait` is disallowed.
264 265
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum ImplTraitPosition {
266
    /// Disallowed in `let` / `const` / `static` bindings.
267
    Binding,
268

D
Dániel Buga 已提交
269
    /// All other positions.
270
    Other,
271 272
}

273
impl<'a> ImplTraitContext<'_, 'a> {
274 275 276 277 278
    #[inline]
    fn disallowed() -> Self {
        ImplTraitContext::Disallowed(ImplTraitPosition::Other)
    }

279
    fn reborrow<'this>(&'this mut self) -> ImplTraitContext<'this, 'a> {
280 281
        use self::ImplTraitContext::*;
        match self {
282
            Universal(params, parent) => Universal(params, *parent),
283 284 285 286 287 288
            ReturnPositionOpaqueTy { fn_def_id, origin } => {
                ReturnPositionOpaqueTy { fn_def_id: *fn_def_id, origin: *origin }
            }
            OtherOpaqueTy { capturable_lifetimes, origin } => {
                OtherOpaqueTy { capturable_lifetimes, origin: *origin }
            }
289
            Disallowed(pos) => Disallowed(*pos),
290 291 292 293
        }
    }
}

C
Camille GILLOT 已提交
294 295 296
pub fn lower_crate<'a, 'hir>(
    sess: &'a Session,
    krate: &'a Crate,
297
    resolver: &'a mut dyn ResolverAstLowering,
298
    nt_to_tokenstream: NtToTokenstream,
C
Camille GILLOT 已提交
299 300
    arena: &'hir Arena<'hir>,
) -> hir::Crate<'hir> {
J
John Kåre Alsaker 已提交
301
    let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering");
302

J
Jeffrey Seyfried 已提交
303
    LoweringContext {
304 305
        sess,
        resolver,
306
        nt_to_tokenstream,
C
Camille GILLOT 已提交
307
        arena,
308
        items: BTreeMap::new(),
309
        trait_items: BTreeMap::new(),
310
        impl_items: BTreeMap::new(),
311
        foreign_items: BTreeMap::new(),
N
Niko Matsakis 已提交
312
        bodies: BTreeMap::new(),
313
        trait_impls: BTreeMap::new(),
314
        modules: BTreeMap::new(),
315
        attrs: BTreeMap::default(),
316
        exported_macros: Vec::new(),
317
        non_exported_macro_attrs: Vec::new(),
318
        catch_scopes: Vec::new(),
319
        loop_scopes: Vec::new(),
320
        is_in_loop_condition: false,
321 322
        is_in_trait_impl: false,
        is_in_dyn_type: false,
323
        anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
324
        type_def_lifetime_params: Default::default(),
325 326
        current_module: CRATE_DEF_ID,
        current_hir_id_owner: vec![(CRATE_DEF_ID, 0)],
327
        item_local_id_counters: Default::default(),
328
        node_id_to_hir_id: IndexVec::new(),
329
        generator_kind: None,
330
        task_context: None,
331
        current_item: None,
332 333 334
        lifetimes_to_define: Vec::new(),
        is_collecting_in_band_lifetimes: false,
        in_scope_lifetimes: Vec::new(),
335 336
        allow_try_trait: Some([sym::try_trait][..].into()),
        allow_gen_future: Some([sym::gen_future][..].into()),
M
Mark Rousskov 已提交
337 338
    }
    .lower_crate(krate)
J
Jeffrey Seyfried 已提交
339
}
340

341
#[derive(Copy, Clone, PartialEq)]
342 343 344
enum ParamMode {
    /// Any path in a type context.
    Explicit,
345 346
    /// Path in a type definition, where the anonymous lifetime `'_` is not allowed.
    ExplicitNamed,
347
    /// The `module::Type` in `module::Type::method` in an expression.
N
Niko Matsakis 已提交
348
    Optional,
349 350
}

351 352 353 354 355
enum ParenthesizedGenericArgs {
    Ok,
    Err,
}

356
/// What to do when we encounter an **anonymous** lifetime
A
Alexander Regueiro 已提交
357
/// reference. Anonymous lifetime references come in two flavors. You
358 359
/// have implicit, or fully elided, references to lifetimes, like the
/// one in `&T` or `Ref<T>`, and you have `'_` lifetimes, like `&'_ T`
A
Alexander Regueiro 已提交
360
/// or `Ref<'_, T>`. These often behave the same, but not always:
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
///
/// - certain usages of implicit references are deprecated, like
///   `Ref<T>`, and we sometimes just give hard errors in those cases
///   as well.
/// - for object bounds there is a difference: `Box<dyn Foo>` is not
///   the same as `Box<dyn Foo + '_>`.
///
/// We describe the effects of the various modes in terms of three cases:
///
/// - **Modern** -- includes all uses of `'_`, but also the lifetime arg
///   of a `&` (e.g., the missing lifetime in something like `&T`)
/// - **Dyn Bound** -- if you have something like `Box<dyn Foo>`,
///   there is an elided lifetime bound (`Box<dyn Foo + 'X>`). These
///   elided bounds follow special rules. Note that this only covers
///   cases where *nothing* is written; the `'_` in `Box<dyn Foo +
///   '_>` is a case of "modern" elision.
D
Dániel Buga 已提交
377
/// - **Deprecated** -- this covers cases like `Ref<T>`, where the lifetime
378 379 380 381 382 383 384 385
///   parameter to ref is completely elided. `Ref<'_, T>` would be the modern,
///   non-deprecated equivalent.
///
/// Currently, the handling of lifetime elision is somewhat spread out
/// between HIR lowering and -- as described below -- the
/// `resolve_lifetime` module. Often we "fallthrough" to that code by generating
/// an "elided" or "underscore" lifetime name. In the future, we probably want to move
/// everything into HIR lowering.
N
Niko Matsakis 已提交
386
#[derive(Copy, Clone, Debug)]
387 388 389 390 391 392 393 394 395 396
enum AnonymousLifetimeMode {
    /// For **Modern** cases, create a new anonymous region parameter
    /// and reference that.
    ///
    /// For **Dyn Bound** cases, pass responsibility to
    /// `resolve_lifetime` code.
    ///
    /// For **Deprecated** cases, report an error.
    CreateParameter,

397 398 399 400 401
    /// Give a hard error when either `&` or `'_` is written. Used to
    /// rule out things like `where T: Foo<'_>`. Does not imply an
    /// error on default object bounds (e.g., `Box<dyn Foo>`).
    ReportError,

402 403 404 405
    /// Pass responsibility to `resolve_lifetime` code for all cases.
    PassThrough,
}

406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428
struct TokenStreamLowering<'a> {
    parse_sess: &'a ParseSess,
    synthesize_tokens: CanSynthesizeMissingTokens,
    nt_to_tokenstream: NtToTokenstream,
}

impl<'a> TokenStreamLowering<'a> {
    fn lower_token_stream(&mut self, tokens: TokenStream) -> TokenStream {
        tokens.into_trees().flat_map(|tree| self.lower_token_tree(tree).into_trees()).collect()
    }

    fn lower_token_tree(&mut self, tree: TokenTree) -> TokenStream {
        match tree {
            TokenTree::Token(token) => self.lower_token(token),
            TokenTree::Delimited(span, delim, tts) => {
                TokenTree::Delimited(span, delim, self.lower_token_stream(tts)).into()
            }
        }
    }

    fn lower_token(&mut self, token: Token) -> TokenStream {
        match token.kind {
            token::Interpolated(nt) => {
429
                let tts = (self.nt_to_tokenstream)(&nt, self.parse_sess, self.synthesize_tokens);
430 431 432 433 434 435 436 437 438 439 440 441
                TokenTree::Delimited(
                    DelimSpan::from_single(token.span),
                    DelimToken::NoDelim,
                    self.lower_token_stream(tts),
                )
                .into()
            }
            _ => TokenTree::Token(token).into(),
        }
    }
}

C
Camille GILLOT 已提交
442 443
impl<'a, 'hir> LoweringContext<'a, 'hir> {
    fn lower_crate(mut self, c: &Crate) -> hir::Crate<'hir> {
444 445
        /// Full-crate AST visitor that inserts into a fresh
        /// `LoweringContext` any information that may be
446 447
        /// needed from arbitrary locations in the crate,
        /// e.g., the number of lifetime generic parameters
448
        /// declared for every type and trait definition.
C
Camille GILLOT 已提交
449 450
        struct MiscCollector<'tcx, 'lowering, 'hir> {
            lctx: &'tcx mut LoweringContext<'lowering, 'hir>,
451
        }
452

C
Camille GILLOT 已提交
453
        impl MiscCollector<'_, '_, '_> {
454
            fn allocate_use_tree_hir_id_counters(&mut self, tree: &UseTree) {
455 456 457
                match tree.kind {
                    UseTreeKind::Simple(_, id1, id2) => {
                        for &id in &[id1, id2] {
458
                            self.lctx.allocate_hir_id_counter(id);
459 460 461 462 463
                        }
                    }
                    UseTreeKind::Glob => (),
                    UseTreeKind::Nested(ref trees) => {
                        for &(ref use_tree, id) in trees {
464 465
                            self.lctx.allocate_hir_id_counter(id);
                            self.allocate_use_tree_hir_id_counters(use_tree);
466 467 468 469 470 471
                        }
                    }
                }
            }
        }

472
        impl<'tcx> Visitor<'tcx> for MiscCollector<'tcx, '_, '_> {
473
            fn visit_item(&mut self, item: &'tcx Item) {
474
                self.lctx.allocate_hir_id_counter(item.id);
475

V
varkor 已提交
476
                match item.kind {
N
Niko Matsakis 已提交
477 478 479
                    ItemKind::Struct(_, ref generics)
                    | ItemKind::Union(_, ref generics)
                    | ItemKind::Enum(_, ref generics)
480 481
                    | ItemKind::TyAlias(box TyAliasKind(_, ref generics, ..))
                    | ItemKind::Trait(box TraitKind(_, _, ref generics, ..)) => {
482
                        let def_id = self.lctx.resolver.local_def_id(item.id);
N
Niko Matsakis 已提交
483 484 485
                        let count = generics
                            .params
                            .iter()
M
Mark Rousskov 已提交
486 487 488
                            .filter(|param| {
                                matches!(param.kind, ast::GenericParamKind::Lifetime { .. })
                            })
489
                            .count();
490
                        self.lctx.type_def_lifetime_params.insert(def_id.to_def_id(), count);
491
                    }
492
                    ItemKind::Use(ref use_tree) => {
493
                        self.allocate_use_tree_hir_id_counters(use_tree);
494
                    }
495 496
                    _ => {}
                }
L
ljedrz 已提交
497

C
Camille GILLOT 已提交
498
                visit::walk_item(self, item);
499
            }
500

501
            fn visit_assoc_item(&mut self, item: &'tcx AssocItem, ctxt: AssocCtxt) {
502
                self.lctx.allocate_hir_id_counter(item.id);
C
Camille GILLOT 已提交
503
                visit::walk_assoc_item(self, item, ctxt);
L
ljedrz 已提交
504 505
            }

C
Camille GILLOT 已提交
506 507 508 509 510
            fn visit_foreign_item(&mut self, item: &'tcx ForeignItem) {
                self.lctx.allocate_hir_id_counter(item.id);
                visit::walk_foreign_item(self, item);
            }

511
            fn visit_ty(&mut self, t: &'tcx Ty) {
V
varkor 已提交
512
                match t.kind {
L
ljedrz 已提交
513 514
                    // Mirrors the case in visit::walk_ty
                    TyKind::BareFn(ref f) => {
M
Mark Rousskov 已提交
515
                        walk_list!(self, visit_generic_param, &f.generic_params);
L
ljedrz 已提交
516
                        // Mirrors visit::walk_fn_decl
517
                        for parameter in &f.decl.inputs {
L
ljedrz 已提交
518
                            // We don't lower the ids of argument patterns
C
Camille GILLOT 已提交
519
                            self.visit_pat(&parameter.pat);
520
                            self.visit_ty(&parameter.ty)
L
ljedrz 已提交
521 522 523 524 525
                        }
                        self.visit_fn_ret_ty(&f.decl.output)
                    }
                    _ => visit::walk_ty(self, t),
                }
526
            }
527 528
        }

529
        self.lower_node_id(CRATE_NODE_ID);
530
        debug_assert!(self.node_id_to_hir_id[CRATE_NODE_ID] == Some(hir::CRATE_HIR_ID));
531

C
Camille GILLOT 已提交
532
        visit::walk_crate(&mut MiscCollector { lctx: &mut self }, c);
533
        visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c);
534

535
        let module = self.lower_mod(&c.items, c.span);
C
Camille GILLOT 已提交
536
        self.lower_attrs(hir::CRATE_HIR_ID, &c.attrs);
537
        let body_ids = body_ids(&self.bodies);
538 539
        let proc_macros =
            c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id].unwrap()).collect();
540

M
marmeladema 已提交
541 542 543 544
        let trait_map = self
            .resolver
            .trait_map()
            .iter()
545 546 547
            .filter_map(|(&k, v)| {
                self.node_id_to_hir_id.get(k).and_then(|id| id.as_ref()).map(|id| (*id, v.clone()))
            })
M
marmeladema 已提交
548 549
            .collect();

550 551 552 553 554 555 556 557 558 559 560 561
        let mut def_id_to_hir_id = IndexVec::default();

        for (node_id, hir_id) in self.node_id_to_hir_id.into_iter_enumerated() {
            if let Some(def_id) = self.resolver.opt_local_def_id(node_id) {
                if def_id_to_hir_id.len() <= def_id.index() {
                    def_id_to_hir_id.resize(def_id.index() + 1, None);
                }
                def_id_to_hir_id[def_id] = hir_id;
            }
        }

        self.resolver.definitions().init_def_id_to_hir_id_mapping(def_id_to_hir_id);
562

563 564 565 566 567 568 569
        #[cfg(debug_assertions)]
        for (&id, attrs) in self.attrs.iter() {
            // Verify that we do not store empty slices in the map.
            if attrs.is_empty() {
                panic!("Stored empty attributes for {:?}", id);
            }
        }
570

571
        hir::Crate {
C
Camille GILLOT 已提交
572
            item: module,
C
Camille GILLOT 已提交
573 574
            exported_macros: self.arena.alloc_from_iter(self.exported_macros),
            non_exported_macro_attrs: self.arena.alloc_from_iter(self.non_exported_macro_attrs),
575 576 577
            items: self.items,
            trait_items: self.trait_items,
            impl_items: self.impl_items,
578
            foreign_items: self.foreign_items,
579
            bodies: self.bodies,
580
            body_ids,
581
            trait_impls: self.trait_impls,
582
            modules: self.modules,
583
            proc_macros,
M
marmeladema 已提交
584
            trait_map,
585
            attrs: self.attrs,
586
        }
587
    }
588

589
    fn insert_item(&mut self, item: hir::Item<'hir>) -> hir::ItemId {
590
        let id = hir::ItemId { def_id: item.def_id };
591
        self.items.insert(id, item);
592
        self.modules.entry(self.current_module).or_default().items.insert(id);
593
        id
594 595
    }

L
ljedrz 已提交
596
    fn allocate_hir_id_counter(&mut self, owner: NodeId) -> hir::HirId {
597
        // Set up the counter if needed.
598
        self.item_local_id_counters.entry(owner).or_insert(0);
599
        // Always allocate the first `HirId` for the owner itself.
600
        let lowered = self.lower_node_id_with_owner(owner, owner);
L
ljedrz 已提交
601
        debug_assert_eq!(lowered.local_id.as_u32(), 0);
602
        lowered
603 604
    }

M
Mazdak Farrokhzad 已提交
605 606 607 608 609
    fn lower_node_id_generic(
        &mut self,
        ast_node_id: NodeId,
        alloc_hir_id: impl FnOnce(&mut Self) -> hir::HirId,
    ) -> hir::HirId {
610
        assert_ne!(ast_node_id, DUMMY_NODE_ID);
611 612 613 614

        let min_size = ast_node_id.as_usize() + 1;

        if min_size > self.node_id_to_hir_id.len() {
615
            self.node_id_to_hir_id.resize(min_size, None);
616 617
        }

618 619 620
        if let Some(existing_hir_id) = self.node_id_to_hir_id[ast_node_id] {
            existing_hir_id
        } else {
621
            // Generate a new `HirId`.
622
            let hir_id = alloc_hir_id(self);
623
            self.node_id_to_hir_id[ast_node_id] = Some(hir_id);
L
ljedrz 已提交
624 625

            hir_id
626 627 628
        }
    }

M
Mazdak Farrokhzad 已提交
629
    fn with_hir_id_owner<T>(&mut self, owner: NodeId, f: impl FnOnce(&mut Self) -> T) -> T {
M
Mark Rousskov 已提交
630 631
        let counter = self
            .item_local_id_counters
N
Niko Matsakis 已提交
632
            .insert(owner, HIR_ID_COUNTER_LOCKED)
633
            .unwrap_or_else(|| panic!("no `item_local_id_counters` entry for {:?}", owner));
634
        let def_id = self.resolver.local_def_id(owner);
635
        self.current_hir_id_owner.push((def_id, counter));
636
        let ret = f(self);
637
        let (new_def_id, new_counter) = self.current_hir_id_owner.pop().unwrap();
638

639
        debug_assert!(def_id == new_def_id);
640 641
        debug_assert!(new_counter >= counter);

M
Mark Rousskov 已提交
642
        let prev = self.item_local_id_counters.insert(owner, new_counter).unwrap();
643
        debug_assert!(prev == HIR_ID_COUNTER_LOCKED);
644
        ret
645 646
    }

647 648 649
    /// This method allocates a new `HirId` for the given `NodeId` and stores it in
    /// the `LoweringContext`'s `NodeId => HirId` map.
    /// Take care not to call this method if the resulting `HirId` is then not
650
    /// actually used in the HIR, as that would trigger an assertion in the
651 652
    /// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped
    /// properly. Calling the method twice with the same `NodeId` is fine though.
L
ljedrz 已提交
653
    fn lower_node_id(&mut self, ast_node_id: NodeId) -> hir::HirId {
654
        self.lower_node_id_generic(ast_node_id, |this| {
655
            let &mut (owner, ref mut local_id_counter) =
N
Niko Matsakis 已提交
656
                this.current_hir_id_owner.last_mut().unwrap();
657 658
            let local_id = *local_id_counter;
            *local_id_counter += 1;
659
            hir::HirId { owner, local_id: hir::ItemLocalId::from_u32(local_id) }
660 661 662
        })
    }

L
ljedrz 已提交
663
    fn lower_node_id_with_owner(&mut self, ast_node_id: NodeId, owner: NodeId) -> hir::HirId {
664
        self.lower_node_id_generic(ast_node_id, |this| {
665 666 667
            let local_id_counter = this
                .item_local_id_counters
                .get_mut(&owner)
668
                .expect("called `lower_node_id_with_owner` before `allocate_hir_id_counter`");
669 670 671 672 673 674 675 676
            let local_id = *local_id_counter;

            // We want to be sure not to modify the counter in the map while it
            // is also on the stack. Otherwise we'll get lost updates when writing
            // back from the stack to the map.
            debug_assert!(local_id != HIR_ID_COUNTER_LOCKED);

            *local_id_counter += 1;
677
            let owner = this.resolver.opt_local_def_id(owner).expect(
678
                "you forgot to call `create_def` or are lowering node-IDs \
679 680
                 that do not belong to the current owner",
            );
681 682

            hir::HirId { owner, local_id: hir::ItemLocalId::from_u32(local_id) }
683 684 685
        })
    }

L
ljedrz 已提交
686
    fn next_id(&mut self) -> hir::HirId {
M
Mark Rousskov 已提交
687 688
        let node_id = self.resolver.next_node_id();
        self.lower_node_id(node_id)
689 690
    }

691 692
    fn lower_res(&mut self, res: Res<NodeId>) -> Res {
        res.map_id(|id| {
L
ljedrz 已提交
693
            self.lower_node_id_generic(id, |_| {
694
                panic!("expected `NodeId` to be lowered already for res {:#?}", res);
L
ljedrz 已提交
695
            })
L
ljedrz 已提交
696 697 698
        })
    }

699
    fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {
700
        self.resolver.get_partial_res(id).map_or(Res::Err, |pr| {
701
            if pr.unresolved_segments() != 0 {
M
Mazdak Farrokhzad 已提交
702
                panic!("path not fully resolved: {:?}", pr);
703
            }
704
            pr.base_res()
705 706 707
        })
    }

708
    fn expect_full_res_from_use(&mut self, id: NodeId) -> impl Iterator<Item = Res<NodeId>> {
709
        self.resolver.get_import_res(id).present_items()
710 711
    }

712
    fn diagnostic(&self) -> &rustc_errors::Handler {
713
        self.sess.diagnostic()
714
    }
N
Nick Cameron 已提交
715

716 717 718 719
    /// Reuses the span but adds information like the kind of the desugaring and features that are
    /// allowed inside this span.
    fn mark_span_with_reason(
        &self,
720
        reason: DesugaringKind,
721 722 723
        span: Span,
        allow_internal_unstable: Option<Lrc<[Symbol]>>,
    ) -> Span {
724
        span.mark_with_reason(allow_internal_unstable, reason, self.sess.edition())
725 726
    }

727 728 729 730 731
    fn with_anonymous_lifetime_mode<R>(
        &mut self,
        anonymous_lifetime_mode: AnonymousLifetimeMode,
        op: impl FnOnce(&mut Self) -> R,
    ) -> R {
N
Niko Matsakis 已提交
732 733 734 735
        debug!(
            "with_anonymous_lifetime_mode(anonymous_lifetime_mode={:?})",
            anonymous_lifetime_mode,
        );
736 737 738 739
        let old_anonymous_lifetime_mode = self.anonymous_lifetime_mode;
        self.anonymous_lifetime_mode = anonymous_lifetime_mode;
        let result = op(self);
        self.anonymous_lifetime_mode = old_anonymous_lifetime_mode;
M
Mark Rousskov 已提交
740 741 742 743
        debug!(
            "with_anonymous_lifetime_mode: restoring anonymous_lifetime_mode={:?}",
            old_anonymous_lifetime_mode
        );
744 745 746
        result
    }

747
    /// Creates a new `hir::GenericParam` for every new lifetime and
748 749 750 751 752 753
    /// type parameter encountered while evaluating `f`. Definitions
    /// are created with the parent provided. If no `parent_id` is
    /// provided, no definitions will be returned.
    ///
    /// Presuming that in-band lifetimes are enabled, then
    /// `self.anonymous_lifetime_mode` will be updated to match the
754
    /// parameter while `f` is running (and restored afterwards).
M
Mazdak Farrokhzad 已提交
755
    fn collect_in_band_defs<T>(
756
        &mut self,
757
        parent_def_id: LocalDefId,
758
        anonymous_lifetime_mode: AnonymousLifetimeMode,
M
Mazdak Farrokhzad 已提交
759 760
        f: impl FnOnce(&mut Self) -> (Vec<hir::GenericParam<'hir>>, T),
    ) -> (Vec<hir::GenericParam<'hir>>, T) {
761 762
        assert!(!self.is_collecting_in_band_lifetimes);
        assert!(self.lifetimes_to_define.is_empty());
763 764
        let old_anonymous_lifetime_mode = self.anonymous_lifetime_mode;

765 766
        self.anonymous_lifetime_mode = anonymous_lifetime_mode;
        self.is_collecting_in_band_lifetimes = true;
767

768
        let (in_band_ty_params, res) = f(self);
769 770

        self.is_collecting_in_band_lifetimes = false;
771
        self.anonymous_lifetime_mode = old_anonymous_lifetime_mode;
772 773 774

        let lifetimes_to_define = self.lifetimes_to_define.split_off(0);

N
Niko Matsakis 已提交
775 776
        let params = lifetimes_to_define
            .into_iter()
777
            .map(|(span, hir_name)| self.lifetime_to_generic_param(span, hir_name, parent_def_id))
V
varkor 已提交
778
            .chain(in_band_ty_params.into_iter())
N
Niko Matsakis 已提交
779
            .collect();
780 781

        (params, res)
782 783
    }

784 785 786 787 788
    /// Converts a lifetime into a new generic parameter.
    fn lifetime_to_generic_param(
        &mut self,
        span: Span,
        hir_name: ParamName,
789
        parent_def_id: LocalDefId,
C
Camille GILLOT 已提交
790
    ) -> hir::GenericParam<'hir> {
M
Mark Rousskov 已提交
791
        let node_id = self.resolver.next_node_id();
792 793 794 795 796

        // Get the name we'll use to make the def-path. Note
        // that collisions are ok here and this shouldn't
        // really show up for end-user.
        let (str_name, kind) = match hir_name {
M
Mark Rousskov 已提交
797 798 799
            ParamName::Plain(ident) => (ident.name, hir::LifetimeParamKind::InBand),
            ParamName::Fresh(_) => (kw::UnderscoreLifetime, hir::LifetimeParamKind::Elided),
            ParamName::Error => (kw::UnderscoreLifetime, hir::LifetimeParamKind::Error),
800 801 802
        };

        // Add a definition for the in-band lifetime def.
803
        self.resolver.create_def(
804
            parent_def_id,
805
            node_id,
806
            DefPathData::LifetimeNs(str_name),
807
            ExpnId::root(),
808 809 810 811
            span,
        );

        hir::GenericParam {
L
ljedrz 已提交
812
            hir_id: self.lower_node_id(node_id),
813
            name: hir_name,
C
Camille GILLOT 已提交
814
            bounds: &[],
815 816
            span,
            pure_wrt_drop: false,
M
Mark Rousskov 已提交
817
            kind: hir::GenericParamKind::Lifetime { kind },
818 819 820
        }
    }

821 822 823 824
    /// When there is a reference to some lifetime `'a`, and in-band
    /// lifetimes are enabled, then we want to push that lifetime into
    /// the vector of names to define later. In that case, it will get
    /// added to the appropriate generics.
825
    fn maybe_collect_in_band_lifetime(&mut self, ident: Ident) {
826 827 828 829
        if !self.is_collecting_in_band_lifetimes {
            return;
        }

830 831 832 833
        if !self.sess.features_untracked().in_band_lifetimes {
            return;
        }

834
        if self.in_scope_lifetimes.contains(&ParamName::Plain(ident.normalize_to_macros_2_0())) {
835 836 837
            return;
        }

V
Vadim Petrochenkov 已提交
838
        let hir_name = ParamName::Plain(ident);
839

840 841 842
        if self.lifetimes_to_define.iter().any(|(_, lt_name)| {
            lt_name.normalize_to_macros_2_0() == hir_name.normalize_to_macros_2_0()
        }) {
843 844 845
            return;
        }

846
        self.lifetimes_to_define.push((ident.span, hir_name));
847 848
    }

849
    /// When we have either an elided or `'_` lifetime in an impl
850
    /// header, we convert it to an in-band lifetime.
851
    fn collect_fresh_in_band_lifetime(&mut self, span: Span) -> ParamName {
852
        assert!(self.is_collecting_in_band_lifetimes);
853
        let index = self.lifetimes_to_define.len() + self.in_scope_lifetimes.len();
854
        let hir_name = ParamName::Fresh(index);
855 856 857 858
        self.lifetimes_to_define.push((span, hir_name));
        hir_name
    }

V
varkor 已提交
859
    // Evaluates `f` with the lifetimes in `params` in-scope.
860 861 862
    // This is used to track which lifetimes have already been defined, and
    // which are new in-band lifetimes that need to have a definition created
    // for them.
M
Mazdak Farrokhzad 已提交
863 864 865 866 867
    fn with_in_scope_lifetime_defs<T>(
        &mut self,
        params: &[GenericParam],
        f: impl FnOnce(&mut Self) -> T,
    ) -> T {
868
        let old_len = self.in_scope_lifetimes.len();
869
        let lt_def_names = params.iter().filter_map(|param| match param.kind {
870 871 872
            GenericParamKind::Lifetime { .. } => {
                Some(ParamName::Plain(param.ident.normalize_to_macros_2_0()))
            }
873 874
            _ => None,
        });
875 876 877 878 879 880 881 882
        self.in_scope_lifetimes.extend(lt_def_names);

        let res = f(self);

        self.in_scope_lifetimes.truncate(old_len);
        res
    }

883 884 885 886 887
    /// Appends in-band lifetime defs and argument-position `impl
    /// Trait` defs to the existing set of generics.
    ///
    /// Presuming that in-band lifetimes are enabled, then
    /// `self.anonymous_lifetime_mode` will be updated to match the
888
    /// parameter while `f` is running (and restored afterwards).
M
Mazdak Farrokhzad 已提交
889
    fn add_in_band_defs<T>(
890 891
        &mut self,
        generics: &Generics,
892
        parent_def_id: LocalDefId,
893
        anonymous_lifetime_mode: AnonymousLifetimeMode,
M
Mazdak Farrokhzad 已提交
894 895
        f: impl FnOnce(&mut Self, &mut Vec<hir::GenericParam<'hir>>) -> T,
    ) -> (hir::Generics<'hir>, T) {
M
Mark Rousskov 已提交
896 897
        let (in_band_defs, (mut lowered_generics, res)) =
            self.with_in_scope_lifetime_defs(&generics.params, |this| {
898
                this.collect_in_band_defs(parent_def_id, anonymous_lifetime_mode, |this| {
899
                    let mut params = Vec::new();
900 901 902 903 904 905 906
                    // Note: it is necessary to lower generics *before* calling `f`.
                    // When lowering `async fn`, there's a final step when lowering
                    // the return type that assumes that all in-scope lifetimes have
                    // already been added to either `in_scope_lifetimes` or
                    // `lifetimes_to_define`. If we swapped the order of these two,
                    // in-band-lifetimes introduced by generics or where-clauses
                    // wouldn't have been added yet.
907 908 909 910 911 912 913
                    let generics = this.lower_generics_mut(
                        generics,
                        ImplTraitContext::Universal(
                            &mut params,
                            this.current_hir_id_owner.last().unwrap().0,
                        ),
                    );
914 915
                    let res = f(this, &mut params);
                    (params, (generics, res))
N
Niko Matsakis 已提交
916
                })
M
Mark Rousskov 已提交
917
            });
918

B
cleanup  
Bastian Kauschke 已提交
919
        lowered_generics.params.extend(in_band_defs);
920

C
Camille GILLOT 已提交
921
        let lowered_generics = lowered_generics.into_generics(self.arena);
922 923 924
        (lowered_generics, res)
    }

M
Mazdak Farrokhzad 已提交
925
    fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T {
926 927 928 929 930 931 932 933 934 935
        let was_in_dyn_type = self.is_in_dyn_type;
        self.is_in_dyn_type = in_scope;

        let result = f(self);

        self.is_in_dyn_type = was_in_dyn_type;

        result
    }

M
Mazdak Farrokhzad 已提交
936
    fn with_new_scopes<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
937 938 939
        let was_in_loop_condition = self.is_in_loop_condition;
        self.is_in_loop_condition = false;

C
Chris Gregory 已提交
940 941
        let catch_scopes = mem::take(&mut self.catch_scopes);
        let loop_scopes = mem::take(&mut self.loop_scopes);
942
        let ret = f(self);
943 944
        self.catch_scopes = catch_scopes;
        self.loop_scopes = loop_scopes;
945 946 947

        self.is_in_loop_condition = was_in_loop_condition;

948
        ret
949 950
    }

951 952 953 954 955 956 957 958 959
    fn lower_attrs(&mut self, id: hir::HirId, attrs: &[Attribute]) -> Option<&'hir [Attribute]> {
        if attrs.is_empty() {
            None
        } else {
            let ret = self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)));
            debug_assert!(!ret.is_empty());
            self.attrs.insert(id, ret);
            Some(ret)
        }
960 961
    }

C
Camille GILLOT 已提交
962
    fn lower_attr(&self, attr: &Attribute) -> Attribute {
963 964
        // Note that we explicitly do not walk the path. Since we don't really
        // lower attributes (we use the AST version) there is nowhere to keep
965
        // the `HirId`s. We don't actually need HIR version of attributes anyway.
966
        // Tokens are also not needed after macro expansion and parsing.
967
        let kind = match attr.kind {
968 969 970 971 972 973 974 975
            AttrKind::Normal(ref item, _) => AttrKind::Normal(
                AttrItem {
                    path: item.path.clone(),
                    args: self.lower_mac_args(&item.args),
                    tokens: None,
                },
                None,
            ),
976
            AttrKind::DocComment(comment_kind, data) => AttrKind::DocComment(comment_kind, data),
977 978
        };

979
        Attribute { kind, id: attr.id, style: attr.style, span: attr.span }
980 981
    }

982 983 984 985 986 987 988
    fn alias_attrs(&mut self, id: hir::HirId, target_id: hir::HirId) {
        if let Some(&a) = self.attrs.get(&target_id) {
            debug_assert!(!a.is_empty());
            self.attrs.insert(id, a);
        }
    }

C
Camille GILLOT 已提交
989
    fn lower_mac_args(&self, args: &MacArgs) -> MacArgs {
990 991
        match *args {
            MacArgs::Empty => MacArgs::Empty,
M
Mark Rousskov 已提交
992
            MacArgs::Delimited(dspan, delim, ref tokens) => {
993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013
                // This is either a non-key-value attribute, or a `macro_rules!` body.
                // We either not have any nonterminals present (in the case of an attribute),
                // or have tokens available for all nonterminals in the case of a nested
                // `macro_rules`: e.g:
                //
                // ```rust
                // macro_rules! outer {
                //     ($e:expr) => {
                //         macro_rules! inner {
                //             () => { $e }
                //         }
                //     }
                // }
                // ```
                //
                // In both cases, we don't want to synthesize any tokens
                MacArgs::Delimited(
                    dspan,
                    delim,
                    self.lower_token_stream(tokens.clone(), CanSynthesizeMissingTokens::No),
                )
M
Mark Rousskov 已提交
1014
            }
1015 1016 1017
            // This is an inert key-value attribute - it will never be visible to macros
            // after it gets lowered to HIR. Therefore, we can synthesize tokens with fake
            // spans to handle nonterminals in `#[doc]` (e.g. `#[doc = $e]`).
1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047
            MacArgs::Eq(eq_span, ref token) => {
                // In valid code the value is always representable as a single literal token.
                fn unwrap_single_token(sess: &Session, tokens: TokenStream, span: Span) -> Token {
                    if tokens.len() != 1 {
                        sess.diagnostic()
                            .delay_span_bug(span, "multiple tokens in key-value attribute's value");
                    }
                    match tokens.into_trees().next() {
                        Some(TokenTree::Token(token)) => token,
                        Some(TokenTree::Delimited(_, delim, tokens)) => {
                            if delim != token::NoDelim {
                                sess.diagnostic().delay_span_bug(
                                    span,
                                    "unexpected delimiter in key-value attribute's value",
                                )
                            }
                            unwrap_single_token(sess, tokens, span)
                        }
                        None => Token::dummy(),
                    }
                }

                let tokens = TokenStreamLowering {
                    parse_sess: &self.sess.parse_sess,
                    synthesize_tokens: CanSynthesizeMissingTokens::Yes,
                    nt_to_tokenstream: self.nt_to_tokenstream,
                }
                .lower_token(token.clone());
                MacArgs::Eq(eq_span, unwrap_single_token(self.sess, tokens, token.span))
            }
1048 1049 1050
        }
    }

1051 1052 1053 1054 1055 1056 1057 1058 1059
    fn lower_token_stream(
        &self,
        tokens: TokenStream,
        synthesize_tokens: CanSynthesizeMissingTokens,
    ) -> TokenStream {
        TokenStreamLowering {
            parse_sess: &self.sess.parse_sess,
            synthesize_tokens,
            nt_to_tokenstream: self.nt_to_tokenstream,
1060
        }
1061
        .lower_token_stream(tokens)
1062
    }
1063

1064 1065 1066 1067 1068 1069 1070 1071 1072 1073
    /// Given an associated type constraint like one of these:
    ///
    /// ```
    /// T: Iterator<Item: Debug>
    ///             ^^^^^^^^^^^
    /// T: Iterator<Item = Debug>
    ///             ^^^^^^^^^^^^
    /// ```
    ///
    /// returns a `hir::TypeBinding` representing `Item`.
E
Esteban Küber 已提交
1074 1075 1076
    fn lower_assoc_ty_constraint(
        &mut self,
        constraint: &AssocTyConstraint,
1077
        mut itctx: ImplTraitContext<'_, 'hir>,
C
Camille GILLOT 已提交
1078
    ) -> hir::TypeBinding<'hir> {
E
Esteban Küber 已提交
1079
        debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx);
1080

1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
        // lower generic arguments of identifier in constraint
        let gen_args = if let Some(ref gen_args) = constraint.gen_args {
            let gen_args_ctor = match gen_args {
                GenericArgs::AngleBracketed(ref data) => {
                    self.lower_angle_bracketed_parameter_data(
                        data,
                        ParamMode::Explicit,
                        itctx.reborrow(),
                    )
                    .0
                }
                GenericArgs::Parenthesized(ref data) => {
                    let mut err = self.sess.struct_span_err(
                        gen_args.span(),
                        "parenthesized generic arguments cannot be used in associated type constraints"
                    );
                    // FIXME: try to write a suggestion here
                    err.emit();
                    self.lower_angle_bracketed_parameter_data(
                        &data.as_angle_bracketed_args(),
                        ParamMode::Explicit,
                        itctx.reborrow(),
                    )
                    .0
                }
            };
            self.arena.alloc(gen_args_ctor.into_generic_args(&self.arena))
        } else {
            self.arena.alloc(hir::GenericArgs::none())
        };
1111

E
Esteban Küber 已提交
1112
        let kind = match constraint.kind {
M
Mark Rousskov 已提交
1113 1114 1115
            AssocTyConstraintKind::Equality { ref ty } => {
                hir::TypeBindingKind::Equality { ty: self.lower_ty(ty, itctx) }
            }
1116
            AssocTyConstraintKind::Bound { ref bounds } => {
1117
                let mut capturable_lifetimes;
1118
                let mut parent_def_id = self.current_hir_id_owner.last().unwrap().0;
A
Alexander Regueiro 已提交
1119
                // Piggy-back on the `impl Trait` context to figure out the correct behavior.
1120 1121 1122
                let (desugar_to_impl_trait, itctx) = match itctx {
                    // We are in the return position:
                    //
A
Alexander Regueiro 已提交
1123
                    //     fn foo() -> impl Iterator<Item: Debug>
1124 1125 1126
                    //
                    // so desugar to
                    //
A
Alexander Regueiro 已提交
1127
                    //     fn foo() -> impl Iterator<Item = impl Debug>
1128 1129
                    ImplTraitContext::ReturnPositionOpaqueTy { .. }
                    | ImplTraitContext::OtherOpaqueTy { .. } => (true, itctx),
1130 1131 1132

                    // We are in the argument position, but within a dyn type:
                    //
A
Alexander Regueiro 已提交
1133
                    //     fn foo(x: dyn Iterator<Item: Debug>)
1134 1135 1136
                    //
                    // so desugar to
                    //
A
Alexander Regueiro 已提交
1137
                    //     fn foo(x: dyn Iterator<Item = impl Debug>)
1138 1139 1140 1141
                    ImplTraitContext::Universal(_, parent) if self.is_in_dyn_type => {
                        parent_def_id = parent;
                        (true, itctx)
                    }
1142

A
Alexander Regueiro 已提交
1143 1144 1145
                    // In `type Foo = dyn Iterator<Item: Debug>` we desugar to
                    // `type Foo = dyn Iterator<Item = impl Debug>` but we have to override the
                    // "impl trait context" to permit `impl Debug` in this position (it desugars
V
varkor 已提交
1146
                    // then to an opaque type).
1147
                    //
1148
                    // FIXME: this is only needed until `impl Trait` is allowed in type aliases.
M
Mark Rousskov 已提交
1149
                    ImplTraitContext::Disallowed(_) if self.is_in_dyn_type => {
1150 1151 1152 1153 1154 1155 1156 1157
                        capturable_lifetimes = FxHashSet::default();
                        (
                            true,
                            ImplTraitContext::OtherOpaqueTy {
                                capturable_lifetimes: &mut capturable_lifetimes,
                                origin: hir::OpaqueTyOrigin::Misc,
                            },
                        )
M
Mark Rousskov 已提交
1158
                    }
1159

1160
                    // We are in the parameter position, but not within a dyn type:
1161
                    //
A
Alexander Regueiro 已提交
1162
                    //     fn foo(x: impl Iterator<Item: Debug>)
1163
                    //
A
Alexander Regueiro 已提交
1164 1165
                    // so we leave it as is and this gets expanded in astconv to a bound like
                    // `<T as Iterator>::Item: Debug` where `T` is the type parameter for the
1166
                    // `impl Iterator`.
1167 1168 1169
                    _ => (false, itctx),
                };

1170
                if desugar_to_impl_trait {
A
Alexander Regueiro 已提交
1171
                    // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
1172
                    // constructing the HIR for `impl bounds...` and then lowering that.
1173

M
Mark Rousskov 已提交
1174
                    let impl_trait_node_id = self.resolver.next_node_id();
1175
                    self.resolver.create_def(
1176
                        parent_def_id,
1177 1178
                        impl_trait_node_id,
                        DefPathData::ImplTrait,
1179
                        ExpnId::root(),
E
Esteban Küber 已提交
1180
                        constraint.span,
1181 1182 1183
                    );

                    self.with_dyn_type_scope(false, |this| {
M
Mark Rousskov 已提交
1184
                        let node_id = this.resolver.next_node_id();
1185
                        let ty = this.lower_ty(
1186
                            &Ty {
M
Mark Rousskov 已提交
1187
                                id: node_id,
V
varkor 已提交
1188
                                kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()),
E
Esteban Küber 已提交
1189
                                span: constraint.span,
A
Aaron Hill 已提交
1190
                                tokens: None,
1191 1192
                            },
                            itctx,
1193 1194
                        );

M
Mark Rousskov 已提交
1195
                        hir::TypeBindingKind::Equality { ty }
1196 1197
                    })
                } else {
1198 1199
                    // Desugar `AssocTy: Bounds` into a type binding where the
                    // later desugars into a trait predicate.
1200 1201
                    let bounds = self.lower_param_bounds(bounds, itctx);

M
Mark Rousskov 已提交
1202
                    hir::TypeBindingKind::Constraint { bounds }
1203
                }
1204 1205 1206
            }
        };

1207
        hir::TypeBinding {
E
Esteban Küber 已提交
1208 1209
            hir_id: self.lower_node_id(constraint.id),
            ident: constraint.ident,
1210
            gen_args,
1211
            kind,
E
Esteban Küber 已提交
1212
            span: constraint.span,
1213
        }
1214 1215
    }

1216 1217 1218
    fn lower_generic_arg(
        &mut self,
        arg: &ast::GenericArg,
C
Camille GILLOT 已提交
1219
        itctx: ImplTraitContext<'_, 'hir>,
C
Camille GILLOT 已提交
1220
    ) -> hir::GenericArg<'hir> {
1221
        match arg {
V
varkor 已提交
1222
            ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(&lt)),
1223
            ast::GenericArg::Type(ty) => {
M
Matthias Krüger 已提交
1224
                // We parse const arguments as path types as we cannot distinguish them during
1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238
                // parsing. We try to resolve that ambiguity by attempting resolution in both the
                // type and value namespaces. If we resolved the path in the value namespace, we
                // transform it into a generic const argument.
                if let TyKind::Path(ref qself, ref path) = ty.kind {
                    if let Some(partial_res) = self.resolver.get_partial_res(ty.id) {
                        let res = partial_res.base_res();
                        if !res.matches_ns(Namespace::TypeNS) {
                            debug!(
                                "lower_generic_arg: Lowering type argument as const argument: {:?}",
                                ty,
                            );

                            // Construct a AnonConst where the expr is the "ty"'s path.

1239
                            let parent_def_id = self.current_hir_id_owner.last().unwrap().0;
1240 1241 1242
                            let node_id = self.resolver.next_node_id();

                            // Add a definition for the in-band const def.
1243
                            self.resolver.create_def(
1244
                                parent_def_id,
1245 1246 1247 1248 1249 1250 1251 1252 1253 1254
                                node_id,
                                DefPathData::AnonConst,
                                ExpnId::root(),
                                ty.span,
                            );

                            let path_expr = Expr {
                                id: ty.id,
                                kind: ExprKind::Path(qself.clone(), path.clone()),
                                span: ty.span,
M
Mazdak Farrokhzad 已提交
1255
                                attrs: AttrVec::new(),
A
Aaron Hill 已提交
1256
                                tokens: None,
1257 1258
                            };

M
Mark Rousskov 已提交
1259 1260 1261
                            let ct = self.with_new_scopes(|this| hir::AnonConst {
                                hir_id: this.lower_node_id(node_id),
                                body: this.lower_const_body(path_expr.span, Some(&path_expr)),
1262
                            });
M
Mark Rousskov 已提交
1263
                            return GenericArg::Const(ConstArg { value: ct, span: ty.span });
1264 1265 1266 1267 1268
                        }
                    }
                }
                GenericArg::Type(self.lower_ty_direct(&ty, itctx))
            }
M
Mark Rousskov 已提交
1269 1270 1271 1272
            ast::GenericArg::Const(ct) => GenericArg::Const(ConstArg {
                value: self.lower_anon_const(&ct),
                span: ct.value.span,
            }),
1273 1274 1275
        }
    }

C
Camille GILLOT 已提交
1276 1277
    fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext<'_, 'hir>) -> &'hir hir::Ty<'hir> {
        self.arena.alloc(self.lower_ty_direct(t, itctx))
1278 1279
    }

1280 1281 1282 1283 1284 1285
    fn lower_path_ty(
        &mut self,
        t: &Ty,
        qself: &Option<QSelf>,
        path: &Path,
        param_mode: ParamMode,
C
Camille GILLOT 已提交
1286
        itctx: ImplTraitContext<'_, 'hir>,
C
Camille GILLOT 已提交
1287
    ) -> hir::Ty<'hir> {
1288 1289 1290
        let id = self.lower_node_id(t.id);
        let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx);
        let ty = self.ty_path(id, t.span, qpath);
V
varkor 已提交
1291
        if let hir::TyKind::TraitObject(..) = ty.kind {
1292 1293 1294 1295 1296
            self.maybe_lint_bare_trait(t.span, t.id, qself.is_none() && path.is_global());
        }
        ty
    }

C
Camille GILLOT 已提交
1297
    fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
1298 1299 1300
        hir::Ty { hir_id: self.next_id(), kind, span }
    }

C
Camille GILLOT 已提交
1301
    fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {
1302 1303 1304
        self.ty(span, hir::TyKind::Tup(tys))
    }

C
Camille GILLOT 已提交
1305
    fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_, 'hir>) -> hir::Ty<'hir> {
V
varkor 已提交
1306
        let kind = match t.kind {
C
TyKind  
csmoe 已提交
1307 1308 1309 1310
            TyKind::Infer => hir::TyKind::Infer,
            TyKind::Err => hir::TyKind::Err,
            TyKind::Slice(ref ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
            TyKind::Ptr(ref mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
1311
            TyKind::Rptr(ref region, ref mt) => {
1312
                let span = self.sess.source_map().next_point(t.span.shrink_to_lo());
1313 1314
                let lifetime = match *region {
                    Some(ref lt) => self.lower_lifetime(lt),
1315
                    None => self.elided_ref_lifetime(span),
1316
                };
C
TyKind  
csmoe 已提交
1317
                hir::TyKind::Rptr(lifetime, self.lower_mt(mt, itctx))
1318
            }
C
Camille GILLOT 已提交
1319 1320
            TyKind::BareFn(ref f) => self.with_in_scope_lifetime_defs(&f.generic_params, |this| {
                this.with_anonymous_lifetime_mode(AnonymousLifetimeMode::PassThrough, |this| {
1321
                    let span = this.sess.source_map().next_point(t.span.shrink_to_lo());
C
Camille GILLOT 已提交
1322 1323 1324 1325 1326 1327
                    hir::TyKind::BareFn(this.arena.alloc(hir::BareFnTy {
                        generic_params: this.lower_generic_params(
                            &f.generic_params,
                            &NodeMap::default(),
                            ImplTraitContext::disallowed(),
                        ),
1328
                        unsafety: this.lower_unsafety(f.unsafety),
1329
                        abi: this.lower_extern(f.ext, span, t.id),
C
Camille GILLOT 已提交
1330 1331 1332
                        decl: this.lower_fn_decl(&f.decl, None, false, None),
                        param_names: this.lower_fn_params_to_names(&f.decl),
                    }))
M
Mark Rousskov 已提交
1333
                })
C
Camille GILLOT 已提交
1334
            }),
C
TyKind  
csmoe 已提交
1335
            TyKind::Never => hir::TyKind::Never,
C
Camille GILLOT 已提交
1336 1337 1338 1339 1340
            TyKind::Tup(ref tys) => {
                hir::TyKind::Tup(self.arena.alloc_from_iter(
                    tys.iter().map(|ty| self.lower_ty_direct(ty, itctx.reborrow())),
                ))
            }
1341
            TyKind::Paren(ref ty) => {
1342
                return self.lower_ty_direct(ty, itctx);
1343 1344
            }
            TyKind::Path(ref qself, ref path) => {
1345
                return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
1346
            }
L
ljedrz 已提交
1347
            TyKind::ImplicitSelf => {
1348 1349
                let res = self.expect_full_res(t.id);
                let res = self.lower_res(res);
L
ljedrz 已提交
1350 1351
                hir::TyKind::Path(hir::QPath::Resolved(
                    None,
C
Camille GILLOT 已提交
1352
                    self.arena.alloc(hir::Path {
1353
                        res,
C
Camille GILLOT 已提交
1354 1355 1356
                        segments: arena_vec![self; hir::PathSegment::from_ident(
                            Ident::with_dummy_span(kw::SelfUpper)
                        )],
L
ljedrz 已提交
1357 1358 1359
                        span: t.span,
                    }),
                ))
M
Mark Rousskov 已提交
1360
            }
1361
            TyKind::Array(ref ty, ref length) => {
C
TyKind  
csmoe 已提交
1362
                hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_anon_const(length))
1363
            }
M
Mark Rousskov 已提交
1364
            TyKind::Typeof(ref expr) => hir::TyKind::Typeof(self.lower_anon_const(expr)),
M
Manish Goregaokar 已提交
1365
            TyKind::TraitObject(ref bounds, kind) => {
1366
                let mut lifetime_bound = None;
1367
                let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
C
Camille GILLOT 已提交
1368 1369 1370
                    let bounds =
                        this.arena.alloc_from_iter(bounds.iter().filter_map(
                            |bound| match *bound {
1371 1372 1373 1374
                                GenericBound::Trait(
                                    ref ty,
                                    TraitBoundModifier::None | TraitBoundModifier::MaybeConst,
                                ) => Some(this.lower_poly_trait_ref(ty, itctx.reborrow())),
1375 1376
                                // `?const ?Bound` will cause an error during AST validation
                                // anyways, so treat it like `?Bound` as compilation proceeds.
1377 1378 1379 1380
                                GenericBound::Trait(
                                    _,
                                    TraitBoundModifier::Maybe | TraitBoundModifier::MaybeConstMaybe,
                                ) => None,
C
Camille GILLOT 已提交
1381 1382 1383 1384 1385 1386 1387 1388
                                GenericBound::Outlives(ref lifetime) => {
                                    if lifetime_bound.is_none() {
                                        lifetime_bound = Some(this.lower_lifetime(lifetime));
                                    }
                                    None
                                }
                            },
                        ));
1389 1390 1391 1392
                    let lifetime_bound =
                        lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
                    (bounds, lifetime_bound)
                });
M
Manish Goregaokar 已提交
1393
                if kind != TraitObjectSyntax::Dyn {
1394
                    self.maybe_lint_bare_trait(t.span, t.id, false);
M
Manish Goregaokar 已提交
1395
                }
1396
                hir::TyKind::TraitObject(bounds, lifetime_bound, kind)
1397
            }
1398
            TyKind::ImplTrait(def_node_id, ref bounds) => {
1399
                let span = t.span;
1400
                match itctx {
1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425
                    ImplTraitContext::ReturnPositionOpaqueTy { fn_def_id, origin } => self
                        .lower_opaque_impl_trait(
                            span,
                            Some(fn_def_id),
                            origin,
                            def_node_id,
                            None,
                            |this| this.lower_param_bounds(bounds, itctx),
                        ),
                    ImplTraitContext::OtherOpaqueTy { ref capturable_lifetimes, origin } => {
                        // Reset capturable lifetimes, any nested impl trait
                        // types will inherit lifetimes from this opaque type,
                        // so don't need to capture them again.
                        let nested_itctx = ImplTraitContext::OtherOpaqueTy {
                            capturable_lifetimes: &mut FxHashSet::default(),
                            origin,
                        };
                        self.lower_opaque_impl_trait(
                            span,
                            None,
                            origin,
                            def_node_id,
                            Some(capturable_lifetimes),
                            |this| this.lower_param_bounds(bounds, nested_itctx),
                        )
N
Niko Matsakis 已提交
1426
                    }
1427
                    ImplTraitContext::Universal(in_band_ty_params, parent_def_id) => {
1428
                        // Add a definition for the in-band `Param`.
1429
                        let def_id = self.resolver.local_def_id(def_node_id);
1430

1431 1432 1433 1434
                        let hir_bounds = self.lower_param_bounds(
                            bounds,
                            ImplTraitContext::Universal(in_band_ty_params, parent_def_id),
                        );
1435
                        // Set the name to `impl Bound1 + Bound2`.
M
Matthew Jasper 已提交
1436
                        let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
1437
                        in_band_ty_params.push(hir::GenericParam {
L
ljedrz 已提交
1438
                            hir_id: self.lower_node_id(def_node_id),
V
Vadim Petrochenkov 已提交
1439
                            name: ParamName::Plain(ident),
1440
                            pure_wrt_drop: false,
V
varkor 已提交
1441
                            bounds: hir_bounds,
V
Vadim Petrochenkov 已提交
1442
                            span,
V
varkor 已提交
1443 1444 1445
                            kind: hir::GenericParamKind::Type {
                                default: None,
                                synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
M
Mark Rousskov 已提交
1446
                            },
1447 1448
                        });

C
TyKind  
csmoe 已提交
1449
                        hir::TyKind::Path(hir::QPath::Resolved(
N
Niko Matsakis 已提交
1450
                            None,
C
Camille GILLOT 已提交
1451
                            self.arena.alloc(hir::Path {
N
Niko Matsakis 已提交
1452
                                span,
1453
                                res: Res::Def(DefKind::TyParam, def_id.to_def_id()),
C
Camille GILLOT 已提交
1454
                                segments: arena_vec![self; hir::PathSegment::from_ident(ident)],
N
Niko Matsakis 已提交
1455 1456 1457
                            }),
                        ))
                    }
1458
                    ImplTraitContext::Disallowed(pos) => {
M
Mark Rousskov 已提交
1459
                        let allowed_in = if self.sess.features_untracked().impl_trait_in_bindings {
1460 1461 1462 1463
                            "bindings or function and inherent method return types"
                        } else {
                            "function and inherent method return types"
                        };
1464
                        let mut err = struct_span_err!(
N
Niko Matsakis 已提交
1465 1466 1467
                            self.sess,
                            t.span,
                            E0562,
1468 1469
                            "`impl Trait` not allowed outside of {}",
                            allowed_in,
N
Niko Matsakis 已提交
1470
                        );
1471
                        if pos == ImplTraitPosition::Binding && self.sess.is_nightly_build() {
1472
                            err.help(
M
Mark Rousskov 已提交
1473
                                "add `#![feature(impl_trait_in_bindings)]` to the crate \
1474
                                   attributes to enable",
M
Mark Rousskov 已提交
1475
                            );
1476 1477
                        }
                        err.emit();
C
TyKind  
csmoe 已提交
1478
                        hir::TyKind::Err
1479 1480
                    }
                }
1481
            }
M
Mazdak Farrokhzad 已提交
1482
            TyKind::MacCall(_) => panic!("`TyKind::MacCall` should have been expanded by now"),
1483 1484 1485 1486 1487 1488 1489
            TyKind::CVarArgs => {
                self.sess.delay_span_bug(
                    t.span,
                    "`TyKind::CVarArgs` should have been handled elsewhere",
                );
                hir::TyKind::Err
            }
1490 1491
        };

M
Mark Rousskov 已提交
1492
        hir::Ty { kind, span: t.span, hir_id: self.lower_node_id(t.id) }
1493
    }
1494

V
varkor 已提交
1495
    fn lower_opaque_impl_trait(
T
Taylor Cramer 已提交
1496 1497
        &mut self,
        span: Span,
1498
        fn_def_id: Option<DefId>,
1499
        origin: hir::OpaqueTyOrigin,
1500
        opaque_ty_node_id: NodeId,
1501
        capturable_lifetimes: Option<&FxHashSet<hir::LifetimeName>>,
C
Camille GILLOT 已提交
1502
        lower_bounds: impl FnOnce(&mut Self) -> hir::GenericBounds<'hir>,
C
Camille GILLOT 已提交
1503
    ) -> hir::TyKind<'hir> {
N
Niko Matsakis 已提交
1504 1505
        debug!(
            "lower_opaque_impl_trait(fn_def_id={:?}, opaque_ty_node_id={:?}, span={:?})",
M
Mark Rousskov 已提交
1506
            fn_def_id, opaque_ty_node_id, span,
N
Niko Matsakis 已提交
1507 1508
        );

T
Taylor Cramer 已提交
1509 1510 1511
        // Make sure we know that some funky desugaring has been going on here.
        // This is a first: there is code in other places like for loop
        // desugaring that explicitly states that we don't want to track that.
1512
        // Not tracking it makes lints in rustc and clippy very fragile, as
T
Taylor Cramer 已提交
1513
        // frequently opened issues show.
M
Mark Rousskov 已提交
1514
        let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
T
Taylor Cramer 已提交
1515

1516
        let opaque_ty_def_id = self.resolver.local_def_id(opaque_ty_node_id);
1517

1518
        self.allocate_hir_id_counter(opaque_ty_node_id);
T
Taylor Cramer 已提交
1519

1520
        let hir_bounds = self.with_hir_id_owner(opaque_ty_node_id, lower_bounds);
T
Taylor Cramer 已提交
1521

1522 1523 1524 1525 1526 1527
        let (lifetimes, lifetime_defs) = self.lifetimes_from_impl_trait_bounds(
            opaque_ty_node_id,
            opaque_ty_def_id,
            &hir_bounds,
            capturable_lifetimes,
        );
T
Taylor Cramer 已提交
1528

1529
        debug!("lower_opaque_impl_trait: lifetimes={:#?}", lifetimes);
N
Niko Matsakis 已提交
1530

1531
        debug!("lower_opaque_impl_trait: lifetime_defs={:#?}", lifetime_defs);
N
Niko Matsakis 已提交
1532

C
Camille GILLOT 已提交
1533
        self.with_hir_id_owner(opaque_ty_node_id, move |lctx| {
1534
            let opaque_ty_item = hir::OpaqueTy {
T
Taylor Cramer 已提交
1535 1536
                generics: hir::Generics {
                    params: lifetime_defs,
C
Camille GILLOT 已提交
1537
                    where_clause: hir::WhereClause { predicates: &[], span },
T
Taylor Cramer 已提交
1538 1539 1540
                    span,
                },
                bounds: hir_bounds,
1541
                impl_trait_fn: fn_def_id,
1542
                origin,
T
Taylor Cramer 已提交
1543 1544
            };

1545
            trace!("lower_opaque_impl_trait: {:#?}", opaque_ty_def_id);
1546
            lctx.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span);
T
Taylor Cramer 已提交
1547

1548
            // `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
1549
            hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, lifetimes)
T
Taylor Cramer 已提交
1550 1551 1552
        })
    }

V
varkor 已提交
1553 1554 1555
    /// Registers a new opaque type with the proper `NodeId`s and
    /// returns the lowered node-ID for the opaque type.
    fn generate_opaque_type(
1556
        &mut self,
1557
        opaque_ty_id: LocalDefId,
C
Camille GILLOT 已提交
1558
        opaque_ty_item: hir::OpaqueTy<'hir>,
1559
        span: Span,
1560
        opaque_ty_span: Span,
1561
    ) {
1562
        let opaque_ty_item_kind = hir::ItemKind::OpaqueTy(opaque_ty_item);
V
varkor 已提交
1563
        // Generate an `type Foo = impl Trait;` declaration.
1564 1565
        trace!("registering opaque type with id {:#?}", opaque_ty_id);
        let opaque_ty_item = hir::Item {
1566
            def_id: opaque_ty_id,
1567
            ident: Ident::invalid(),
V
varkor 已提交
1568
            kind: opaque_ty_item_kind,
1569
            vis: respan(span.shrink_to_lo(), hir::VisibilityKind::Inherited),
1570
            span: opaque_ty_span,
1571 1572 1573
        };

        // Insert the item into the global item list. This usually happens
V
varkor 已提交
1574
        // automatically for all AST items. But this opaque type item
1575
        // does not actually exist in the AST.
1576
        self.insert_item(opaque_ty_item);
1577 1578
    }

T
Taylor Cramer 已提交
1579 1580
    fn lifetimes_from_impl_trait_bounds(
        &mut self,
1581
        opaque_ty_id: NodeId,
1582
        parent_def_id: LocalDefId,
C
Camille GILLOT 已提交
1583
        bounds: hir::GenericBounds<'hir>,
1584
        lifetimes_to_include: Option<&FxHashSet<hir::LifetimeName>>,
C
Camille GILLOT 已提交
1585
    ) -> (&'hir [hir::GenericArg<'hir>], &'hir [hir::GenericParam<'hir>]) {
N
Niko Matsakis 已提交
1586 1587
        debug!(
            "lifetimes_from_impl_trait_bounds(opaque_ty_id={:?}, \
1588
             parent_def_id={:?}, \
N
Niko Matsakis 已提交
1589
             bounds={:#?})",
1590
            opaque_ty_id, parent_def_id, bounds,
N
Niko Matsakis 已提交
1591 1592
        );

1593
        // This visitor walks over `impl Trait` bounds and creates defs for all lifetimes that
T
Taylor Cramer 已提交
1594
        // appear in the bounds, excluding lifetimes that are created within the bounds.
1595
        // E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`.
C
Camille GILLOT 已提交
1596 1597
        struct ImplTraitLifetimeCollector<'r, 'a, 'hir> {
            context: &'r mut LoweringContext<'a, 'hir>,
1598
            parent: LocalDefId,
1599
            opaque_ty_id: NodeId,
1600 1601
            collect_elided_lifetimes: bool,
            currently_bound_lifetimes: Vec<hir::LifetimeName>,
1602
            already_defined_lifetimes: FxHashSet<hir::LifetimeName>,
C
Camille GILLOT 已提交
1603 1604
            output_lifetimes: Vec<hir::GenericArg<'hir>>,
            output_lifetime_params: Vec<hir::GenericParam<'hir>>,
1605
            lifetimes_to_include: Option<&'r FxHashSet<hir::LifetimeName>>,
T
Taylor Cramer 已提交
1606 1607
        }

1608
        impl<'r, 'a, 'v, 'hir> intravisit::Visitor<'v> for ImplTraitLifetimeCollector<'r, 'a, 'hir> {
1609
            type Map = intravisit::ErasedMap<'v>;
1610

1611
            fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
1612
                intravisit::NestedVisitorMap::None
T
Taylor Cramer 已提交
1613 1614
            }

C
Camille GILLOT 已提交
1615
            fn visit_generic_args(&mut self, span: Span, parameters: &'v hir::GenericArgs<'v>) {
1616 1617 1618 1619
                // Don't collect elided lifetimes used inside of `Fn()` syntax.
                if parameters.parenthesized {
                    let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
                    self.collect_elided_lifetimes = false;
1620
                    intravisit::walk_generic_args(self, span, parameters);
1621 1622
                    self.collect_elided_lifetimes = old_collect_elided_lifetimes;
                } else {
1623
                    intravisit::walk_generic_args(self, span, parameters);
1624 1625 1626
                }
            }

C
Camille GILLOT 已提交
1627
            fn visit_ty(&mut self, t: &'v hir::Ty<'v>) {
1628
                // Don't collect elided lifetimes used inside of `fn()` syntax.
V
varkor 已提交
1629
                if let hir::TyKind::BareFn(_) = t.kind {
1630 1631
                    let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
                    self.collect_elided_lifetimes = false;
1632 1633 1634 1635

                    // Record the "stack height" of `for<'a>` lifetime bindings
                    // to be able to later fully undo their introduction.
                    let old_len = self.currently_bound_lifetimes.len();
1636
                    intravisit::walk_ty(self, t);
1637 1638
                    self.currently_bound_lifetimes.truncate(old_len);

1639 1640
                    self.collect_elided_lifetimes = old_collect_elided_lifetimes;
                } else {
1641
                    intravisit::walk_ty(self, t)
1642 1643 1644
                }
            }

N
Niko Matsakis 已提交
1645 1646
            fn visit_poly_trait_ref(
                &mut self,
C
Camille GILLOT 已提交
1647
                trait_ref: &'v hir::PolyTraitRef<'v>,
1648
                modifier: hir::TraitBoundModifier,
N
Niko Matsakis 已提交
1649
            ) {
1650 1651
                // Record the "stack height" of `for<'a>` lifetime bindings
                // to be able to later fully undo their introduction.
T
Taylor Cramer 已提交
1652
                let old_len = self.currently_bound_lifetimes.len();
1653
                intravisit::walk_poly_trait_ref(self, trait_ref, modifier);
1654 1655
                self.currently_bound_lifetimes.truncate(old_len);
            }
T
Taylor Cramer 已提交
1656

C
Camille GILLOT 已提交
1657
            fn visit_generic_param(&mut self, param: &'v hir::GenericParam<'v>) {
1658
                // Record the introduction of 'a in `for<'a> ...`.
1659
                if let hir::GenericParamKind::Lifetime { .. } = param.kind {
1660
                    // Introduce lifetimes one at a time so that we can handle
1661
                    // cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd>`.
1662
                    let lt_name = hir::LifetimeName::Param(param.name);
V
varkor 已提交
1663
                    self.currently_bound_lifetimes.push(lt_name);
T
Taylor Cramer 已提交
1664 1665
                }

1666
                intravisit::walk_generic_param(self, param);
T
Taylor Cramer 已提交
1667 1668 1669
            }

            fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
1670
                let name = match lifetime.name {
N
Niko Matsakis 已提交
1671
                    hir::LifetimeName::Implicit | hir::LifetimeName::Underscore => {
1672 1673
                        if self.collect_elided_lifetimes {
                            // Use `'_` for both implicit and underscore lifetimes in
1674
                            // `type Foo<'_> = impl SomeTrait<'_>;`.
1675 1676
                            hir::LifetimeName::Underscore
                        } else {
N
Niko Matsakis 已提交
1677
                            return;
1678
                        }
N
Niko Matsakis 已提交
1679
                    }
1680
                    hir::LifetimeName::Param(_) => lifetime.name,
1681 1682 1683 1684 1685

                    // Refers to some other lifetime that is "in
                    // scope" within the type.
                    hir::LifetimeName::ImplicitObjectLifetimeDefault => return,

1686
                    hir::LifetimeName::Error | hir::LifetimeName::Static => return,
1687 1688
                };

N
Niko Matsakis 已提交
1689
                if !self.currently_bound_lifetimes.contains(&name)
M
Mark Rousskov 已提交
1690
                    && !self.already_defined_lifetimes.contains(&name)
1691
                    && self.lifetimes_to_include.map_or(true, |lifetimes| lifetimes.contains(&name))
M
Mark Rousskov 已提交
1692
                {
1693 1694
                    self.already_defined_lifetimes.insert(name);

1695
                    self.output_lifetimes.push(hir::GenericArg::Lifetime(hir::Lifetime {
L
ljedrz 已提交
1696
                        hir_id: self.context.next_id(),
1697 1698
                        span: lifetime.span,
                        name,
1699
                    }));
1700

M
Mark Rousskov 已提交
1701
                    let def_node_id = self.context.resolver.next_node_id();
L
ljedrz 已提交
1702
                    let hir_id =
1703
                        self.context.lower_node_id_with_owner(def_node_id, self.opaque_ty_id);
1704
                    self.context.resolver.create_def(
1705
                        self.parent,
1706
                        def_node_id,
1707
                        DefPathData::LifetimeNs(name.ident().name),
1708
                        ExpnId::root(),
M
Mark Rousskov 已提交
1709 1710
                        lifetime.span,
                    );
V
varkor 已提交
1711

1712 1713
                    let (name, kind) = match name {
                        hir::LifetimeName::Underscore => (
1714
                            hir::ParamName::Plain(Ident::with_dummy_span(kw::UnderscoreLifetime)),
1715 1716
                            hir::LifetimeParamKind::Elided,
                        ),
M
Mark Rousskov 已提交
1717 1718 1719
                        hir::LifetimeName::Param(param_name) => {
                            (param_name, hir::LifetimeParamKind::Explicit)
                        }
M
Mazdak Farrokhzad 已提交
1720
                        _ => panic!("expected `LifetimeName::Param` or `ParamName::Plain`"),
1721 1722
                    };

V
varkor 已提交
1723
                    self.output_lifetime_params.push(hir::GenericParam {
L
ljedrz 已提交
1724
                        hir_id,
1725
                        name,
1726
                        span: lifetime.span,
V
varkor 已提交
1727
                        pure_wrt_drop: false,
C
Camille GILLOT 已提交
1728
                        bounds: &[],
M
Mark Rousskov 已提交
1729
                        kind: hir::GenericParamKind::Lifetime { kind },
V
varkor 已提交
1730
                    });
T
Taylor Cramer 已提交
1731 1732 1733 1734 1735 1736
                }
            }
        }

        let mut lifetime_collector = ImplTraitLifetimeCollector {
            context: self,
1737
            parent: parent_def_id,
1738
            opaque_ty_id,
1739
            collect_elided_lifetimes: true,
T
Taylor Cramer 已提交
1740
            currently_bound_lifetimes: Vec::new(),
1741
            already_defined_lifetimes: FxHashSet::default(),
T
Taylor Cramer 已提交
1742
            output_lifetimes: Vec::new(),
1743
            output_lifetime_params: Vec::new(),
1744
            lifetimes_to_include,
T
Taylor Cramer 已提交
1745 1746 1747
        };

        for bound in bounds {
1748
            intravisit::walk_param_bound(&mut lifetime_collector, &bound);
T
Taylor Cramer 已提交
1749 1750
        }

C
Camille GILLOT 已提交
1751 1752 1753
        let ImplTraitLifetimeCollector { output_lifetimes, output_lifetime_params, .. } =
            lifetime_collector;

C
Camille GILLOT 已提交
1754 1755 1756 1757
        (
            self.arena.alloc_from_iter(output_lifetimes),
            self.arena.alloc_from_iter(output_lifetime_params),
        )
T
Taylor Cramer 已提交
1758 1759
    }

1760
    fn lower_local(&mut self, l: &Local) -> hir::Local<'hir> {
C
Camille GILLOT 已提交
1761
        let ty = l.ty.as_ref().map(|t| {
1762
            let mut capturable_lifetimes;
C
Camille GILLOT 已提交
1763 1764 1765
            self.lower_ty(
                t,
                if self.sess.features_untracked().impl_trait_in_bindings {
1766 1767 1768 1769 1770
                    capturable_lifetimes = FxHashSet::default();
                    ImplTraitContext::OtherOpaqueTy {
                        capturable_lifetimes: &mut capturable_lifetimes,
                        origin: hir::OpaqueTyOrigin::Binding,
                    }
C
Camille GILLOT 已提交
1771 1772 1773 1774 1775
                } else {
                    ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
                },
            )
        });
C
Camille GILLOT 已提交
1776
        let init = l.init.as_ref().map(|e| self.lower_expr(e));
1777
        let hir_id = self.lower_node_id(l.id);
C
Camille GILLOT 已提交
1778
        self.lower_attrs(hir_id, &l.attrs);
1779 1780 1781 1782 1783 1784 1785 1786
        hir::Local {
            hir_id,
            ty,
            pat: self.lower_pat(&l.pat),
            init,
            span: l.span,
            source: hir::LocalSource::Normal,
        }
N
Nick Cameron 已提交
1787
    }
1788

C
Camille GILLOT 已提交
1789
    fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] {
1790 1791 1792 1793 1794 1795 1796
        // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
        // as they are not explicit in HIR/Ty function signatures.
        // (instead, the `c_variadic` flag is set to `true`)
        let mut inputs = &decl.inputs[..];
        if decl.c_variadic() {
            inputs = &inputs[..inputs.len() - 1];
        }
C
Camille GILLOT 已提交
1797 1798
        self.arena.alloc_from_iter(inputs.iter().map(|param| match param.pat.kind {
            PatKind::Ident(_, ident, _) => ident,
J
Joshua Nelson 已提交
1799
            _ => Ident::new(kw::Empty, param.pat.span),
C
Camille GILLOT 已提交
1800
        }))
1801 1802
    }

T
Taylor Cramer 已提交
1803 1804
    // Lowers a function declaration.
    //
1805 1806
    // `decl`: the unlowered (AST) function declaration.
    // `fn_def_id`: if `Some`, impl Trait arguments are lowered into generic parameters on the
T
Taylor Cramer 已提交
1807
    //      given DefId, otherwise impl Trait is disallowed. Must be `Some` if
1808 1809 1810
    //      `make_ret_async` is also `Some`.
    // `impl_trait_return_allow`: determines whether `impl Trait` can be used in return position.
    //      This guards against trait declarations and implementations where `impl Trait` is
T
Taylor Cramer 已提交
1811
    //      disallowed.
1812 1813 1814
    // `make_ret_async`: if `Some`, converts `-> T` into `-> impl Future<Output = T>` in the
    //      return type. This is used for `async fn` declarations. The `NodeId` is the ID of the
    //      return type `impl Trait` item.
N
Niko Matsakis 已提交
1815 1816 1817
    fn lower_fn_decl(
        &mut self,
        decl: &FnDecl,
C
Camille GILLOT 已提交
1818
        mut in_band_ty_params: Option<(DefId, &mut Vec<hir::GenericParam<'hir>>)>,
N
Niko Matsakis 已提交
1819
        impl_trait_return_allow: bool,
1820
        make_ret_async: Option<NodeId>,
C
Camille GILLOT 已提交
1821
    ) -> &'hir hir::FnDecl<'hir> {
M
Mark Rousskov 已提交
1822 1823
        debug!(
            "lower_fn_decl(\
C
csmoe 已提交
1824 1825 1826 1827
            fn_decl: {:?}, \
            in_band_ty_params: {:?}, \
            impl_trait_return_allow: {}, \
            make_ret_async: {:?})",
M
Mark Rousskov 已提交
1828
            decl, in_band_ty_params, impl_trait_return_allow, make_ret_async,
C
csmoe 已提交
1829
        );
1830 1831 1832
        let lt_mode = if make_ret_async.is_some() {
            // In `async fn`, argument-position elided lifetimes
            // must be transformed into fresh generic parameters so that
V
varkor 已提交
1833
            // they can be applied to the opaque `impl Trait` return type.
1834 1835 1836 1837 1838
            AnonymousLifetimeMode::CreateParameter
        } else {
            self.anonymous_lifetime_mode
        };

1839 1840
        let c_variadic = decl.c_variadic();

1841 1842 1843
        // Remember how many lifetimes were already around so that we can
        // only look at the lifetime parameters introduced by the arguments.
        let inputs = self.with_anonymous_lifetime_mode(lt_mode, |this| {
1844 1845 1846 1847 1848 1849 1850
            // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
            // as they are not explicit in HIR/Ty function signatures.
            // (instead, the `c_variadic` flag is set to `true`)
            let mut inputs = &decl.inputs[..];
            if c_variadic {
                inputs = &inputs[..inputs.len() - 1];
            }
C
Camille GILLOT 已提交
1851 1852
            this.arena.alloc_from_iter(inputs.iter().map(|param| {
                if let Some((_, ibty)) = &mut in_band_ty_params {
1853 1854 1855 1856 1857 1858 1859
                    this.lower_ty_direct(
                        &param.ty,
                        ImplTraitContext::Universal(
                            ibty,
                            this.current_hir_id_owner.last().unwrap().0,
                        ),
                    )
C
Camille GILLOT 已提交
1860 1861 1862 1863
                } else {
                    this.lower_ty_direct(&param.ty, ImplTraitContext::disallowed())
                }
            }))
1864
        });
T
Taylor Cramer 已提交
1865

1866
        let output = if let Some(ret_id) = make_ret_async {
T
Taylor Cramer 已提交
1867
            self.lower_async_fn_ret_ty(
1868
                &decl.output,
1869
                in_band_ty_params.expect("`make_ret_async` but no `fn_def_id`").0,
1870 1871
                ret_id,
            )
T
Taylor Cramer 已提交
1872 1873
        } else {
            match decl.output {
1874
                FnRetTy::Ty(ref ty) => {
M
Matthew Jasper 已提交
1875 1876
                    let context = match in_band_ty_params {
                        Some((def_id, _)) if impl_trait_return_allow => {
1877 1878 1879 1880
                            ImplTraitContext::ReturnPositionOpaqueTy {
                                fn_def_id: def_id,
                                origin: hir::OpaqueTyOrigin::FnReturn,
                            }
M
Matthew Jasper 已提交
1881 1882 1883
                        }
                        _ => ImplTraitContext::disallowed(),
                    };
1884
                    hir::FnRetTy::Return(self.lower_ty(ty, context))
M
Matthew Jasper 已提交
1885
                }
1886
                FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(span),
T
Taylor Cramer 已提交
1887 1888 1889
            }
        };

C
Camille GILLOT 已提交
1890
        self.arena.alloc(hir::FnDecl {
T
Taylor Cramer 已提交
1891 1892
            inputs,
            output,
1893
            c_variadic,
M
Mark Rousskov 已提交
1894
            implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
L
LingMan 已提交
1895 1896 1897 1898 1899
                use BindingMode::{ByRef, ByValue};
                let is_mutable_pat = matches!(
                    arg.pat.kind,
                    PatKind::Ident(ByValue(Mutability::Mut) | ByRef(Mutability::Mut), ..)
                );
1900

M
Mark Rousskov 已提交
1901 1902 1903 1904 1905 1906 1907 1908 1909 1910
                match arg.ty.kind {
                    TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,
                    TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
                    // Given we are only considering `ImplicitSelf` types, we needn't consider
                    // the case where we have a mutable pattern to a reference as that would
                    // no longer be an `ImplicitSelf`.
                    TyKind::Rptr(_, ref mt)
                        if mt.ty.kind.is_implicit_self() && mt.mutbl == ast::Mutability::Mut =>
                    {
                        hir::ImplicitSelfKind::MutRef
1911
                    }
M
Mark Rousskov 已提交
1912 1913 1914 1915 1916 1917
                    TyKind::Rptr(_, ref mt) if mt.ty.kind.is_implicit_self() => {
                        hir::ImplicitSelfKind::ImmRef
                    }
                    _ => hir::ImplicitSelfKind::None,
                }
            }),
1918 1919
        })
    }
1920

1921 1922
    // Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`
    // combined with the following definition of `OpaqueTy`:
1923
    //
1924
    //     type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;
T
Taylor Cramer 已提交
1925
    //
1926
    // `inputs`: lowered types of parameters to the function (used to collect lifetimes)
1927 1928
    // `output`: unlowered output type (`T` in `-> T`)
    // `fn_def_id`: `DefId` of the parent function (used to create child impl trait definition)
1929
    // `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
1930
    // `elided_lt_replacement`: replacement for elided lifetimes in the return type
T
Taylor Cramer 已提交
1931 1932
    fn lower_async_fn_ret_ty(
        &mut self,
1933
        output: &FnRetTy,
T
Taylor Cramer 已提交
1934
        fn_def_id: DefId,
1935
        opaque_ty_node_id: NodeId,
1936
    ) -> hir::FnRetTy<'hir> {
N
Niko Matsakis 已提交
1937 1938 1939 1940 1941 1942 1943 1944
        debug!(
            "lower_async_fn_ret_ty(\
             output={:?}, \
             fn_def_id={:?}, \
             opaque_ty_node_id={:?})",
            output, fn_def_id, opaque_ty_node_id,
        );

1945
        let span = output.span();
T
Taylor Cramer 已提交
1946

M
Mark Rousskov 已提交
1947
        let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);
T
Taylor Cramer 已提交
1948

1949
        let opaque_ty_def_id = self.resolver.local_def_id(opaque_ty_node_id);
T
Taylor Cramer 已提交
1950

1951
        self.allocate_hir_id_counter(opaque_ty_node_id);
T
Taylor Cramer 已提交
1952

N
Niko Matsakis 已提交
1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998
        // When we create the opaque type for this async fn, it is going to have
        // to capture all the lifetimes involved in the signature (including in the
        // return type). This is done by introducing lifetime parameters for:
        //
        // - all the explicitly declared lifetimes from the impl and function itself;
        // - all the elided lifetimes in the fn arguments;
        // - all the elided lifetimes in the return type.
        //
        // So for example in this snippet:
        //
        // ```rust
        // impl<'a> Foo<'a> {
        //   async fn bar<'b>(&self, x: &'b Vec<f64>, y: &str) -> &u32 {
        //   //               ^ '0                       ^ '1     ^ '2
        //   // elided lifetimes used below
        //   }
        // }
        // ```
        //
        // we would create an opaque type like:
        //
        // ```
        // type Bar<'a, 'b, '0, '1, '2> = impl Future<Output = &'2 u32>;
        // ```
        //
        // and we would then desugar `bar` to the equivalent of:
        //
        // ```rust
        // impl<'a> Foo<'a> {
        //   fn bar<'b, '0, '1>(&'0 self, x: &'b Vec<f64>, y: &'1 str) -> Bar<'a, 'b, '0, '1, '_>
        // }
        // ```
        //
        // Note that the final parameter to `Bar` is `'_`, not `'2` --
        // this is because the elided lifetimes from the return type
        // should be figured out using the ordinary elision rules, and
        // this desugaring achieves that.
        //
        // The variable `input_lifetimes_count` tracks the number of
        // lifetime parameters to the opaque type *not counting* those
        // lifetimes elided in the return type. This includes those
        // that are explicitly declared (`in_scope_lifetimes`) and
        // those elided lifetimes we found in the arguments (current
        // content of `lifetimes_to_define`). Next, we will process
        // the return type, which will cause `lifetimes_to_define` to
        // grow.
1999
        let input_lifetimes_count = self.in_scope_lifetimes.len() + self.lifetimes_to_define.len();
N
Niko Matsakis 已提交
2000

2001
        let lifetime_params = self.with_hir_id_owner(opaque_ty_node_id, |this| {
2002 2003 2004 2005 2006 2007 2008 2009
            // We have to be careful to get elision right here. The
            // idea is that we create a lifetime parameter for each
            // lifetime in the return type.  So, given a return type
            // like `async fn foo(..) -> &[&u32]`, we lower to `impl
            // Future<Output = &'1 [ &'2 u32 ]>`.
            //
            // Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
            // hence the elision takes place at the fn site.
M
Mark Rousskov 已提交
2010 2011 2012 2013
            let future_bound = this
                .with_anonymous_lifetime_mode(AnonymousLifetimeMode::CreateParameter, |this| {
                    this.lower_async_fn_output_type_to_future_bound(output, fn_def_id, span)
                });
T
Taylor Cramer 已提交
2014

N
Niko Matsakis 已提交
2015 2016
            debug!("lower_async_fn_ret_ty: future_bound={:#?}", future_bound);

2017
            // Calculate all the lifetimes that should be captured
V
varkor 已提交
2018
            // by the opaque type. This should include all in-scope
2019 2020 2021 2022
            // lifetime parameters, including those defined in-band.
            //
            // Note: this must be done after lowering the output type,
            // as the output type may introduce new in-band lifetimes.
M
Mark Rousskov 已提交
2023 2024 2025 2026 2027 2028 2029
            let lifetime_params: Vec<(Span, ParamName)> = this
                .in_scope_lifetimes
                .iter()
                .cloned()
                .map(|name| (name.ident().span, name))
                .chain(this.lifetimes_to_define.iter().cloned())
                .collect();
T
Taylor Cramer 已提交
2030

2031 2032 2033 2034
            debug!("lower_async_fn_ret_ty: in_scope_lifetimes={:#?}", this.in_scope_lifetimes);
            debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", this.lifetimes_to_define);
            debug!("lower_async_fn_ret_ty: lifetime_params={:#?}", lifetime_params);

C
Camille GILLOT 已提交
2035 2036
            let generic_params =
                this.arena.alloc_from_iter(lifetime_params.iter().map(|(span, hir_name)| {
2037
                    this.lifetime_to_generic_param(*span, *hir_name, opaque_ty_def_id)
C
Camille GILLOT 已提交
2038
                }));
T
Taylor Cramer 已提交
2039

2040
            let opaque_ty_item = hir::OpaqueTy {
2041 2042
                generics: hir::Generics {
                    params: generic_params,
C
Camille GILLOT 已提交
2043
                    where_clause: hir::WhereClause { predicates: &[], span },
2044 2045
                    span,
                },
C
Camille GILLOT 已提交
2046
                bounds: arena_vec![this; future_bound],
2047
                impl_trait_fn: Some(fn_def_id),
V
varkor 已提交
2048
                origin: hir::OpaqueTyOrigin::AsyncFn,
T
Taylor Cramer 已提交
2049 2050
            };

2051
            trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id);
2052
            this.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span);
T
Taylor Cramer 已提交
2053

2054
            lifetime_params
2055
        });
T
Taylor Cramer 已提交
2056

N
Niko Matsakis 已提交
2057 2058 2059 2060
        // As documented above on the variable
        // `input_lifetimes_count`, we need to create the lifetime
        // arguments to our opaque type. Continuing with our example,
        // we're creating the type arguments for the return type:
2061 2062
        //
        // ```
N
Niko Matsakis 已提交
2063
        // Bar<'a, 'b, '0, '1, '_>
2064 2065
        // ```
        //
N
Niko Matsakis 已提交
2066 2067 2068 2069 2070 2071 2072
        // For the "input" lifetime parameters, we wish to create
        // references to the parameters themselves, including the
        // "implicit" ones created from parameter types (`'a`, `'b`,
        // '`0`, `'1`).
        //
        // For the "output" lifetime parameters, we just want to
        // generate `'_`.
D
Dániel Buga 已提交
2073 2074 2075
        let mut generic_args = Vec::with_capacity(lifetime_params.len());
        generic_args.extend(lifetime_params[..input_lifetimes_count].iter().map(
            |&(span, hir_name)| {
N
Niko Matsakis 已提交
2076
                // Input lifetime like `'a` or `'1`:
2077 2078 2079 2080
                GenericArg::Lifetime(hir::Lifetime {
                    hir_id: self.next_id(),
                    span,
                    name: hir::LifetimeName::Param(hir_name),
2081
                })
D
Dániel Buga 已提交
2082 2083
            },
        ));
C
Camille GILLOT 已提交
2084
        generic_args.extend(lifetime_params[input_lifetimes_count..].iter().map(|&(span, _)|
M
Mark Rousskov 已提交
2085 2086 2087 2088 2089
            // Output lifetime like `'_`.
            GenericArg::Lifetime(hir::Lifetime {
                hir_id: self.next_id(),
                span,
                name: hir::LifetimeName::Implicit,
C
Camille GILLOT 已提交
2090 2091
            })));
        let generic_args = self.arena.alloc_from_iter(generic_args);
T
Taylor Cramer 已提交
2092

2093
        // Create the `Foo<...>` reference itself. Note that the `type
2094 2095 2096
        // Foo = impl Trait` is, internally, created as a child of the
        // async fn, so the *type parameters* are inherited.  It's
        // only the lifetime parameters that we must supply.
2097 2098
        let opaque_ty_ref =
            hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, generic_args);
2099
        let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
2100
        hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
2101
    }
T
Taylor Cramer 已提交
2102

P
pierwill 已提交
2103
    /// Transforms `-> T` into `Future<Output = T>`.
2104 2105
    fn lower_async_fn_output_type_to_future_bound(
        &mut self,
2106
        output: &FnRetTy,
2107 2108
        fn_def_id: DefId,
        span: Span,
C
Camille GILLOT 已提交
2109
    ) -> hir::GenericBound<'hir> {
2110 2111
        // Compute the `T` in `Future<Output = T>` from the return type.
        let output_ty = match output {
2112
            FnRetTy::Ty(ty) => {
M
Matthew Jasper 已提交
2113 2114 2115
                // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the
                // `impl Future` opaque type that `async fn` implicitly
                // generates.
2116 2117 2118 2119
                let context = ImplTraitContext::ReturnPositionOpaqueTy {
                    fn_def_id,
                    origin: hir::OpaqueTyOrigin::FnReturn,
                };
M
Matthew Jasper 已提交
2120 2121
                self.lower_ty(ty, context)
            }
2122
            FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
2123
        };
T
Taylor Cramer 已提交
2124

2125
        // "<Output = T>"
D
David Wood 已提交
2126
        let future_args = self.arena.alloc(hir::GenericArgs {
C
Camille GILLOT 已提交
2127
            args: &[],
2128
            bindings: arena_vec![self; self.output_ty_binding(span, output_ty)],
2129
            parenthesized: false,
T
Taylor Cramer 已提交
2130 2131
        });

D
David Wood 已提交
2132 2133
        hir::GenericBound::LangItemTrait(
            // ::std::future::Future<future_params>
2134
            hir::LangItem::Future,
D
David Wood 已提交
2135 2136 2137
            span,
            self.next_id(),
            future_args,
2138
        )
T
Taylor Cramer 已提交
2139 2140
    }

V
varkor 已提交
2141
    fn lower_param_bound(
N
Niko Matsakis 已提交
2142
        &mut self,
V
varkor 已提交
2143
        tpb: &GenericBound,
C
Camille GILLOT 已提交
2144
        itctx: ImplTraitContext<'_, 'hir>,
C
Camille GILLOT 已提交
2145
    ) -> hir::GenericBound<'hir> {
2146
        match *tpb {
M
Mark Rousskov 已提交
2147 2148 2149 2150
            GenericBound::Trait(ref ty, modifier) => hir::GenericBound::Trait(
                self.lower_poly_trait_ref(ty, itctx),
                self.lower_trait_bound_modifier(modifier),
            ),
V
varkor 已提交
2151 2152
            GenericBound::Outlives(ref lifetime) => {
                hir::GenericBound::Outlives(self.lower_lifetime(lifetime))
2153 2154 2155
            }
        }
    }
2156

2157
    fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
2158
        let span = l.ident.span;
V
Vadim Petrochenkov 已提交
2159
        match l.ident {
M
Mark Rousskov 已提交
2160 2161 2162 2163 2164 2165 2166 2167
            ident if ident.name == kw::StaticLifetime => {
                self.new_named_lifetime(l.id, span, hir::LifetimeName::Static)
            }
            ident if ident.name == kw::UnderscoreLifetime => match self.anonymous_lifetime_mode {
                AnonymousLifetimeMode::CreateParameter => {
                    let fresh_name = self.collect_fresh_in_band_lifetime(span);
                    self.new_named_lifetime(l.id, span, hir::LifetimeName::Param(fresh_name))
                }
2168

M
Mark Rousskov 已提交
2169 2170 2171
                AnonymousLifetimeMode::PassThrough => {
                    self.new_named_lifetime(l.id, span, hir::LifetimeName::Underscore)
                }
2172

M
Mark Rousskov 已提交
2173 2174
                AnonymousLifetimeMode::ReportError => self.new_error_lifetime(Some(l.id), span),
            },
2175 2176 2177
            ident => {
                self.maybe_collect_in_band_lifetime(ident);
                let param_name = ParamName::Plain(ident);
2178
                self.new_named_lifetime(l.id, span, hir::LifetimeName::Param(param_name))
2179
            }
2180 2181
        }
    }
2182

2183 2184 2185 2186 2187 2188
    fn new_named_lifetime(
        &mut self,
        id: NodeId,
        span: Span,
        name: hir::LifetimeName,
    ) -> hir::Lifetime {
M
Mark Rousskov 已提交
2189
        hir::Lifetime { hir_id: self.lower_node_id(id), span, name }
2190 2191
    }

C
Camille GILLOT 已提交
2192 2193 2194 2195 2196 2197
    fn lower_generic_params_mut<'s>(
        &'s mut self,
        params: &'s [GenericParam],
        add_bounds: &'s NodeMap<Vec<GenericBound>>,
        mut itctx: ImplTraitContext<'s, 'hir>,
    ) -> impl Iterator<Item = hir::GenericParam<'hir>> + Captures<'a> + Captures<'s> {
M
Mark Rousskov 已提交
2198 2199
        params
            .iter()
C
Camille GILLOT 已提交
2200
            .map(move |param| self.lower_generic_param(param, add_bounds, itctx.reborrow()))
M
Mark Rousskov 已提交
2201 2202
    }

C
Camille GILLOT 已提交
2203 2204 2205 2206 2207 2208 2209 2210 2211
    fn lower_generic_params(
        &mut self,
        params: &[GenericParam],
        add_bounds: &NodeMap<Vec<GenericBound>>,
        itctx: ImplTraitContext<'_, 'hir>,
    ) -> &'hir [hir::GenericParam<'hir>] {
        self.arena.alloc_from_iter(self.lower_generic_params_mut(params, add_bounds, itctx))
    }

M
Mark Rousskov 已提交
2212 2213 2214 2215
    fn lower_generic_param(
        &mut self,
        param: &GenericParam,
        add_bounds: &NodeMap<Vec<GenericBound>>,
C
Camille GILLOT 已提交
2216
        mut itctx: ImplTraitContext<'_, 'hir>,
C
Camille GILLOT 已提交
2217
    ) -> hir::GenericParam<'hir> {
C
Camille GILLOT 已提交
2218
        let mut bounds: Vec<_> = self
M
Mark Rousskov 已提交
2219
            .with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
C
Camille GILLOT 已提交
2220
                this.lower_param_bounds_mut(&param.bounds, itctx.reborrow()).collect()
M
Mark Rousskov 已提交
2221
            });
2222

V
varkor 已提交
2223
        let (name, kind) = match param.kind {
2224
            GenericParamKind::Lifetime => {
V
varkor 已提交
2225 2226 2227
                let was_collecting_in_band = self.is_collecting_in_band_lifetimes;
                self.is_collecting_in_band_lifetimes = false;

M
Mark Rousskov 已提交
2228 2229 2230 2231
                let lt = self
                    .with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
                        this.lower_lifetime(&Lifetime { id: param.id, ident: param.ident })
                    });
2232 2233
                let param_name = match lt.name {
                    hir::LifetimeName::Param(param_name) => param_name,
2234
                    hir::LifetimeName::Implicit
M
Mark Rousskov 已提交
2235 2236
                    | hir::LifetimeName::Underscore
                    | hir::LifetimeName::Static => hir::ParamName::Plain(lt.name.ident()),
2237
                    hir::LifetimeName::ImplicitObjectLifetimeDefault => {
M
Mazdak Farrokhzad 已提交
2238
                        self.sess.diagnostic().span_bug(
2239 2240 2241 2242
                            param.ident.span,
                            "object-lifetime-default should not occur here",
                        );
                    }
2243
                    hir::LifetimeName::Error => ParamName::Error,
2244
                };
V
varkor 已提交
2245

M
Mark Rousskov 已提交
2246 2247
                let kind =
                    hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
2248

V
varkor 已提交
2249
                self.is_collecting_in_band_lifetimes = was_collecting_in_band;
2250

V
varkor 已提交
2251
                (param_name, kind)
V
varkor 已提交
2252
            }
V
varkor 已提交
2253
            GenericParamKind::Type { ref default, .. } => {
V
varkor 已提交
2254
                let add_bounds = add_bounds.get(&param.id).map_or(&[][..], |x| &x);
V
varkor 已提交
2255
                if !add_bounds.is_empty() {
C
Camille GILLOT 已提交
2256 2257
                    let params = self.lower_param_bounds_mut(add_bounds, itctx.reborrow());
                    bounds.extend(params);
V
varkor 已提交
2258
                }
2259

V
varkor 已提交
2260
                let kind = hir::GenericParamKind::Type {
2261
                    default: default.as_ref().map(|x| {
2262
                        self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Other))
2263
                    }),
M
Mark Rousskov 已提交
2264 2265 2266
                    synthetic: param
                        .attrs
                        .iter()
2267
                        .filter(|attr| self.sess.check_name(attr, sym::rustc_synthetic))
B
Bastian Kauschke 已提交
2268
                        .map(|_| hir::SyntheticTyParamKind::FromAttr)
M
Mark Rousskov 已提交
2269
                        .next(),
V
varkor 已提交
2270 2271
                };

M
Matthew Jasper 已提交
2272
                (hir::ParamName::Plain(param.ident), kind)
V
varkor 已提交
2273
            }
2274
            GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
2275 2276 2277 2278
                let ty = self
                    .with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
                        this.lower_ty(&ty, ImplTraitContext::disallowed())
                    });
2279 2280
                let default = default.as_ref().map(|def| self.lower_anon_const(def));
                (hir::ParamName::Plain(param.ident), hir::GenericParamKind::Const { ty, default })
2281
            }
V
varkor 已提交
2282 2283
        };

2284
        let hir_id = self.lower_node_id(param.id);
2285
        self.lower_attrs(hir_id, &param.attrs);
V
varkor 已提交
2286
        hir::GenericParam {
2287
            hir_id,
V
varkor 已提交
2288 2289
            name,
            span: param.ident.span,
2290
            pure_wrt_drop: self.sess.contains_name(&param.attrs, sym::may_dangle),
C
Camille GILLOT 已提交
2291
            bounds: self.arena.alloc_from_iter(bounds),
V
varkor 已提交
2292
            kind,
V
varkor 已提交
2293
        }
2294
    }
2295

C
Camille GILLOT 已提交
2296 2297 2298
    fn lower_trait_ref(
        &mut self,
        p: &TraitRef,
C
Camille GILLOT 已提交
2299
        itctx: ImplTraitContext<'_, 'hir>,
C
Camille GILLOT 已提交
2300
    ) -> hir::TraitRef<'hir> {
2301
        let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
2302
            hir::QPath::Resolved(None, path) => path,
M
Mazdak Farrokhzad 已提交
2303
            qpath => panic!("lower_trait_ref: unexpected QPath `{:?}`", qpath),
2304
        };
M
Mark Rousskov 已提交
2305
        hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
2306 2307
    }

N
Niko Matsakis 已提交
2308 2309 2310
    fn lower_poly_trait_ref(
        &mut self,
        p: &PolyTraitRef,
C
Camille GILLOT 已提交
2311
        mut itctx: ImplTraitContext<'_, 'hir>,
C
Camille GILLOT 已提交
2312
    ) -> hir::PolyTraitRef<'hir> {
2313 2314 2315 2316 2317
        let bound_generic_params = self.lower_generic_params(
            &p.bound_generic_params,
            &NodeMap::default(),
            itctx.reborrow(),
        );
2318

M
Mark Rousskov 已提交
2319
        let trait_ref = self.with_in_scope_lifetime_defs(&p.bound_generic_params, |this| {
2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339
            // Any impl Trait types defined within this scope can capture
            // lifetimes bound on this predicate.
            let lt_def_names = p.bound_generic_params.iter().filter_map(|param| match param.kind {
                GenericParamKind::Lifetime { .. } => Some(hir::LifetimeName::Param(
                    ParamName::Plain(param.ident.normalize_to_macros_2_0()),
                )),
                _ => None,
            });
            if let ImplTraitContext::OtherOpaqueTy { ref mut capturable_lifetimes, .. } = itctx {
                capturable_lifetimes.extend(lt_def_names.clone());
            }

            let res = this.lower_trait_ref(&p.trait_ref, itctx.reborrow());

            if let ImplTraitContext::OtherOpaqueTy { ref mut capturable_lifetimes, .. } = itctx {
                for param in lt_def_names {
                    capturable_lifetimes.remove(&param);
                }
            }
            res
M
Mark Rousskov 已提交
2340
        });
2341

C
Camille GILLOT 已提交
2342
        hir::PolyTraitRef { bound_generic_params, trait_ref, span: p.span }
2343 2344
    }

C
Camille GILLOT 已提交
2345
    fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext<'_, 'hir>) -> hir::MutTy<'hir> {
M
Mark Rousskov 已提交
2346
        hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
2347
    }
2348

M
Mark Rousskov 已提交
2349 2350 2351
    fn lower_param_bounds(
        &mut self,
        bounds: &[GenericBound],
C
Camille GILLOT 已提交
2352
        itctx: ImplTraitContext<'_, 'hir>,
C
Camille GILLOT 已提交
2353
    ) -> hir::GenericBounds<'hir> {
C
Camille GILLOT 已提交
2354 2355 2356
        self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
    }

C
Camille GILLOT 已提交
2357 2358 2359 2360 2361 2362
    fn lower_param_bounds_mut<'s>(
        &'s mut self,
        bounds: &'s [GenericBound],
        mut itctx: ImplTraitContext<'s, 'hir>,
    ) -> impl Iterator<Item = hir::GenericBound<'hir>> + Captures<'s> + Captures<'a> {
        bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx.reborrow()))
2363 2364
    }

C
Camille GILLOT 已提交
2365 2366 2367 2368 2369
    fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> &'hir hir::Block<'hir> {
        self.arena.alloc(self.lower_block_noalloc(b, targeted_by_break))
    }

    fn lower_block_noalloc(&mut self, b: &Block, targeted_by_break: bool) -> hir::Block<'hir> {
C
Cameron Steffen 已提交
2370 2371 2372 2373 2374 2375
        let (stmts, expr) = match &*b.stmts {
            [stmts @ .., Stmt { kind: StmtKind::Expr(e), .. }] => (stmts, Some(&*e)),
            stmts => (stmts, None),
        };
        let stmts = self.arena.alloc_from_iter(stmts.iter().flat_map(|stmt| self.lower_stmt(stmt)));
        let expr = expr.map(|e| self.lower_expr(e));
2376 2377
        let rules = self.lower_block_check_mode(&b.rules);
        let hir_id = self.lower_node_id(b.id);
2378

2379
        hir::Block { hir_id, stmts, expr, rules, span: b.span, targeted_by_break }
2380
    }
2381

2382 2383
    /// Lowers a block directly to an expression, presuming that it
    /// has no attributes and is not targeted by a `break`.
C
Camille GILLOT 已提交
2384
    fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
2385
        let block = self.lower_block(b, false);
M
Mazdak Farrokhzad 已提交
2386
        self.expr_block(block, AttrVec::new())
2387 2388
    }

2389
    fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
M
Mark Rousskov 已提交
2390 2391 2392
        self.with_new_scopes(|this| hir::AnonConst {
            hir_id: this.lower_node_id(c.id),
            body: this.lower_const_body(c.value.span, Some(&c.value)),
2393
        })
2394 2395
    }

C
Camille GILLOT 已提交
2396
    fn lower_stmt(&mut self, s: &Stmt) -> SmallVec<[hir::Stmt<'hir>; 1]> {
C
Camille GILLOT 已提交
2397
        let (hir_id, kind) = match s.kind {
2398
            StmtKind::Local(ref l) => {
2399
                let l = self.lower_local(l);
C
Camille GILLOT 已提交
2400
                let hir_id = self.lower_node_id(s.id);
2401
                self.alias_attrs(hir_id, l.hir_id);
2402 2403 2404 2405 2406
                return smallvec![hir::Stmt {
                    hir_id,
                    kind: hir::StmtKind::Local(self.arena.alloc(l)),
                    span: s.span,
                }];
M
Mark Rousskov 已提交
2407
            }
2408 2409 2410
            StmtKind::Item(ref it) => {
                // Can only use the ID once.
                let mut id = Some(s.id);
M
Mark Rousskov 已提交
2411 2412
                return self
                    .lower_item_id(it)
N
Niko Matsakis 已提交
2413
                    .into_iter()
L
ljedrz 已提交
2414
                    .map(|item_id| {
M
Mark Rousskov 已提交
2415 2416 2417 2418 2419 2420
                        let hir_id = id
                            .take()
                            .map(|id| self.lower_node_id(id))
                            .unwrap_or_else(|| self.next_id());

                        hir::Stmt { hir_id, kind: hir::StmtKind::Item(item_id), span: s.span }
N
Niko Matsakis 已提交
2421 2422
                    })
                    .collect();
2423
            }
C
Camille GILLOT 已提交
2424 2425 2426
            StmtKind::Expr(ref e) => {
                let e = self.lower_expr(e);
                let hir_id = self.lower_node_id(s.id);
2427
                self.alias_attrs(hir_id, e.hir_id);
C
Camille GILLOT 已提交
2428 2429 2430 2431 2432
                (hir_id, hir::StmtKind::Expr(e))
            }
            StmtKind::Semi(ref e) => {
                let e = self.lower_expr(e);
                let hir_id = self.lower_node_id(s.id);
2433
                self.alias_attrs(hir_id, e.hir_id);
C
Camille GILLOT 已提交
2434 2435
                (hir_id, hir::StmtKind::Semi(e))
            }
2436
            StmtKind::Empty => return smallvec![],
2437
            StmtKind::MacCall(..) => panic!("shouldn't exist here"),
2438
        };
C
Camille GILLOT 已提交
2439
        smallvec![hir::Stmt { hir_id, kind, span: s.span }]
2440 2441
    }

2442 2443
    fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode {
        match *b {
2444 2445 2446 2447
            BlockCheckMode::Default => hir::BlockCheckMode::DefaultBlock,
            BlockCheckMode::Unsafe(u) => {
                hir::BlockCheckMode::UnsafeBlock(self.lower_unsafe_source(u))
            }
2448
        }
2449 2450
    }

2451 2452
    fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
        match u {
2453 2454
            CompilerGenerated => hir::UnsafeSource::CompilerGenerated,
            UserProvided => hir::UnsafeSource::UserProvided,
2455
        }
2456 2457
    }

2458 2459 2460
    fn lower_trait_bound_modifier(&mut self, f: TraitBoundModifier) -> hir::TraitBoundModifier {
        match f {
            TraitBoundModifier::None => hir::TraitBoundModifier::None,
2461
            TraitBoundModifier::MaybeConst => hir::TraitBoundModifier::MaybeConst,
2462 2463 2464

            // `MaybeConstMaybe` will cause an error during AST validation, but we need to pick a
            // placeholder for compilation to proceed.
D
Dylan MacKenzie 已提交
2465 2466 2467
            TraitBoundModifier::MaybeConstMaybe | TraitBoundModifier::Maybe => {
                hir::TraitBoundModifier::Maybe
            }
2468
        }
2469
    }
2470

2471
    // Helper methods for building HIR.
2472

C
Camille GILLOT 已提交
2473
    fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> {
V
varkor 已提交
2474
        hir::Stmt { span, kind, hir_id: self.next_id() }
2475 2476
    }

C
Camille GILLOT 已提交
2477
    fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> {
C
Camille GILLOT 已提交
2478
        self.stmt(span, hir::StmtKind::Expr(self.arena.alloc(expr)))
2479 2480
    }

N
Niko Matsakis 已提交
2481 2482
    fn stmt_let_pat(
        &mut self,
2483
        attrs: Option<&'hir [Attribute]>,
2484
        span: Span,
C
Camille GILLOT 已提交
2485 2486
        init: Option<&'hir hir::Expr<'hir>>,
        pat: &'hir hir::Pat<'hir>,
N
Niko Matsakis 已提交
2487
        source: hir::LocalSource,
C
Camille GILLOT 已提交
2488
    ) -> hir::Stmt<'hir> {
2489
        let hir_id = self.next_id();
2490 2491 2492 2493
        if let Some(a) = attrs {
            debug_assert!(!a.is_empty());
            self.attrs.insert(hir_id, a);
        }
C
Camille GILLOT 已提交
2494
        let local = hir::Local { hir_id, init, pat, source, span, ty: None };
C
Camille GILLOT 已提交
2495
        self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local)))
2496
    }
L
ljedrz 已提交
2497

C
Camille GILLOT 已提交
2498
    fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
C
Camille GILLOT 已提交
2499
        self.block_all(expr.span, &[], Some(expr))
2500
    }
2501

N
Niko Matsakis 已提交
2502 2503 2504
    fn block_all(
        &mut self,
        span: Span,
C
Camille GILLOT 已提交
2505 2506
        stmts: &'hir [hir::Stmt<'hir>],
        expr: Option<&'hir hir::Expr<'hir>>,
C
Camille GILLOT 已提交
2507 2508
    ) -> &'hir hir::Block<'hir> {
        let blk = hir::Block {
2509 2510
            stmts,
            expr,
L
ljedrz 已提交
2511
            hir_id: self.next_id(),
2512
            rules: hir::BlockCheckMode::DefaultBlock,
2513
            span,
2514
            targeted_by_break: false,
C
Camille GILLOT 已提交
2515 2516
        };
        self.arena.alloc(blk)
2517
    }
2518

2519
    /// Constructs a `true` or `false` literal pattern.
C
Camille GILLOT 已提交
2520
    fn pat_bool(&mut self, span: Span, val: bool) -> &'hir hir::Pat<'hir> {
2521
        let expr = self.expr_bool(span, val);
C
Camille GILLOT 已提交
2522
        self.pat(span, hir::PatKind::Lit(expr))
2523 2524
    }

C
Camille GILLOT 已提交
2525
    fn pat_ok(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
D
David Wood 已提交
2526 2527
        let field = self.single_pat_field(span, pat);
        self.pat_lang_item_variant(span, hir::LangItem::ResultOk, field)
2528
    }
2529

C
Camille GILLOT 已提交
2530
    fn pat_err(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
D
David Wood 已提交
2531 2532
        let field = self.single_pat_field(span, pat);
        self.pat_lang_item_variant(span, hir::LangItem::ResultErr, field)
2533
    }
J
Jorge Aparicio 已提交
2534

C
Camille GILLOT 已提交
2535
    fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
D
David Wood 已提交
2536 2537
        let field = self.single_pat_field(span, pat);
        self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
2538
    }
J
Jorge Aparicio 已提交
2539

C
Camille GILLOT 已提交
2540
    fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
D
David Wood 已提交
2541
        self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
2542
    }
2543

D
David Wood 已提交
2544
    fn single_pat_field(
N
Niko Matsakis 已提交
2545 2546
        &mut self,
        span: Span,
D
David Wood 已提交
2547
        pat: &'hir hir::Pat<'hir>,
2548 2549
    ) -> &'hir [hir::PatField<'hir>] {
        let field = hir::PatField {
D
David Wood 已提交
2550 2551 2552 2553 2554
            hir_id: self.next_id(),
            ident: Ident::new(sym::integer(0), span),
            is_shorthand: false,
            pat,
            span,
2555
        };
D
David Wood 已提交
2556 2557 2558 2559 2560 2561 2562
        arena_vec![self; field]
    }

    fn pat_lang_item_variant(
        &mut self,
        span: Span,
        lang_item: hir::LangItem,
2563
        fields: &'hir [hir::PatField<'hir>],
D
David Wood 已提交
2564 2565 2566
    ) -> &'hir hir::Pat<'hir> {
        let qpath = hir::QPath::LangItem(lang_item, span);
        self.pat(span, hir::PatKind::Struct(qpath, fields, false))
2567
    }
2568

C
Camille GILLOT 已提交
2569
    fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, hir::HirId) {
2570
        self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::Unannotated)
2571
    }
2572

N
Niko Matsakis 已提交
2573 2574 2575
    fn pat_ident_binding_mode(
        &mut self,
        span: Span,
2576
        ident: Ident,
N
Niko Matsakis 已提交
2577
        bm: hir::BindingAnnotation,
C
Camille GILLOT 已提交
2578
    ) -> (&'hir hir::Pat<'hir>, hir::HirId) {
L
ljedrz 已提交
2579
        let hir_id = self.next_id();
N
Nick Cameron 已提交
2580

2581
        (
C
Camille GILLOT 已提交
2582
            self.arena.alloc(hir::Pat {
2583
                hir_id,
V
varkor 已提交
2584
                kind: hir::PatKind::Binding(bm, hir_id, ident.with_span_pos(span), None),
2585
                span,
2586
                default_binding_modes: true,
2587
            }),
M
Mark Rousskov 已提交
2588
            hir_id,
2589
        )
2590
    }
2591

C
Camille GILLOT 已提交
2592
    fn pat_wild(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
2593 2594
        self.pat(span, hir::PatKind::Wild)
    }
2595

C
Camille GILLOT 已提交
2596
    fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611
        self.arena.alloc(hir::Pat {
            hir_id: self.next_id(),
            kind,
            span,
            default_binding_modes: true,
        })
    }

    fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
        self.arena.alloc(hir::Pat {
            hir_id: self.next_id(),
            kind,
            span,
            default_binding_modes: false,
        })
2612
    }
2613

C
Camille GILLOT 已提交
2614 2615 2616 2617 2618 2619
    fn ty_path(
        &mut self,
        mut hir_id: hir::HirId,
        span: Span,
        qpath: hir::QPath<'hir>,
    ) -> hir::Ty<'hir> {
V
varkor 已提交
2620
        let kind = match qpath {
2621
            hir::QPath::Resolved(None, path) => {
C
TyKind  
csmoe 已提交
2622
                // Turn trait object paths into `TyKind::TraitObject` instead.
2623
                match path.res {
2624
                    Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
2625
                        let principal = hir::PolyTraitRef {
C
Camille GILLOT 已提交
2626
                            bound_generic_params: &[],
M
Mark Rousskov 已提交
2627
                            trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
2628 2629
                            span,
                        };
2630

2631 2632
                        // The original ID is taken by the `PolyTraitRef`,
                        // so the `Ty` itself needs a different one.
L
ljedrz 已提交
2633
                        hir_id = self.next_id();
C
Camille GILLOT 已提交
2634 2635 2636
                        hir::TyKind::TraitObject(
                            arena_vec![self; principal],
                            self.elided_dyn_bound(span),
2637
                            TraitObjectSyntax::None,
C
Camille GILLOT 已提交
2638
                        )
2639 2640
                    }
                    _ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
2641 2642
                }
            }
C
TyKind  
csmoe 已提交
2643
            _ => hir::TyKind::Path(qpath),
2644
        };
V
varkor 已提交
2645

M
Mark Rousskov 已提交
2646
        hir::Ty { hir_id, kind, span }
2647
    }
2648

2649 2650 2651
    /// Invoked to create the lifetime argument for a type `&T`
    /// with no explicit lifetime.
    fn elided_ref_lifetime(&mut self, span: Span) -> hir::Lifetime {
2652
        match self.anonymous_lifetime_mode {
2653 2654
            // Intercept when we are in an impl header or async fn and introduce an in-band
            // lifetime.
2655 2656 2657 2658 2659
            // Hence `impl Foo for &u32` becomes `impl<'f> Foo for &'f u32` for some fresh
            // `'f`.
            AnonymousLifetimeMode::CreateParameter => {
                let fresh_name = self.collect_fresh_in_band_lifetime(span);
                hir::Lifetime {
L
ljedrz 已提交
2660
                    hir_id: self.next_id(),
2661
                    span,
2662
                    name: hir::LifetimeName::Param(fresh_name),
2663 2664 2665
                }
            }

2666 2667
            AnonymousLifetimeMode::ReportError => self.new_error_lifetime(None, span),

2668 2669
            AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span),
        }
2670 2671
    }

2672 2673 2674 2675 2676 2677 2678
    /// Report an error on illegal use of `'_` or a `&T` with no explicit lifetime;
    /// return a "error lifetime".
    fn new_error_lifetime(&mut self, id: Option<NodeId>, span: Span) -> hir::Lifetime {
        let (id, msg, label) = match id {
            Some(id) => (id, "`'_` cannot be used here", "`'_` is a reserved lifetime name"),

            None => (
M
Mark Rousskov 已提交
2679
                self.resolver.next_node_id(),
2680 2681 2682 2683 2684
                "`&` without an explicit lifetime name cannot be used here",
                "explicit lifetime name needed here",
            ),
        };

M
Mark Rousskov 已提交
2685
        let mut err = struct_span_err!(self.sess, span, E0637, "{}", msg,);
2686 2687 2688 2689 2690 2691
        err.span_label(span, label);
        err.emit();

        self.new_named_lifetime(id, span, hir::LifetimeName::Error)
    }

2692 2693 2694 2695
    /// Invoked to create the lifetime argument(s) for a path like
    /// `std::cell::Ref<T>`; note that implicit lifetimes in these
    /// sorts of cases are deprecated. This may therefore report a warning or an
    /// error, depending on the mode.
C
Camille GILLOT 已提交
2696 2697 2698 2699 2700 2701
    fn elided_path_lifetimes<'s>(
        &'s mut self,
        span: Span,
        count: usize,
    ) -> impl Iterator<Item = hir::Lifetime> + Captures<'a> + Captures<'s> + Captures<'hir> {
        (0..count).map(move |_| self.elided_path_lifetime(span))
2702 2703 2704
    }

    fn elided_path_lifetime(&mut self, span: Span) -> hir::Lifetime {
2705
        match self.anonymous_lifetime_mode {
2706 2707
            AnonymousLifetimeMode::CreateParameter => {
                // We should have emitted E0726 when processing this path above
M
Mark Rousskov 已提交
2708 2709
                self.sess
                    .delay_span_bug(span, "expected 'implicit elided lifetime not allowed' error");
M
Mark Rousskov 已提交
2710
                let id = self.resolver.next_node_id();
2711 2712
                self.new_named_lifetime(id, span, hir::LifetimeName::Error)
            }
2713 2714 2715 2716 2717 2718
            // `PassThrough` is the normal case.
            // `new_error_lifetime`, which would usually be used in the case of `ReportError`,
            // is unsuitable here, as these can occur from missing lifetime parameters in a
            // `PathSegment`, for which there is no associated `'_` or `&T` with no explicit
            // lifetime. Instead, we simply create an implicit lifetime, which will be checked
            // later, at which point a suitable error will be emitted.
M
Mark Rousskov 已提交
2719 2720 2721
            AnonymousLifetimeMode::PassThrough | AnonymousLifetimeMode::ReportError => {
                self.new_implicit_lifetime(span)
            }
2722
        }
2723 2724 2725 2726 2727 2728 2729
    }

    /// Invoked to create the lifetime argument(s) for an elided trait object
    /// bound, like the bound in `Box<dyn Debug>`. This method is not invoked
    /// when the bound is written, even if it is written with `'_` like in
    /// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked.
    fn elided_dyn_bound(&mut self, span: Span) -> hir::Lifetime {
2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745
        match self.anonymous_lifetime_mode {
            // NB. We intentionally ignore the create-parameter mode here.
            // and instead "pass through" to resolve-lifetimes, which will apply
            // the object-lifetime-defaulting rules. Elided object lifetime defaults
            // do not act like other elided lifetimes. In other words, given this:
            //
            //     impl Foo for Box<dyn Debug>
            //
            // we do not introduce a fresh `'_` to serve as the bound, but instead
            // ultimately translate to the equivalent of:
            //
            //     impl Foo for Box<dyn Debug + 'static>
            //
            // `resolve_lifetime` has the code to make that happen.
            AnonymousLifetimeMode::CreateParameter => {}

2746 2747 2748 2749
            AnonymousLifetimeMode::ReportError => {
                // ReportError applies to explicit use of `'_`.
            }

2750 2751 2752 2753
            // This is the normal case.
            AnonymousLifetimeMode::PassThrough => {}
        }

2754 2755 2756 2757 2758 2759 2760
        let r = hir::Lifetime {
            hir_id: self.next_id(),
            span,
            name: hir::LifetimeName::ImplicitObjectLifetimeDefault,
        };
        debug!("elided_dyn_bound: r={:?}", r);
        r
2761 2762 2763
    }

    fn new_implicit_lifetime(&mut self, span: Span) -> hir::Lifetime {
M
Mark Rousskov 已提交
2764
        hir::Lifetime { hir_id: self.next_id(), span, name: hir::LifetimeName::Implicit }
2765
    }
M
Manish Goregaokar 已提交
2766

2767
    fn maybe_lint_bare_trait(&mut self, span: Span, id: NodeId, is_global: bool) {
2768 2769
        // FIXME(davidtwco): This is a hack to detect macros which produce spans of the
        // call site which do not have a macro backtrace. See #61963.
M
Mark Rousskov 已提交
2770 2771 2772
        let is_macro_callsite = self
            .sess
            .source_map()
2773 2774 2775 2776
            .span_to_snippet(span)
            .map(|snippet| snippet.starts_with("#["))
            .unwrap_or(true);
        if !is_macro_callsite {
2777
            self.resolver.lint_buffer().buffer_lint_with_diagnostic(
M
Mazdak Farrokhzad 已提交
2778
                BARE_TRAIT_OBJECTS,
2779 2780 2781
                id,
                span,
                "trait objects without an explicit `dyn` are deprecated",
2782
                BuiltinLintDiagnostics::BareTraitObject(span, is_global),
2783 2784
            )
        }
M
Manish Goregaokar 已提交
2785
    }
2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805

    fn maybe_lint_missing_abi(&mut self, span: Span, id: NodeId, default: Abi) {
        // FIXME(davidtwco): This is a hack to detect macros which produce spans of the
        // call site which do not have a macro backtrace. See #61963.
        let is_macro_callsite = self
            .sess
            .source_map()
            .span_to_snippet(span)
            .map(|snippet| snippet.starts_with("#["))
            .unwrap_or(true);
        if !is_macro_callsite {
            self.resolver.lint_buffer().buffer_lint_with_diagnostic(
                MISSING_ABI,
                id,
                span,
                "extern declarations without an explicit ABI are deprecated",
                BuiltinLintDiagnostics::MissingAbi(span, default),
            )
        }
    }
2806
}
2807

2808
fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body<'_>>) -> Vec<hir::BodyId> {
2809 2810 2811 2812 2813 2814
    // Sorting by span ensures that we get things in order within a
    // file, and also puts the files in a sensible order.
    let mut body_ids: Vec<_> = bodies.keys().cloned().collect();
    body_ids.sort_by_key(|b| bodies[b].value.span);
    body_ids
}
C
Camille GILLOT 已提交
2815 2816 2817

/// Helper struct for delayed construction of GenericArgs.
struct GenericArgsCtor<'hir> {
C
Camille GILLOT 已提交
2818
    args: SmallVec<[hir::GenericArg<'hir>; 4]>,
C
Camille GILLOT 已提交
2819 2820 2821 2822
    bindings: &'hir [hir::TypeBinding<'hir>],
    parenthesized: bool,
}

2823
impl<'hir> GenericArgsCtor<'hir> {
C
Camille GILLOT 已提交
2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835
    fn is_empty(&self) -> bool {
        self.args.is_empty() && self.bindings.is_empty() && !self.parenthesized
    }

    fn into_generic_args(self, arena: &'hir Arena<'hir>) -> hir::GenericArgs<'hir> {
        hir::GenericArgs {
            args: arena.alloc_from_iter(self.args),
            bindings: self.bindings,
            parenthesized: self.parenthesized,
        }
    }
}