use super::{AnonymousLifetimeMode, LoweringContext, ParamMode};
use super::{ImplTraitContext, ImplTraitPosition, ImplTraitTypeIdVisitor};
use crate::Arena;

use rustc_ast::ast::*;
use rustc_ast::attr;
use rustc_ast::node_id::NodeMap;
use rustc_ast::ptr::P;
use rustc_ast::visit::{self, AssocCtxt, Visitor};
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::LocalDefId;
use rustc_span::source_map::{respan, DesugaringKind};
use rustc_span::symbol::{kw, sym};
use rustc_span::Span;
use rustc_target::spec::abi;

use log::debug;
use smallvec::{smallvec, SmallVec};
use std::collections::BTreeSet;

pub(super) struct ItemLowerer<'a, 'lowering, 'hir> {
    pub(super) lctx: &'a mut LoweringContext<'lowering, 'hir>,
}

impl ItemLowerer<'_, '_, '_> {
    fn with_trait_impl_ref(&mut self, impl_ref: &Option<TraitRef>, f: impl FnOnce(&mut Self)) {
        let old = self.lctx.is_in_trait_impl;
        self.lctx.is_in_trait_impl = if let &None = impl_ref { false } else { true };
        f(self);
        self.lctx.is_in_trait_impl = old;
    }
}

impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
    fn visit_mod(&mut self, m: &'a Mod, _s: Span, _attrs: &[Attribute], n: NodeId) {
        let hir_id = self.lctx.lower_node_id(n);

        self.lctx.modules.insert(
            hir_id,
            hir::ModuleItems {
                items: BTreeSet::new(),
                trait_items: BTreeSet::new(),
                impl_items: BTreeSet::new(),
            },
        );

        let old = self.lctx.current_module;
        self.lctx.current_module = hir_id;
        visit::walk_mod(self, m);
        self.lctx.current_module = old;
    }

    fn visit_item(&mut self, item: &'a Item) {
        let mut item_hir_id = None;
        self.lctx.with_hir_id_owner(item.id, |lctx| {
            lctx.without_in_scope_lifetime_defs(|lctx| {
                if let Some(hir_item) = lctx.lower_item(item) {
                    item_hir_id = Some(hir_item.hir_id);
                    lctx.insert_item(hir_item);
                }
            })
        });

        if let Some(hir_id) = item_hir_id {
            self.lctx.with_parent_item_lifetime_defs(hir_id, |this| {
                let this = &mut ItemLowerer { lctx: this };
                if let ItemKind::Impl { ref of_trait, .. } = item.kind {
                    this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item));
                } else {
                    visit::walk_item(this, item);
                }
            });
        }
    }

    fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
        self.lctx.with_hir_id_owner(item.id, |lctx| match ctxt {
            AssocCtxt::Trait => {
                let hir_item = lctx.lower_trait_item(item);
                let id = hir::TraitItemId { hir_id: hir_item.hir_id };
                lctx.trait_items.insert(id, hir_item);
                lctx.modules.get_mut(&lctx.current_module).unwrap().trait_items.insert(id);
            }
            AssocCtxt::Impl => {
                let hir_item = lctx.lower_impl_item(item);
                let id = hir::ImplItemId { hir_id: hir_item.hir_id };
                lctx.impl_items.insert(id, hir_item);
                lctx.modules.get_mut(&lctx.current_module).unwrap().impl_items.insert(id);
            }
        });

        visit::walk_assoc_item(self, item, ctxt);
    }
}

impl<'hir> LoweringContext<'_, 'hir> {
    // Same as the method above, but accepts `hir::GenericParam`s
    // instead of `ast::GenericParam`s.
    // This should only be used with generics that have already had their
    // in-band lifetimes added. In practice, this means that this function is
    // only used when lowering a child item of a trait or impl.
    fn with_parent_item_lifetime_defs<T>(
        &mut self,
        parent_hir_id: hir::HirId,
        f: impl FnOnce(&mut LoweringContext<'_, '_>) -> T,
    ) -> T {
        let old_len = self.in_scope_lifetimes.len();

        let parent_generics = match self.items.get(&parent_hir_id).unwrap().kind {
            hir::ItemKind::Impl { ref generics, .. }
            | hir::ItemKind::Trait(_, _, ref generics, ..) => &generics.params[..],
            _ => &[],
        };
        let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind {
            hir::GenericParamKind::Lifetime { .. } => Some(param.name.normalize_to_macros_2_0()),
            _ => None,
        });
        self.in_scope_lifetimes.extend(lt_def_names);

        let res = f(self);

        self.in_scope_lifetimes.truncate(old_len);
        res
    }

    // Clears (and restores) the `in_scope_lifetimes` field. Used when
    // visiting nested items, which never inherit in-scope lifetimes
    // from their surrounding environment.
    fn without_in_scope_lifetime_defs<T>(
        &mut self,
        f: impl FnOnce(&mut LoweringContext<'_, '_>) -> T,
    ) -> T {
        let old_in_scope_lifetimes = std::mem::replace(&mut self.in_scope_lifetimes, vec![]);

        // this vector is only used when walking over impl headers,
        // input types, and the like, and should not be non-empty in
        // between items
        assert!(self.lifetimes_to_define.is_empty());

        let res = f(self);

        assert!(self.in_scope_lifetimes.is_empty());
        self.in_scope_lifetimes = old_in_scope_lifetimes;

        res
    }

    pub(super) fn lower_mod(&mut self, m: &Mod) -> hir::Mod<'hir> {
        hir::Mod {
            inner: m.inner,
            item_ids: self
                .arena
                .alloc_from_iter(m.items.iter().flat_map(|x| self.lower_item_id(x))),
        }
    }

    pub(super) fn lower_item_id(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {
        let node_ids = match i.kind {
            ItemKind::Use(ref use_tree) => {
                let mut vec = smallvec![i.id];
                self.lower_item_id_use_tree(use_tree, i.id, &mut vec);
                vec
            }
            ItemKind::MacroDef(..) => SmallVec::new(),
            ItemKind::Fn(..) | ItemKind::Impl { of_trait: None, .. } => smallvec![i.id],
            ItemKind::Static(ref ty, ..) => {
                let mut ids = smallvec![i.id];
                if self.sess.features_untracked().impl_trait_in_bindings {
                    let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
                    visitor.visit_ty(ty);
                }
                ids
            }
            ItemKind::Const(_, ref ty, ..) => {
                let mut ids = smallvec![i.id];
                if self.sess.features_untracked().impl_trait_in_bindings {
                    let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
                    visitor.visit_ty(ty);
                }
                ids
            }
            _ => smallvec![i.id],
        };

        node_ids
            .into_iter()
            .map(|node_id| hir::ItemId { id: self.allocate_hir_id_counter(node_id) })
            .collect()
    }

    fn lower_item_id_use_tree(
        &mut self,
        tree: &UseTree,
        base_id: NodeId,
        vec: &mut SmallVec<[NodeId; 1]>,
    ) {
        match tree.kind {
            UseTreeKind::Nested(ref nested_vec) => {
                for &(ref nested, id) in nested_vec {
                    vec.push(id);
                    self.lower_item_id_use_tree(nested, id, vec);
                }
            }
            UseTreeKind::Glob => {}
            UseTreeKind::Simple(_, id1, id2) => {
                for (_, &id) in
                    self.expect_full_res_from_use(base_id).skip(1).zip([id1, id2].iter())
                {
                    vec.push(id);
                }
            }
        }
    }

    pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item<'hir>> {
        let mut ident = i.ident;
        let mut vis = self.lower_visibility(&i.vis, None);
        let attrs = self.lower_attrs(&i.attrs);

        if let ItemKind::MacroDef(MacroDef { ref body, macro_rules }) = i.kind {
            if !macro_rules || attr::contains_name(&i.attrs, sym::macro_export) {
                let hir_id = self.lower_node_id(i.id);
                let body = P(self.lower_mac_args(body));
                self.exported_macros.push(hir::MacroDef {
                    ident,
                    vis,
                    attrs,
                    hir_id,
                    span: i.span,
                    ast: MacroDef { body, macro_rules },
                });
            } else {
                self.non_exported_macro_attrs.extend(attrs.iter().cloned());
            }
            return None;
        }

        let kind = self.lower_item_kind(i.span, i.id, &mut ident, attrs, &mut vis, &i.kind);

        Some(hir::Item { hir_id: self.lower_node_id(i.id), ident, attrs, kind, vis, span: i.span })
    }

    fn lower_item_kind(
        &mut self,
        span: Span,
        id: NodeId,
        ident: &mut Ident,
        attrs: &'hir [Attribute],
        vis: &mut hir::Visibility<'hir>,
        i: &ItemKind,
    ) -> hir::ItemKind<'hir> {
        match *i {
            ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(orig_name),
            ItemKind::Use(ref use_tree) => {
                // Start with an empty prefix.
                let prefix = Path { segments: vec![], span: use_tree.span };

                self.lower_use_tree(use_tree, &prefix, id, vis, ident, attrs)
            }
            ItemKind::Static(ref t, m, ref e) => {
                let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
                hir::ItemKind::Static(ty, m, body_id)
            }
            ItemKind::Const(_, ref t, ref e) => {
                let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
                hir::ItemKind::Const(ty, body_id)
            }
            ItemKind::Fn(_, FnSig { ref decl, header }, ref generics, ref body) => {
                let fn_def_id = self.resolver.definitions().local_def_id(id).expect_local();
                self.with_new_scopes(|this| {
                    this.current_item = Some(ident.span);

                    // Note: we don't need to change the return type from `T` to
                    // `impl Future<Output = T>` here because lower_body
                    // only cares about the input argument patterns in the function
                    // declaration (decl), not the return types.
                    let asyncness = header.asyncness;
                    let body_id =
                        this.lower_maybe_async_body(span, &decl, asyncness, body.as_deref());

                    let (generics, decl) = this.add_in_band_defs(
                        generics,
                        fn_def_id,
                        AnonymousLifetimeMode::PassThrough,
                        |this, idty| {
                            let ret_id = asyncness.opt_return_id();
                            this.lower_fn_decl(
                                &decl,
                                Some((fn_def_id.to_def_id(), idty)),
                                true,
                                ret_id,
                            )
                        },
                    );
                    let sig = hir::FnSig { decl, header: this.lower_fn_header(header) };
                    hir::ItemKind::Fn(sig, generics, body_id)
                })
            }
            ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
            ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)),
            ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)),
            ItemKind::TyAlias(_, ref gen, _, Some(ref ty)) => match ty.kind.opaque_top_hack() {
                None => {
                    let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
                    let generics = self.lower_generics(gen, ImplTraitContext::disallowed());
                    hir::ItemKind::TyAlias(ty, generics)
                }
                Some(bounds) => {
                    let ctx = || ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc);
                    let ty = hir::OpaqueTy {
                        generics: self.lower_generics(gen, ctx()),
                        bounds: self.lower_param_bounds(bounds, ctx()),
                        impl_trait_fn: None,
                        origin: hir::OpaqueTyOrigin::TypeAlias,
                    };
                    hir::ItemKind::OpaqueTy(ty)
                }
            },
            ItemKind::TyAlias(_, ref generics, _, None) => {
                let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err));
                let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
                hir::ItemKind::TyAlias(ty, generics)
            }
            ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemKind::Enum(
                hir::EnumDef {
                    variants: self.arena.alloc_from_iter(
                        enum_definition.variants.iter().map(|x| self.lower_variant(x)),
                    ),
                },
                self.lower_generics(generics, ImplTraitContext::disallowed()),
            ),
            ItemKind::Struct(ref struct_def, ref generics) => {
                let struct_def = self.lower_variant_data(struct_def);
                hir::ItemKind::Struct(
                    struct_def,
                    self.lower_generics(generics, ImplTraitContext::disallowed()),
                )
            }
            ItemKind::Union(ref vdata, ref generics) => {
                let vdata = self.lower_variant_data(vdata);
                hir::ItemKind::Union(
                    vdata,
                    self.lower_generics(generics, ImplTraitContext::disallowed()),
                )
            }
            ItemKind::Impl {
                unsafety,
                polarity,
                defaultness,
                constness,
                generics: ref ast_generics,
                of_trait: ref trait_ref,
                self_ty: ref ty,
                items: ref impl_items,
            } => {
                let def_id = self.resolver.definitions().local_def_id(id).expect_local();

                // Lower the "impl header" first. This ordering is important
                // for in-band lifetimes! Consider `'a` here:
                //
                //     impl Foo<'a> for u32 {
                //         fn method(&'a self) { .. }
                //     }
                //
                // Because we start by lowering the `Foo<'a> for u32`
                // part, we will add `'a` to the list of generics on
                // the impl. When we then encounter it later in the
                // method, it will not be considered an in-band
                // lifetime to be added, but rather a reference to a
                // parent lifetime.
                let lowered_trait_impl_id = self.lower_node_id(id);
                let (generics, (trait_ref, lowered_ty)) = self.add_in_band_defs(
                    ast_generics,
                    def_id,
                    AnonymousLifetimeMode::CreateParameter,
                    |this, _| {
                        let trait_ref = trait_ref.as_ref().map(|trait_ref| {
                            this.lower_trait_ref(trait_ref, ImplTraitContext::disallowed())
                        });

                        if let Some(ref trait_ref) = trait_ref {
                            if let Res::Def(DefKind::Trait, def_id) = trait_ref.path.res {
                                this.trait_impls
                                    .entry(def_id)
                                    .or_default()
                                    .push(lowered_trait_impl_id);
                            }
                        }

                        let lowered_ty = this.lower_ty(ty, ImplTraitContext::disallowed());

                        (trait_ref, lowered_ty)
                    },
                );

                let new_impl_items =
                    self.with_in_scope_lifetime_defs(&ast_generics.params, |this| {
                        this.arena.alloc_from_iter(
                            impl_items.iter().map(|item| this.lower_impl_item_ref(item)),
                        )
                    });

                // `defaultness.has_value()` is never called for an `impl`, always `true` in order
                // to not cause an assertion failure inside the `lower_defaultness` function.
                let has_val = true;
                let (defaultness, defaultness_span) = self.lower_defaultness(defaultness, has_val);
                hir::ItemKind::Impl {
                    unsafety: self.lower_unsafety(unsafety),
                    polarity,
                    defaultness,
                    defaultness_span,
                    constness: self.lower_constness(constness),
                    generics,
                    of_trait: trait_ref,
                    self_ty: lowered_ty,
                    items: new_impl_items,
                }
            }
            ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => {
                let bounds = self.lower_param_bounds(bounds, ImplTraitContext::disallowed());
                let items = self
                    .arena
                    .alloc_from_iter(items.iter().map(|item| self.lower_trait_item_ref(item)));
                hir::ItemKind::Trait(
                    is_auto,
                    self.lower_unsafety(unsafety),
                    self.lower_generics(generics, ImplTraitContext::disallowed()),
                    bounds,
                    items,
                )
            }
            ItemKind::TraitAlias(ref generics, ref bounds) => hir::ItemKind::TraitAlias(
                self.lower_generics(generics, ImplTraitContext::disallowed()),
                self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
            ),
            ItemKind::MacroDef(..) | ItemKind::MacCall(..) => {
                panic!("`TyMac` should have been expanded by now")
            }
        }
    }

    fn lower_const_item(
        &mut self,
        ty: &Ty,
        span: Span,
        body: Option<&Expr>,
    ) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
        let itctx = if self.sess.features_untracked().impl_trait_in_bindings {
            ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc)
        } else {
            ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
        };
        let ty = self.lower_ty(ty, itctx);
        (ty, self.lower_const_body(span, body))
    }

    fn lower_use_tree(
        &mut self,
        tree: &UseTree,
        prefix: &Path,
        id: NodeId,
        vis: &mut hir::Visibility<'hir>,
        ident: &mut Ident,
        attrs: &'hir [Attribute],
    ) -> hir::ItemKind<'hir> {
        debug!("lower_use_tree(tree={:?})", tree);
        debug!("lower_use_tree: vis = {:?}", vis);

        let path = &tree.prefix;
        let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect();

        match tree.kind {
            UseTreeKind::Simple(rename, id1, id2) => {
                *ident = tree.ident();

                // First, apply the prefix to the path.
                let mut path = Path { segments, span: path.span };

                // Correctly resolve `self` imports.
                if path.segments.len() > 1
                    && path.segments.last().unwrap().ident.name == kw::SelfLower
                {
                    let _ = path.segments.pop();
                    if rename.is_none() {
                        *ident = path.segments.last().unwrap().ident;
                    }
                }

                let mut resolutions = self.expect_full_res_from_use(id);
                // We want to return *something* from this function, so hold onto the first item
                // for later.
                let ret_res = self.lower_res(resolutions.next().unwrap_or(Res::Err));

                // Here, we are looping over namespaces, if they exist for the definition
                // being imported. We only handle type and value namespaces because we
                // won't be dealing with macros in the rest of the compiler.
                // Essentially a single `use` which imports two names is desugared into
                // two imports.
                for (res, &new_node_id) in resolutions.zip([id1, id2].iter()) {
                    let ident = *ident;
                    let mut path = path.clone();
                    for seg in &mut path.segments {
                        seg.id = self.resolver.next_node_id();
                    }
                    let span = path.span;

                    self.with_hir_id_owner(new_node_id, |this| {
                        let new_id = this.lower_node_id(new_node_id);
                        let res = this.lower_res(res);
                        let path = this.lower_path_extra(res, &path, ParamMode::Explicit, None);
                        let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
                        let vis = this.rebuild_vis(&vis);

                        this.insert_item(hir::Item {
                            hir_id: new_id,
                            ident,
                            attrs,
                            kind,
                            vis,
                            span,
                        });
                    });
                }

                let path = self.lower_path_extra(ret_res, &path, ParamMode::Explicit, None);
                hir::ItemKind::Use(path, hir::UseKind::Single)
            }
            UseTreeKind::Glob => {
                let path =
                    self.lower_path(id, &Path { segments, span: path.span }, ParamMode::Explicit);
                hir::ItemKind::Use(path, hir::UseKind::Glob)
            }
            UseTreeKind::Nested(ref trees) => {
                // Nested imports are desugared into simple imports.
                // So, if we start with
                //
                // ```
                // pub(x) use foo::{a, b};
                // ```
                //
                // we will create three items:
                //
                // ```
                // pub(x) use foo::a;
                // pub(x) use foo::b;
                // pub(x) use foo::{}; // <-- this is called the `ListStem`
                // ```
                //
                // The first two are produced by recursively invoking
                // `lower_use_tree` (and indeed there may be things
                // like `use foo::{a::{b, c}}` and so forth).  They
                // wind up being directly added to
                // `self.items`. However, the structure of this
                // function also requires us to return one item, and
                // for that we return the `{}` import (called the
                // `ListStem`).

                let prefix = Path { segments, span: prefix.span.to(path.span) };

                // Add all the nested `PathListItem`s to the HIR.
                for &(ref use_tree, id) in trees {
                    let new_hir_id = self.lower_node_id(id);

                    let mut prefix = prefix.clone();

                    // Give the segments new node-ids since they are being cloned.
                    for seg in &mut prefix.segments {
                        seg.id = self.resolver.next_node_id();
                    }

                    // Each `use` import is an item and thus are owners of the
                    // names in the path. Up to this point the nested import is
                    // the current owner, since we want each desugared import to
                    // own its own names, we have to adjust the owner before
                    // lowering the rest of the import.
                    self.with_hir_id_owner(id, |this| {
                        let mut vis = this.rebuild_vis(&vis);
                        let mut ident = *ident;

                        let kind =
                            this.lower_use_tree(use_tree, &prefix, id, &mut vis, &mut ident, attrs);

                        this.insert_item(hir::Item {
                            hir_id: new_hir_id,
                            ident,
                            attrs,
                            kind,
                            vis,
                            span: use_tree.span,
                        });
                    });
                }

                // Subtle and a bit hacky: we lower the privacy level
                // of the list stem to "private" most of the time, but
                // not for "restricted" paths. The key thing is that
                // we don't want it to stay as `pub` (with no caveats)
                // because that affects rustdoc and also the lints
                // about `pub` items. But we can't *always* make it
                // private -- particularly not for restricted paths --
                // because it contains node-ids that would then be
                // unused, failing the check that HirIds are "densely
                // assigned".
                match vis.node {
                    hir::VisibilityKind::Public
                    | hir::VisibilityKind::Crate(_)
                    | hir::VisibilityKind::Inherited => {
                        *vis = respan(prefix.span.shrink_to_lo(), hir::VisibilityKind::Inherited);
                    }
                    hir::VisibilityKind::Restricted { .. } => {
                        // Do nothing here, as described in the comment on the match.
                    }
                }

                let res = self.expect_full_res_from_use(id).next().unwrap_or(Res::Err);
                let res = self.lower_res(res);
                let path = self.lower_path_extra(res, &prefix, ParamMode::Explicit, None);
                hir::ItemKind::Use(path, hir::UseKind::ListStem)
            }
        }
    }

    /// Paths like the visibility path in `pub(super) use foo::{bar, baz}` are repeated
    /// many times in the HIR tree; for each occurrence, we need to assign distinct
    /// `NodeId`s. (See, e.g., #56128.)
    fn rebuild_use_path(&mut self, path: &hir::Path<'hir>) -> &'hir hir::Path<'hir> {
        debug!("rebuild_use_path(path = {:?})", path);
        let segments =
            self.arena.alloc_from_iter(path.segments.iter().map(|seg| hir::PathSegment {
                ident: seg.ident,
                hir_id: seg.hir_id.map(|_| self.next_id()),
                res: seg.res,
                args: None,
                infer_args: seg.infer_args,
            }));
        self.arena.alloc(hir::Path { span: path.span, res: path.res, segments })
    }

    fn rebuild_vis(&mut self, vis: &hir::Visibility<'hir>) -> hir::Visibility<'hir> {
        let vis_kind = match vis.node {
            hir::VisibilityKind::Public => hir::VisibilityKind::Public,
            hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
            hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
            hir::VisibilityKind::Restricted { ref path, hir_id: _ } => {
                hir::VisibilityKind::Restricted {
                    path: self.rebuild_use_path(path),
                    hir_id: self.next_id(),
                }
            }
        };
        respan(vis.span, vis_kind)
    }

    fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem<'hir> {
        let def_id = self.resolver.definitions().local_def_id(i.id).expect_local();
        hir::ForeignItem {
            hir_id: self.lower_node_id(i.id),
            ident: i.ident,
            attrs: self.lower_attrs(&i.attrs),
            kind: match i.kind {
                ForeignItemKind::Fn(_, ref sig, ref generics, _) => {
                    let fdec = &sig.decl;
                    let (generics, (fn_dec, fn_args)) = self.add_in_band_defs(
                        generics,
                        def_id,
                        AnonymousLifetimeMode::PassThrough,
                        |this, _| {
                            (
                                // Disallow `impl Trait` in foreign items.
                                this.lower_fn_decl(fdec, None, false, None),
                                this.lower_fn_params_to_names(fdec),
                            )
                        },
                    );

                    hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
                }
                ForeignItemKind::Static(ref t, m, _) => {
                    let ty = self.lower_ty(t, ImplTraitContext::disallowed());
                    hir::ForeignItemKind::Static(ty, m)
                }
                ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
                ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
            },
            vis: self.lower_visibility(&i.vis, None),
            span: i.span,
        }
    }

    fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod<'hir> {
        hir::ForeignMod {
            abi: fm.abi.map_or(abi::Abi::C, |abi| self.lower_abi(abi)),
            items: self.arena.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item(x))),
        }
    }

    fn lower_global_asm(&mut self, ga: &GlobalAsm) -> &'hir hir::GlobalAsm {
        self.arena.alloc(hir::GlobalAsm { asm: ga.asm })
    }

    fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> {
        hir::Variant {
            attrs: self.lower_attrs(&v.attrs),
            data: self.lower_variant_data(&v.data),
            disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const(e)),
            id: self.lower_node_id(v.id),
            ident: v.ident,
            span: v.span,
        }
    }

    fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData<'hir> {
        match *vdata {
            VariantData::Struct(ref fields, recovered) => hir::VariantData::Struct(
                self.arena
                    .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_struct_field(f))),
                recovered,
            ),
            VariantData::Tuple(ref fields, id) => hir::VariantData::Tuple(
                self.arena
                    .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_struct_field(f))),
                self.lower_node_id(id),
            ),
            VariantData::Unit(id) => hir::VariantData::Unit(self.lower_node_id(id)),
        }
    }

    fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::StructField<'hir> {
        let ty = if let TyKind::Path(ref qself, ref path) = f.ty.kind {
            let t = self.lower_path_ty(
                &f.ty,
                qself,
                path,
                ParamMode::ExplicitNamed, // no `'_` in declarations (Issue #61124)
                ImplTraitContext::disallowed(),
            );
            self.arena.alloc(t)
        } else {
            self.lower_ty(&f.ty, ImplTraitContext::disallowed())
        };
        hir::StructField {
            span: f.span,
            hir_id: self.lower_node_id(f.id),
            ident: match f.ident {
                Some(ident) => ident,
                // FIXME(jseyfried): positional field hygiene.
                None => Ident::new(sym::integer(index), f.span),
            },
            vis: self.lower_visibility(&f.vis, None),
            ty,
            attrs: self.lower_attrs(&f.attrs),
        }
    }

    fn lower_trait_item(&mut self, i: &AssocItem) -> hir::TraitItem<'hir> {
        let trait_item_def_id = self.resolver.definitions().local_def_id(i.id).expect_local();

        let (generics, kind) = match i.kind {
            AssocItemKind::Const(_, ref ty, ref default) => {
                let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
                let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x)));
                (hir::Generics::empty(), hir::TraitItemKind::Const(ty, body))
            }
            AssocItemKind::Fn(_, ref sig, ref generics, None) => {
                let names = self.lower_fn_params_to_names(&sig.decl);
                let (generics, sig) =
                    self.lower_method_sig(generics, sig, trait_item_def_id, false, None);
                (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)))
            }
            AssocItemKind::Fn(_, ref sig, ref generics, Some(ref body)) => {
                let body_id = self.lower_fn_body_block(i.span, &sig.decl, Some(body));
                let (generics, sig) =
                    self.lower_method_sig(generics, sig, trait_item_def_id, false, None);
                (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)))
            }
            AssocItemKind::TyAlias(_, ref generics, ref bounds, ref default) => {
                let ty = default.as_ref().map(|x| self.lower_ty(x, ImplTraitContext::disallowed()));
                let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
                let kind = hir::TraitItemKind::Type(
                    self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
                    ty,
                );

                (generics, kind)
            }
            AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"),
        };

        hir::TraitItem {
            hir_id: self.lower_node_id(i.id),
            ident: i.ident,
            attrs: self.lower_attrs(&i.attrs),
            generics,
            kind,
            span: i.span,
        }
    }

    fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
        let (kind, has_default) = match &i.kind {
            AssocItemKind::Const(_, _, default) => (hir::AssocItemKind::Const, default.is_some()),
            AssocItemKind::TyAlias(_, _, _, default) => {
                (hir::AssocItemKind::Type, default.is_some())
            }
            AssocItemKind::Fn(_, sig, _, default) => {
                (hir::AssocItemKind::Method { has_self: sig.decl.has_self() }, default.is_some())
            }
            AssocItemKind::MacCall(..) => unimplemented!(),
        };
        let id = hir::TraitItemId { hir_id: self.lower_node_id(i.id) };
        let defaultness = hir::Defaultness::Default { has_value: has_default };
        hir::TraitItemRef { id, ident: i.ident, span: i.span, defaultness, kind }
    }

    /// Construct `ExprKind::Err` for the given `span`.
    crate fn expr_err(&mut self, span: Span) -> hir::Expr<'hir> {
        self.expr(span, hir::ExprKind::Err, AttrVec::new())
    }

    fn lower_impl_item(&mut self, i: &AssocItem) -> hir::ImplItem<'hir> {
        let impl_item_def_id = self.resolver.definitions().local_def_id(i.id).expect_local();

        let (generics, kind) = match &i.kind {
            AssocItemKind::Const(_, ty, expr) => {
                let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
                (
                    hir::Generics::empty(),
                    hir::ImplItemKind::Const(ty, self.lower_const_body(i.span, expr.as_deref())),
                )
            }
            AssocItemKind::Fn(_, sig, generics, body) => {
                self.current_item = Some(i.span);
                let asyncness = sig.header.asyncness;
                let body_id =
                    self.lower_maybe_async_body(i.span, &sig.decl, asyncness, body.as_deref());
                let impl_trait_return_allow = !self.is_in_trait_impl;
                let (generics, sig) = self.lower_method_sig(
                    generics,
                    sig,
                    impl_item_def_id,
                    impl_trait_return_allow,
                    asyncness.opt_return_id(),
                );

                (generics, hir::ImplItemKind::Fn(sig, body_id))
            }
            AssocItemKind::TyAlias(_, generics, _, ty) => {
                let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
                let kind = match ty {
                    None => {
                        let ty = self.arena.alloc(self.ty(i.span, hir::TyKind::Err));
                        hir::ImplItemKind::TyAlias(ty)
                    }
                    Some(ty) => match ty.kind.opaque_top_hack() {
                        None => {
                            let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
                            hir::ImplItemKind::TyAlias(ty)
                        }
                        Some(bs) => {
                            let bs = self.lower_param_bounds(bs, ImplTraitContext::disallowed());
                            hir::ImplItemKind::OpaqueTy(bs)
                        }
                    },
                };
                (generics, kind)
            }
            AssocItemKind::MacCall(..) => panic!("`TyMac` should have been expanded by now"),
        };

        // Since `default impl` is not yet implemented, this is always true in impls.
        let has_value = true;
        let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
        hir::ImplItem {
            hir_id: self.lower_node_id(i.id),
            ident: i.ident,
            attrs: self.lower_attrs(&i.attrs),
            generics,
            vis: self.lower_visibility(&i.vis, None),
            defaultness,
            kind,
            span: i.span,
        }
    }

    fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef<'hir> {
        // Since `default impl` is not yet implemented, this is always true in impls.
        let has_value = true;
        let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
        hir::ImplItemRef {
            id: hir::ImplItemId { hir_id: self.lower_node_id(i.id) },
            ident: i.ident,
            span: i.span,
            vis: self.lower_visibility(&i.vis, Some(i.id)),
            defaultness,
            kind: match &i.kind {
                AssocItemKind::Const(..) => hir::AssocItemKind::Const,
                AssocItemKind::TyAlias(.., ty) => {
                    match ty.as_deref().and_then(|ty| ty.kind.opaque_top_hack()) {
                        None => hir::AssocItemKind::Type,
                        Some(_) => hir::AssocItemKind::OpaqueTy,
                    }
                }
                AssocItemKind::Fn(_, sig, ..) => {
                    hir::AssocItemKind::Method { has_self: sig.decl.has_self() }
                }
                AssocItemKind::MacCall(..) => unimplemented!(),
            },
        }
    }

    /// If an `explicit_owner` is given, this method allocates the `HirId` in
    /// the address space of that item instead of the item currently being
    /// lowered. This can happen during `lower_impl_item_ref()` where we need to
    /// lower a `Visibility` value although we haven't lowered the owning
    /// `ImplItem` in question yet.
    fn lower_visibility(
        &mut self,
        v: &Visibility,
        explicit_owner: Option<NodeId>,
    ) -> hir::Visibility<'hir> {
        let node = match v.node {
            VisibilityKind::Public => hir::VisibilityKind::Public,
            VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
            VisibilityKind::Restricted { ref path, id } => {
                debug!("lower_visibility: restricted path id = {:?}", id);
                let lowered_id = if let Some(owner) = explicit_owner {
                    self.lower_node_id_with_owner(id, owner)
                } else {
                    self.lower_node_id(id)
                };
                let res = self.expect_full_res(id);
                let res = self.lower_res(res);
                hir::VisibilityKind::Restricted {
                    path: self.lower_path_extra(res, path, ParamMode::Explicit, explicit_owner),
                    hir_id: lowered_id,
                }
            }
            VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
        };
        respan(v.span, node)
    }

    fn lower_defaultness(
        &self,
        d: Defaultness,
        has_value: bool,
    ) -> (hir::Defaultness, Option<Span>) {
        match d {
            Defaultness::Default(sp) => (hir::Defaultness::Default { has_value }, Some(sp)),
            Defaultness::Final => {
                assert!(has_value);
                (hir::Defaultness::Final, None)
            }
        }
    }

    fn record_body(
        &mut self,
        params: &'hir [hir::Param<'hir>],
        value: hir::Expr<'hir>,
    ) -> hir::BodyId {
        let body = hir::Body { generator_kind: self.generator_kind, params, value };
        let id = body.id();
        self.bodies.insert(id, body);
        id
    }

    pub(super) fn lower_body(
        &mut self,
        f: impl FnOnce(&mut Self) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>),
    ) -> hir::BodyId {
        let prev_gen_kind = self.generator_kind.take();
        let (parameters, result) = f(self);
        let body_id = self.record_body(parameters, result);
        self.generator_kind = prev_gen_kind;
        body_id
    }

    fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
        hir::Param {
            attrs: self.lower_attrs(&param.attrs),
            hir_id: self.lower_node_id(param.id),
            pat: self.lower_pat(&param.pat),
            span: param.span,
        }
    }

    pub(super) fn lower_fn_body(
        &mut self,
        decl: &FnDecl,
        body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
    ) -> hir::BodyId {
        self.lower_body(|this| {
            (
                this.arena.alloc_from_iter(decl.inputs.iter().map(|x| this.lower_param(x))),
                body(this),
            )
        })
    }

    fn lower_fn_body_block(
        &mut self,
        span: Span,
        decl: &FnDecl,
        body: Option<&Block>,
    ) -> hir::BodyId {
        self.lower_fn_body(decl, |this| this.lower_block_expr_opt(span, body))
    }

    fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr<'hir> {
        match block {
            Some(block) => self.lower_block_expr(block),
            None => self.expr_err(span),
        }
    }

    pub(super) fn lower_const_body(&mut self, span: Span, expr: Option<&Expr>) -> hir::BodyId {
        self.lower_body(|this| {
            (
                &[],
                match expr {
                    Some(expr) => this.lower_expr_mut(expr),
                    None => this.expr_err(span),
                },
            )
        })
    }

    fn lower_maybe_async_body(
        &mut self,
        span: Span,
        decl: &FnDecl,
        asyncness: Async,
        body: Option<&Block>,
    ) -> hir::BodyId {
        let closure_id = match asyncness {
            Async::Yes { closure_id, .. } => closure_id,
            Async::No => return self.lower_fn_body_block(span, decl, body),
        };

        self.lower_body(|this| {
            let mut parameters: Vec<hir::Param<'_>> = Vec::new();
            let mut statements: Vec<hir::Stmt<'_>> = Vec::new();

            // Async function parameters are lowered into the closure body so that they are
            // captured and so that the drop order matches the equivalent non-async functions.
            //
            // from:
            //
            //     async fn foo(<pattern>: <ty>, <pattern>: <ty>, <pattern>: <ty>) {
            //         <body>
            //     }
            //
            // into:
            //
            //     fn foo(__arg0: <ty>, __arg1: <ty>, __arg2: <ty>) {
            //       async move {
            //         let __arg2 = __arg2;
            //         let <pattern> = __arg2;
            //         let __arg1 = __arg1;
            //         let <pattern> = __arg1;
            //         let __arg0 = __arg0;
            //         let <pattern> = __arg0;
            //         drop-temps { <body> } // see comments later in fn for details
            //       }
            //     }
            //
            // If `<pattern>` is a simple ident, then it is lowered to a single
            // `let <pattern> = <pattern>;` statement as an optimization.
            //
            // Note that the body is embedded in `drop-temps`; an
            // equivalent desugaring would be `return { <body>
            // };`. The key point is that we wish to drop all the
            // let-bound variables and temporaries created in the body
            // (and its tail expression!) before we drop the
            // parameters (c.f. rust-lang/rust#64512).
            for (index, parameter) in decl.inputs.iter().enumerate() {
                let parameter = this.lower_param(parameter);
                let span = parameter.pat.span;

                // Check if this is a binding pattern, if so, we can optimize and avoid adding a
                // `let <pat> = __argN;` statement. In this case, we do not rename the parameter.
                let (ident, is_simple_parameter) = match parameter.pat.kind {
                    hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, _) => {
                        (ident, true)
                    }
                    _ => {
                        // Replace the ident for bindings that aren't simple.
                        let name = format!("__arg{}", index);
                        let ident = Ident::from_str(&name);

                        (ident, false)
                    }
                };

                let desugared_span = this.mark_span_with_reason(DesugaringKind::Async, span, None);

                // Construct a parameter representing `__argN: <ty>` to replace the parameter of the
                // async function.
                //
                // If this is the simple case, this parameter will end up being the same as the
                // original parameter, but with a different pattern id.
                let mut stmt_attrs = AttrVec::new();
                stmt_attrs.extend(parameter.attrs.iter().cloned());
                let (new_parameter_pat, new_parameter_id) = this.pat_ident(desugared_span, ident);
                let new_parameter = hir::Param {
                    attrs: parameter.attrs,
                    hir_id: parameter.hir_id,
                    pat: new_parameter_pat,
                    span: parameter.span,
                };

                if is_simple_parameter {
                    // If this is the simple case, then we only insert one statement that is
                    // `let <pat> = <pat>;`. We re-use the original argument's pattern so that
                    // `HirId`s are densely assigned.
                    let expr = this.expr_ident(desugared_span, ident, new_parameter_id);
                    let stmt = this.stmt_let_pat(
                        stmt_attrs,
                        desugared_span,
                        Some(expr),
                        parameter.pat,
                        hir::LocalSource::AsyncFn,
                    );
                    statements.push(stmt);
                } else {
                    // If this is not the simple case, then we construct two statements:
                    //
                    // ```
                    // let __argN = __argN;
                    // let <pat> = __argN;
                    // ```
                    //
                    // The first statement moves the parameter into the closure and thus ensures
                    // that the drop order is correct.
                    //
                    // The second statement creates the bindings that the user wrote.

                    // Construct the `let mut __argN = __argN;` statement. It must be a mut binding
                    // because the user may have specified a `ref mut` binding in the next
                    // statement.
                    let (move_pat, move_id) = this.pat_ident_binding_mode(
                        desugared_span,
                        ident,
                        hir::BindingAnnotation::Mutable,
                    );
                    let move_expr = this.expr_ident(desugared_span, ident, new_parameter_id);
                    let move_stmt = this.stmt_let_pat(
                        AttrVec::new(),
                        desugared_span,
                        Some(move_expr),
                        move_pat,
                        hir::LocalSource::AsyncFn,
                    );

                    // Construct the `let <pat> = __argN;` statement. We re-use the original
                    // parameter's pattern so that `HirId`s are densely assigned.
                    let pattern_expr = this.expr_ident(desugared_span, ident, move_id);
                    let pattern_stmt = this.stmt_let_pat(
                        stmt_attrs,
                        desugared_span,
                        Some(pattern_expr),
                        parameter.pat,
                        hir::LocalSource::AsyncFn,
                    );

                    statements.push(move_stmt);
                    statements.push(pattern_stmt);
                };

                parameters.push(new_parameter);
            }

            let body_span = body.map_or(span, |b| b.span);
            let async_expr = this.make_async_expr(
                CaptureBy::Value,
                closure_id,
                None,
                body_span,
                hir::AsyncGeneratorKind::Fn,
                |this| {
                    // Create a block from the user's function body:
                    let user_body = this.lower_block_expr_opt(body_span, body);

                    // Transform into `drop-temps { <user-body> }`, an expression:
                    let desugared_span =
                        this.mark_span_with_reason(DesugaringKind::Async, user_body.span, None);
                    let user_body = this.expr_drop_temps(
                        desugared_span,
                        this.arena.alloc(user_body),
                        AttrVec::new(),
                    );

                    // As noted above, create the final block like
                    //
                    // ```
                    // {
                    //   let $param_pattern = $raw_param;
                    //   ...
                    //   drop-temps { <user-body> }
                    // }
                    // ```
                    let body = this.block_all(
                        desugared_span,
                        this.arena.alloc_from_iter(statements),
                        Some(user_body),
                    );

                    this.expr_block(body, AttrVec::new())
                },
            );

            (
                this.arena.alloc_from_iter(parameters),
                this.expr(body_span, async_expr, AttrVec::new()),
            )
        })
    }

    fn lower_method_sig(
        &mut self,
        generics: &Generics,
        sig: &FnSig,
        fn_def_id: LocalDefId,
        impl_trait_return_allow: bool,
        is_async: Option<NodeId>,
    ) -> (hir::Generics<'hir>, hir::FnSig<'hir>) {
        let header = self.lower_fn_header(sig.header);
        let (generics, decl) = self.add_in_band_defs(
            generics,
            fn_def_id,
            AnonymousLifetimeMode::PassThrough,
            |this, idty| {
                this.lower_fn_decl(
                    &sig.decl,
                    Some((fn_def_id.to_def_id(), idty)),
                    impl_trait_return_allow,
                    is_async,
                )
            },
        );
        (generics, hir::FnSig { header, decl })
    }

    fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
        hir::FnHeader {
            unsafety: self.lower_unsafety(h.unsafety),
            asyncness: self.lower_asyncness(h.asyncness),
            constness: self.lower_constness(h.constness),
            abi: self.lower_extern(h.ext),
        }
    }

    pub(super) fn lower_abi(&mut self, abi: StrLit) -> abi::Abi {
        abi::lookup(&abi.symbol_unescaped.as_str()).unwrap_or_else(|| {
            self.error_on_invalid_abi(abi);
            abi::Abi::Rust
        })
    }

    pub(super) fn lower_extern(&mut self, ext: Extern) -> abi::Abi {
        match ext {
            Extern::None => abi::Abi::Rust,
            Extern::Implicit => abi::Abi::C,
            Extern::Explicit(abi) => self.lower_abi(abi),
        }
    }

    fn error_on_invalid_abi(&self, abi: StrLit) {
        struct_span_err!(self.sess, abi.span, E0703, "invalid ABI: found `{}`", abi.symbol)
            .span_label(abi.span, "invalid ABI")
            .help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
            .emit();
    }

    fn lower_asyncness(&mut self, a: Async) -> hir::IsAsync {
        match a {
            Async::Yes { .. } => hir::IsAsync::Async,
            Async::No => hir::IsAsync::NotAsync,
        }
    }

    fn lower_constness(&mut self, c: Const) -> hir::Constness {
        match c {
            Const::Yes(_) => hir::Constness::Const,
            Const::No => hir::Constness::NotConst,
        }
    }

    pub(super) fn lower_unsafety(&mut self, u: Unsafe) -> hir::Unsafety {
        match u {
            Unsafe::Yes(_) => hir::Unsafety::Unsafe,
            Unsafe::No => hir::Unsafety::Normal,
        }
    }

    pub(super) fn lower_generics_mut(
        &mut self,
        generics: &Generics,
        itctx: ImplTraitContext<'_, 'hir>,
    ) -> GenericsCtor<'hir> {
        // Collect `?Trait` bounds in where clause and move them to parameter definitions.
        // FIXME: this could probably be done with less rightward drift. It also looks like two
        // control paths where `report_error` is called are the only paths that advance to after the
        // match statement, so the error reporting could probably just be moved there.
        let mut add_bounds: NodeMap<Vec<_>> = Default::default();
        for pred in &generics.where_clause.predicates {
            if let WherePredicate::BoundPredicate(ref bound_pred) = *pred {
                'next_bound: for bound in &bound_pred.bounds {
                    if let GenericBound::Trait(_, TraitBoundModifier::Maybe) = *bound {
                        let report_error = |this: &mut Self| {
                            this.diagnostic().span_err(
                                bound_pred.bounded_ty.span,
                                "`?Trait` bounds are only permitted at the \
                                 point where a type parameter is declared",
                            );
                        };
                        // Check if the where clause type is a plain type parameter.
                        match bound_pred.bounded_ty.kind {
                            TyKind::Path(None, ref path)
                                if path.segments.len() == 1
                                    && bound_pred.bound_generic_params.is_empty() =>
                            {
                                if let Some(Res::Def(DefKind::TyParam, def_id)) = self
                                    .resolver
                                    .get_partial_res(bound_pred.bounded_ty.id)
                                    .map(|d| d.base_res())
                                {
                                    if let Some(node_id) =
                                        self.resolver.definitions().as_local_node_id(def_id)
                                    {
                                        for param in &generics.params {
                                            if let GenericParamKind::Type { .. } = param.kind {
                                                if node_id == param.id {
                                                    add_bounds
                                                        .entry(param.id)
                                                        .or_default()
                                                        .push(bound.clone());
                                                    continue 'next_bound;
                                                }
                                            }
                                        }
                                    }
                                }
                                report_error(self)
                            }
                            _ => report_error(self),
                        }
                    }
                }
            }
        }

        GenericsCtor {
            params: self.lower_generic_params_mut(&generics.params, &add_bounds, itctx).collect(),
            where_clause: self.lower_where_clause(&generics.where_clause),
            span: generics.span,
        }
    }

    pub(super) fn lower_generics(
        &mut self,
        generics: &Generics,
        itctx: ImplTraitContext<'_, 'hir>,
    ) -> hir::Generics<'hir> {
        let generics_ctor = self.lower_generics_mut(generics, itctx);
        generics_ctor.into_generics(self.arena)
    }

    fn lower_where_clause(&mut self, wc: &WhereClause) -> hir::WhereClause<'hir> {
        self.with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
            hir::WhereClause {
                predicates: this.arena.alloc_from_iter(
                    wc.predicates.iter().map(|predicate| this.lower_where_predicate(predicate)),
                ),
                span: wc.span,
            }
        })
    }

    fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
        match *pred {
            WherePredicate::BoundPredicate(WhereBoundPredicate {
                ref bound_generic_params,
                ref bounded_ty,
                ref bounds,
                span,
            }) => {
                self.with_in_scope_lifetime_defs(&bound_generic_params, |this| {
                    hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
                        bound_generic_params: this.lower_generic_params(
                            bound_generic_params,
                            &NodeMap::default(),
                            ImplTraitContext::disallowed(),
                        ),
                        bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::disallowed()),
                        bounds: this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| {
                            match *bound {
                                // Ignore `?Trait` bounds.
                                // They were copied into type parameters already.
                                GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
                                _ => Some(
                                    this.lower_param_bound(bound, ImplTraitContext::disallowed()),
                                ),
                            }
                        })),
                        span,
                    })
                })
            }
            WherePredicate::RegionPredicate(WhereRegionPredicate {
                ref lifetime,
                ref bounds,
                span,
            }) => hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
                span,
                lifetime: self.lower_lifetime(lifetime),
                bounds: self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
            }),
            WherePredicate::EqPredicate(WhereEqPredicate { id, ref lhs_ty, ref rhs_ty, span }) => {
                hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
                    hir_id: self.lower_node_id(id),
                    lhs_ty: self.lower_ty(lhs_ty, ImplTraitContext::disallowed()),
                    rhs_ty: self.lower_ty(rhs_ty, ImplTraitContext::disallowed()),
                    span,
                })
            }
        }
    }
}

/// Helper struct for delayed construction of Generics.
pub(super) struct GenericsCtor<'hir> {
    pub(super) params: SmallVec<[hir::GenericParam<'hir>; 4]>,
    where_clause: hir::WhereClause<'hir>,
    span: Span,
}

impl<'hir> GenericsCtor<'hir> {
    pub(super) fn into_generics(self, arena: &'hir Arena<'hir>) -> hir::Generics<'hir> {
        hir::Generics {
            params: arena.alloc_from_iter(self.params),
            where_clause: self.where_clause,
            span: self.span,
        }
    }
}
