1 use super::{AnonymousLifetimeMode, LoweringContext, ParamMode}
;
2 use super::{ImplTraitContext, ImplTraitPosition}
;
5 use rustc_ast
::node_id
::NodeMap
;
7 use rustc_ast
::visit
::{self, AssocCtxt, FnCtxt, FnKind, Visitor}
;
9 use rustc_data_structures
::fx
::FxHashSet
;
10 use rustc_errors
::struct_span_err
;
12 use rustc_hir
::def
::{DefKind, Res}
;
13 use rustc_hir
::def_id
::LocalDefId
;
14 use rustc_span
::source_map
::{respan, DesugaringKind}
;
15 use rustc_span
::symbol
::{kw, sym, Ident}
;
17 use rustc_target
::spec
::abi
;
18 use smallvec
::{smallvec, SmallVec}
;
24 pub(super) struct ItemLowerer
<'a
, 'lowering
, 'hir
> {
25 pub(super) lctx
: &'a
mut LoweringContext
<'lowering
, 'hir
>,
28 impl ItemLowerer
<'_
, '_
, '_
> {
29 fn with_trait_impl_ref(&mut self, impl_ref
: &Option
<TraitRef
>, f
: impl FnOnce(&mut Self)) {
30 let old
= self.lctx
.is_in_trait_impl
;
31 self.lctx
.is_in_trait_impl
= impl_ref
.is_some();
33 self.lctx
.is_in_trait_impl
= old
;
37 impl<'a
> Visitor
<'a
> for ItemLowerer
<'a
, '_
, '_
> {
38 fn visit_item(&mut self, item
: &'a Item
) {
39 let mut item_hir_id
= None
;
40 self.lctx
.with_hir_id_owner(item
.id
, |lctx
| {
41 lctx
.without_in_scope_lifetime_defs(|lctx
| {
42 if let Some(hir_item
) = lctx
.lower_item(item
) {
43 let id
= lctx
.insert_item(hir_item
);
44 item_hir_id
= Some(id
);
49 if let Some(hir_id
) = item_hir_id
{
50 self.lctx
.with_parent_item_lifetime_defs(hir_id
, |this
| {
51 let this
= &mut ItemLowerer { lctx: this }
;
53 ItemKind
::Mod(..) => {
54 let def_id
= this
.lctx
.lower_node_id(item
.id
).expect_owner();
55 let old_current_module
=
56 mem
::replace(&mut this
.lctx
.current_module
, def_id
);
57 visit
::walk_item(this
, item
);
58 this
.lctx
.current_module
= old_current_module
;
60 ItemKind
::Impl(box ImplKind { ref of_trait, .. }
) => {
61 this
.with_trait_impl_ref(of_trait
, |this
| visit
::walk_item(this
, item
));
63 _
=> visit
::walk_item(this
, item
),
69 fn visit_fn(&mut self, fk
: FnKind
<'a
>, sp
: Span
, _
: NodeId
) {
71 FnKind
::Fn(FnCtxt
::Foreign
, _
, sig
, _
, _
) => {
72 self.visit_fn_header(&sig
.header
);
73 visit
::walk_fn_decl(self, &sig
.decl
);
74 // Don't visit the foreign function body even if it has one, since lowering the
75 // body would have no meaning and will have already been caught as a parse error.
77 _
=> visit
::walk_fn(self, fk
, sp
),
81 fn visit_assoc_item(&mut self, item
: &'a AssocItem
, ctxt
: AssocCtxt
) {
82 self.lctx
.with_hir_id_owner(item
.id
, |lctx
| match ctxt
{
84 let hir_item
= lctx
.lower_trait_item(item
);
85 let id
= hir_item
.trait_item_id();
86 lctx
.trait_items
.insert(id
, hir_item
);
87 lctx
.modules
.entry(lctx
.current_module
).or_default().trait_items
.insert(id
);
90 let hir_item
= lctx
.lower_impl_item(item
);
91 let id
= hir_item
.impl_item_id();
92 lctx
.impl_items
.insert(id
, hir_item
);
93 lctx
.modules
.entry(lctx
.current_module
).or_default().impl_items
.insert(id
);
97 visit
::walk_assoc_item(self, item
, ctxt
);
100 fn visit_foreign_item(&mut self, item
: &'a ForeignItem
) {
101 self.lctx
.allocate_hir_id_counter(item
.id
);
102 self.lctx
.with_hir_id_owner(item
.id
, |lctx
| {
103 let hir_item
= lctx
.lower_foreign_item(item
);
104 let id
= hir_item
.foreign_item_id();
105 lctx
.foreign_items
.insert(id
, hir_item
);
106 lctx
.modules
.entry(lctx
.current_module
).or_default().foreign_items
.insert(id
);
109 visit
::walk_foreign_item(self, item
);
113 impl<'hir
> LoweringContext
<'_
, 'hir
> {
114 // Same as the method above, but accepts `hir::GenericParam`s
115 // instead of `ast::GenericParam`s.
116 // This should only be used with generics that have already had their
117 // in-band lifetimes added. In practice, this means that this function is
118 // only used when lowering a child item of a trait or impl.
119 fn with_parent_item_lifetime_defs
<T
>(
121 parent_hir_id
: hir
::ItemId
,
122 f
: impl FnOnce(&mut LoweringContext
<'_
, '_
>) -> T
,
124 let old_len
= self.in_scope_lifetimes
.len();
126 let parent_generics
= match self.items
.get(&parent_hir_id
).unwrap().kind
{
127 hir
::ItemKind
::Impl(hir
::Impl { ref generics, .. }
)
128 | hir
::ItemKind
::Trait(_
, _
, ref generics
, ..) => generics
.params
,
131 let lt_def_names
= parent_generics
.iter().filter_map(|param
| match param
.kind
{
132 hir
::GenericParamKind
::Lifetime { .. }
=> Some(param
.name
.normalize_to_macros_2_0()),
135 self.in_scope_lifetimes
.extend(lt_def_names
);
139 self.in_scope_lifetimes
.truncate(old_len
);
143 // Clears (and restores) the `in_scope_lifetimes` field. Used when
144 // visiting nested items, which never inherit in-scope lifetimes
145 // from their surrounding environment.
146 fn without_in_scope_lifetime_defs
<T
>(
148 f
: impl FnOnce(&mut LoweringContext
<'_
, '_
>) -> T
,
150 let old_in_scope_lifetimes
= mem
::replace(&mut self.in_scope_lifetimes
, vec
![]);
152 // this vector is only used when walking over impl headers,
153 // input types, and the like, and should not be non-empty in
155 assert
!(self.lifetimes_to_define
.is_empty());
159 assert
!(self.in_scope_lifetimes
.is_empty());
160 self.in_scope_lifetimes
= old_in_scope_lifetimes
;
165 pub(super) fn lower_mod(&mut self, items
: &[P
<Item
>], inner
: Span
) -> hir
::Mod
<'hir
> {
168 item_ids
: self.arena
.alloc_from_iter(items
.iter().flat_map(|x
| self.lower_item_id(x
))),
172 pub(super) fn lower_item_id(&mut self, i
: &Item
) -> SmallVec
<[hir
::ItemId
; 1]> {
173 let node_ids
= match i
.kind
{
174 ItemKind
::Use(ref use_tree
) => {
175 let mut vec
= smallvec
![i
.id
];
176 self.lower_item_id_use_tree(use_tree
, i
.id
, &mut vec
);
179 ItemKind
::MacroDef(..) => SmallVec
::new(),
180 ItemKind
::Fn(..) | ItemKind
::Impl(box ImplKind { of_trait: None, .. }
) => {
183 _
=> smallvec
![i
.id
],
188 .map(|node_id
| hir
::ItemId
{
189 def_id
: self.allocate_hir_id_counter(node_id
).expect_owner(),
194 fn lower_item_id_use_tree(
198 vec
: &mut SmallVec
<[NodeId
; 1]>,
201 UseTreeKind
::Nested(ref nested_vec
) => {
202 for &(ref nested
, id
) in nested_vec
{
204 self.lower_item_id_use_tree(nested
, id
, vec
);
207 UseTreeKind
::Glob
=> {}
208 UseTreeKind
::Simple(_
, id1
, id2
) => {
210 iter
::zip(self.expect_full_res_from_use(base_id
).skip(1), &[id1
, id2
])
218 pub fn lower_item(&mut self, i
: &Item
) -> Option
<hir
::Item
<'hir
>> {
219 let mut ident
= i
.ident
;
220 let mut vis
= self.lower_visibility(&i
.vis
, None
);
222 if let ItemKind
::MacroDef(MacroDef { ref body, macro_rules }
) = i
.kind
{
223 if !macro_rules
|| self.sess
.contains_name(&i
.attrs
, sym
::macro_export
) {
224 let hir_id
= self.lower_node_id(i
.id
);
225 self.lower_attrs(hir_id
, &i
.attrs
);
226 let body
= P(self.lower_mac_args(body
));
227 self.exported_macros
.push(hir
::MacroDef
{
230 def_id
: hir_id
.expect_owner(),
232 ast
: MacroDef { body, macro_rules }
,
235 for a
in i
.attrs
.iter() {
236 let a
= self.lower_attr(a
);
237 self.non_exported_macro_attrs
.push(a
);
243 let hir_id
= self.lower_node_id(i
.id
);
244 let attrs
= self.lower_attrs(hir_id
, &i
.attrs
);
245 let kind
= self.lower_item_kind(i
.span
, i
.id
, hir_id
, &mut ident
, attrs
, &mut vis
, &i
.kind
);
246 Some(hir
::Item { def_id: hir_id.expect_owner(), ident, kind, vis, span: i.span }
)
255 attrs
: Option
<&'hir
[Attribute
]>,
256 vis
: &mut hir
::Visibility
<'hir
>,
258 ) -> hir
::ItemKind
<'hir
> {
260 ItemKind
::ExternCrate(orig_name
) => hir
::ItemKind
::ExternCrate(orig_name
),
261 ItemKind
::Use(ref use_tree
) => {
262 // Start with an empty prefix.
263 let prefix
= Path { segments: vec![], span: use_tree.span, tokens: None }
;
265 self.lower_use_tree(use_tree
, &prefix
, id
, vis
, ident
, attrs
)
267 ItemKind
::Static(ref t
, m
, ref e
) => {
268 let (ty
, body_id
) = self.lower_const_item(t
, span
, e
.as_deref());
269 hir
::ItemKind
::Static(ty
, m
, body_id
)
271 ItemKind
::Const(_
, ref t
, ref e
) => {
272 let (ty
, body_id
) = self.lower_const_item(t
, span
, e
.as_deref());
273 hir
::ItemKind
::Const(ty
, body_id
)
275 ItemKind
::Fn(box FnKind(
277 FnSig { ref decl, header, span: fn_sig_span }
,
281 let fn_def_id
= self.resolver
.local_def_id(id
);
282 self.with_new_scopes(|this
| {
283 this
.current_item
= Some(ident
.span
);
285 // Note: we don't need to change the return type from `T` to
286 // `impl Future<Output = T>` here because lower_body
287 // only cares about the input argument patterns in the function
288 // declaration (decl), not the return types.
289 let asyncness
= header
.asyncness
;
291 this
.lower_maybe_async_body(span
, &decl
, asyncness
, body
.as_deref());
293 let (generics
, decl
) = this
.add_in_band_defs(
296 AnonymousLifetimeMode
::PassThrough
,
298 let ret_id
= asyncness
.opt_return_id();
301 Some((fn_def_id
.to_def_id(), idty
)),
307 let sig
= hir
::FnSig
{
309 header
: this
.lower_fn_header(header
, fn_sig_span
, id
),
312 hir
::ItemKind
::Fn(sig
, generics
, body_id
)
315 ItemKind
::Mod(_
, ref mod_kind
) => match mod_kind
{
316 ModKind
::Loaded(items
, _
, inner_span
) => {
317 hir
::ItemKind
::Mod(self.lower_mod(items
, *inner_span
))
319 ModKind
::Unloaded
=> panic
!("`mod` items should have been loaded by now"),
321 ItemKind
::ForeignMod(ref fm
) => {
322 if fm
.abi
.is_none() {
323 self.maybe_lint_missing_abi(span
, id
, abi
::Abi
::C { unwind: false }
);
325 hir
::ItemKind
::ForeignMod
{
326 abi
: fm
.abi
.map_or(abi
::Abi
::C { unwind: false }
, |abi
| self.lower_abi(abi
)),
329 .alloc_from_iter(fm
.items
.iter().map(|x
| self.lower_foreign_item_ref(x
))),
332 ItemKind
::GlobalAsm(ref asm
) => {
333 hir
::ItemKind
::GlobalAsm(self.lower_inline_asm(span
, asm
))
335 ItemKind
::TyAlias(box TyAliasKind(_
, ref gen
, _
, Some(ref ty
))) => {
338 // type Foo = impl Trait
343 // opaque type Foo1: Trait
344 let ty
= self.lower_ty(
346 ImplTraitContext
::TypeAliasesOpaqueTy
{
347 capturable_lifetimes
: &mut FxHashSet
::default(),
350 let generics
= self.lower_generics(gen
, ImplTraitContext
::disallowed());
351 hir
::ItemKind
::TyAlias(ty
, generics
)
353 ItemKind
::TyAlias(box TyAliasKind(_
, ref generics
, _
, None
)) => {
354 let ty
= self.arena
.alloc(self.ty(span
, hir
::TyKind
::Err
));
355 let generics
= self.lower_generics(generics
, ImplTraitContext
::disallowed());
356 hir
::ItemKind
::TyAlias(ty
, generics
)
358 ItemKind
::Enum(ref enum_definition
, ref generics
) => hir
::ItemKind
::Enum(
360 variants
: self.arena
.alloc_from_iter(
361 enum_definition
.variants
.iter().map(|x
| self.lower_variant(x
)),
364 self.lower_generics(generics
, ImplTraitContext
::disallowed()),
366 ItemKind
::Struct(ref struct_def
, ref generics
) => {
367 let struct_def
= self.lower_variant_data(hir_id
, struct_def
);
368 hir
::ItemKind
::Struct(
370 self.lower_generics(generics
, ImplTraitContext
::disallowed()),
373 ItemKind
::Union(ref vdata
, ref generics
) => {
374 let vdata
= self.lower_variant_data(hir_id
, vdata
);
375 hir
::ItemKind
::Union(
377 self.lower_generics(generics
, ImplTraitContext
::disallowed()),
380 ItemKind
::Impl(box ImplKind
{
385 generics
: ref ast_generics
,
386 of_trait
: ref trait_ref
,
388 items
: ref impl_items
,
390 // Lower the "impl header" first. This ordering is important
391 // for in-band lifetimes! Consider `'a` here:
393 // impl Foo<'a> for u32 {
394 // fn method(&'a self) { .. }
397 // Because we start by lowering the `Foo<'a> for u32`
398 // part, we will add `'a` to the list of generics on
399 // the impl. When we then encounter it later in the
400 // method, it will not be considered an in-band
401 // lifetime to be added, but rather a reference to a
403 let lowered_trait_def_id
= self.lower_node_id(id
).expect_owner();
404 let (generics
, (trait_ref
, lowered_ty
)) = self.add_in_band_defs(
406 lowered_trait_def_id
,
407 AnonymousLifetimeMode
::CreateParameter
,
409 let trait_ref
= trait_ref
.as_ref().map(|trait_ref
| {
410 this
.lower_trait_ref(trait_ref
, ImplTraitContext
::disallowed())
413 if let Some(ref trait_ref
) = trait_ref
{
414 if let Res
::Def(DefKind
::Trait
, def_id
) = trait_ref
.path
.res
{
418 .push(lowered_trait_def_id
);
422 let lowered_ty
= this
.lower_ty(ty
, ImplTraitContext
::disallowed());
424 (trait_ref
, lowered_ty
)
429 self.with_in_scope_lifetime_defs(&ast_generics
.params
, |this
| {
430 this
.arena
.alloc_from_iter(
431 impl_items
.iter().map(|item
| this
.lower_impl_item_ref(item
)),
435 // `defaultness.has_value()` is never called for an `impl`, always `true` in order
436 // to not cause an assertion failure inside the `lower_defaultness` function.
438 let (defaultness
, defaultness_span
) = self.lower_defaultness(defaultness
, has_val
);
439 hir
::ItemKind
::Impl(hir
::Impl
{
440 unsafety
: self.lower_unsafety(unsafety
),
444 constness
: self.lower_constness(constness
),
448 items
: new_impl_items
,
451 ItemKind
::Trait(box TraitKind(
458 let bounds
= self.lower_param_bounds(bounds
, ImplTraitContext
::disallowed());
461 .alloc_from_iter(items
.iter().map(|item
| self.lower_trait_item_ref(item
)));
462 hir
::ItemKind
::Trait(
464 self.lower_unsafety(unsafety
),
465 self.lower_generics(generics
, ImplTraitContext
::disallowed()),
470 ItemKind
::TraitAlias(ref generics
, ref bounds
) => hir
::ItemKind
::TraitAlias(
471 self.lower_generics(generics
, ImplTraitContext
::disallowed()),
472 self.lower_param_bounds(bounds
, ImplTraitContext
::disallowed()),
474 ItemKind
::MacroDef(..) | ItemKind
::MacCall(..) => {
475 panic
!("`TyMac` should have been expanded by now")
485 ) -> (&'hir hir
::Ty
<'hir
>, hir
::BodyId
) {
486 let ty
= self.lower_ty(ty
, ImplTraitContext
::Disallowed(ImplTraitPosition
::Binding
));
487 (ty
, self.lower_const_body(span
, body
))
495 vis
: &mut hir
::Visibility
<'hir
>,
497 attrs
: Option
<&'hir
[Attribute
]>,
498 ) -> hir
::ItemKind
<'hir
> {
499 debug
!("lower_use_tree(tree={:?})", tree
);
500 debug
!("lower_use_tree: vis = {:?}", vis
);
502 let path
= &tree
.prefix
;
503 let segments
= prefix
.segments
.iter().chain(path
.segments
.iter()).cloned().collect();
506 UseTreeKind
::Simple(rename
, id1
, id2
) => {
507 *ident
= tree
.ident();
509 // First, apply the prefix to the path.
510 let mut path
= Path { segments, span: path.span, tokens: None }
;
512 // Correctly resolve `self` imports.
513 if path
.segments
.len() > 1
514 && path
.segments
.last().unwrap().ident
.name
== kw
::SelfLower
516 let _
= path
.segments
.pop();
517 if rename
.is_none() {
518 *ident
= path
.segments
.last().unwrap().ident
;
522 let mut resolutions
= self.expect_full_res_from_use(id
);
523 // We want to return *something* from this function, so hold onto the first item
525 let ret_res
= self.lower_res(resolutions
.next().unwrap_or(Res
::Err
));
527 // Here, we are looping over namespaces, if they exist for the definition
528 // being imported. We only handle type and value namespaces because we
529 // won't be dealing with macros in the rest of the compiler.
530 // Essentially a single `use` which imports two names is desugared into
532 for (res
, &new_node_id
) in iter
::zip(resolutions
, &[id1
, id2
]) {
534 let mut path
= path
.clone();
535 for seg
in &mut path
.segments
{
536 seg
.id
= self.resolver
.next_node_id();
538 let span
= path
.span
;
540 self.with_hir_id_owner(new_node_id
, |this
| {
541 let new_id
= this
.lower_node_id(new_node_id
);
542 let res
= this
.lower_res(res
);
543 let path
= this
.lower_path_extra(res
, &path
, ParamMode
::Explicit
, None
);
544 let kind
= hir
::ItemKind
::Use(path
, hir
::UseKind
::Single
);
545 let vis
= this
.rebuild_vis(&vis
);
546 if let Some(attrs
) = attrs
{
547 this
.attrs
.insert(new_id
, attrs
);
550 this
.insert_item(hir
::Item
{
551 def_id
: new_id
.expect_owner(),
560 let path
= self.lower_path_extra(ret_res
, &path
, ParamMode
::Explicit
, None
);
561 hir
::ItemKind
::Use(path
, hir
::UseKind
::Single
)
563 UseTreeKind
::Glob
=> {
564 let path
= self.lower_path(
566 &Path { segments, span: path.span, tokens: None }
,
569 hir
::ItemKind
::Use(path
, hir
::UseKind
::Glob
)
571 UseTreeKind
::Nested(ref trees
) => {
572 // Nested imports are desugared into simple imports.
573 // So, if we start with
576 // pub(x) use foo::{a, b};
579 // we will create three items:
582 // pub(x) use foo::a;
583 // pub(x) use foo::b;
584 // pub(x) use foo::{}; // <-- this is called the `ListStem`
587 // The first two are produced by recursively invoking
588 // `lower_use_tree` (and indeed there may be things
589 // like `use foo::{a::{b, c}}` and so forth). They
590 // wind up being directly added to
591 // `self.items`. However, the structure of this
592 // function also requires us to return one item, and
593 // for that we return the `{}` import (called the
596 let prefix
= Path { segments, span: prefix.span.to(path.span), tokens: None }
;
598 // Add all the nested `PathListItem`s to the HIR.
599 for &(ref use_tree
, id
) in trees
{
600 let new_hir_id
= self.lower_node_id(id
);
602 let mut prefix
= prefix
.clone();
604 // Give the segments new node-ids since they are being cloned.
605 for seg
in &mut prefix
.segments
{
606 seg
.id
= self.resolver
.next_node_id();
609 // Each `use` import is an item and thus are owners of the
610 // names in the path. Up to this point the nested import is
611 // the current owner, since we want each desugared import to
612 // own its own names, we have to adjust the owner before
613 // lowering the rest of the import.
614 self.with_hir_id_owner(id
, |this
| {
615 let mut vis
= this
.rebuild_vis(&vis
);
616 let mut ident
= *ident
;
619 this
.lower_use_tree(use_tree
, &prefix
, id
, &mut vis
, &mut ident
, attrs
);
620 if let Some(attrs
) = attrs
{
621 this
.attrs
.insert(new_hir_id
, attrs
);
624 this
.insert_item(hir
::Item
{
625 def_id
: new_hir_id
.expect_owner(),
634 // Subtle and a bit hacky: we lower the privacy level
635 // of the list stem to "private" most of the time, but
636 // not for "restricted" paths. The key thing is that
637 // we don't want it to stay as `pub` (with no caveats)
638 // because that affects rustdoc and also the lints
639 // about `pub` items. But we can't *always* make it
640 // private -- particularly not for restricted paths --
641 // because it contains node-ids that would then be
642 // unused, failing the check that HirIds are "densely
645 hir
::VisibilityKind
::Public
646 | hir
::VisibilityKind
::Crate(_
)
647 | hir
::VisibilityKind
::Inherited
=> {
648 *vis
= respan(prefix
.span
.shrink_to_lo(), hir
::VisibilityKind
::Inherited
);
650 hir
::VisibilityKind
::Restricted { .. }
=> {
651 // Do nothing here, as described in the comment on the match.
655 let res
= self.expect_full_res_from_use(id
).next().unwrap_or(Res
::Err
);
656 let res
= self.lower_res(res
);
657 let path
= self.lower_path_extra(res
, &prefix
, ParamMode
::Explicit
, None
);
658 hir
::ItemKind
::Use(path
, hir
::UseKind
::ListStem
)
663 /// Paths like the visibility path in `pub(super) use foo::{bar, baz}` are repeated
664 /// many times in the HIR tree; for each occurrence, we need to assign distinct
665 /// `NodeId`s. (See, e.g., #56128.)
666 fn rebuild_use_path(&mut self, path
: &hir
::Path
<'hir
>) -> &'hir hir
::Path
<'hir
> {
667 debug
!("rebuild_use_path(path = {:?})", path
);
669 self.arena
.alloc_from_iter(path
.segments
.iter().map(|seg
| hir
::PathSegment
{
671 hir_id
: seg
.hir_id
.map(|_
| self.next_id()),
674 infer_args
: seg
.infer_args
,
676 self.arena
.alloc(hir
::Path { span: path.span, res: path.res, segments }
)
679 fn rebuild_vis(&mut self, vis
: &hir
::Visibility
<'hir
>) -> hir
::Visibility
<'hir
> {
680 let vis_kind
= match vis
.node
{
681 hir
::VisibilityKind
::Public
=> hir
::VisibilityKind
::Public
,
682 hir
::VisibilityKind
::Crate(sugar
) => hir
::VisibilityKind
::Crate(sugar
),
683 hir
::VisibilityKind
::Inherited
=> hir
::VisibilityKind
::Inherited
,
684 hir
::VisibilityKind
::Restricted { ref path, hir_id: _ }
=> {
685 hir
::VisibilityKind
::Restricted
{
686 path
: self.rebuild_use_path(path
),
687 hir_id
: self.next_id(),
691 respan(vis
.span
, vis_kind
)
694 fn lower_foreign_item(&mut self, i
: &ForeignItem
) -> hir
::ForeignItem
<'hir
> {
695 let hir_id
= self.lower_node_id(i
.id
);
696 let def_id
= hir_id
.expect_owner();
697 self.lower_attrs(hir_id
, &i
.attrs
);
702 ForeignItemKind
::Fn(box FnKind(_
, ref sig
, ref generics
, _
)) => {
703 let fdec
= &sig
.decl
;
704 let (generics
, (fn_dec
, fn_args
)) = self.add_in_band_defs(
707 AnonymousLifetimeMode
::PassThrough
,
710 // Disallow `impl Trait` in foreign items.
711 this
.lower_fn_decl(fdec
, None
, false, None
),
712 this
.lower_fn_params_to_names(fdec
),
717 hir
::ForeignItemKind
::Fn(fn_dec
, fn_args
, generics
)
719 ForeignItemKind
::Static(ref t
, m
, _
) => {
720 let ty
= self.lower_ty(t
, ImplTraitContext
::disallowed());
721 hir
::ForeignItemKind
::Static(ty
, m
)
723 ForeignItemKind
::TyAlias(..) => hir
::ForeignItemKind
::Type
,
724 ForeignItemKind
::MacCall(_
) => panic
!("macro shouldn't exist here"),
726 vis
: self.lower_visibility(&i
.vis
, None
),
731 fn lower_foreign_item_ref(&mut self, i
: &ForeignItem
) -> hir
::ForeignItemRef
<'hir
> {
732 hir
::ForeignItemRef
{
733 id
: hir
::ForeignItemId { def_id: self.lower_node_id(i.id).expect_owner() }
,
736 vis
: self.lower_visibility(&i
.vis
, Some(i
.id
)),
740 fn lower_variant(&mut self, v
: &Variant
) -> hir
::Variant
<'hir
> {
741 let id
= self.lower_node_id(v
.id
);
742 self.lower_attrs(id
, &v
.attrs
);
745 data
: self.lower_variant_data(id
, &v
.data
),
746 disr_expr
: v
.disr_expr
.as_ref().map(|e
| self.lower_anon_const(e
)),
752 fn lower_variant_data(
754 parent_id
: hir
::HirId
,
756 ) -> hir
::VariantData
<'hir
> {
758 VariantData
::Struct(ref fields
, recovered
) => hir
::VariantData
::Struct(
760 .alloc_from_iter(fields
.iter().enumerate().map(|f
| self.lower_field_def(f
))),
763 VariantData
::Tuple(ref fields
, id
) => {
764 let ctor_id
= self.lower_node_id(id
);
765 self.alias_attrs(ctor_id
, parent_id
);
766 hir
::VariantData
::Tuple(
767 self.arena
.alloc_from_iter(
768 fields
.iter().enumerate().map(|f
| self.lower_field_def(f
)),
773 VariantData
::Unit(id
) => {
774 let ctor_id
= self.lower_node_id(id
);
775 self.alias_attrs(ctor_id
, parent_id
);
776 hir
::VariantData
::Unit(ctor_id
)
781 pub(super) fn lower_field_def(
783 (index
, f
): (usize, &FieldDef
),
784 ) -> hir
::FieldDef
<'hir
> {
785 let ty
= if let TyKind
::Path(ref qself
, ref path
) = f
.ty
.kind
{
786 let t
= self.lower_path_ty(
790 ParamMode
::ExplicitNamed
, // no `'_` in declarations (Issue #61124)
791 ImplTraitContext
::disallowed(),
795 self.lower_ty(&f
.ty
, ImplTraitContext
::disallowed())
797 let hir_id
= self.lower_node_id(f
.id
);
798 self.lower_attrs(hir_id
, &f
.attrs
);
802 ident
: match f
.ident
{
803 Some(ident
) => ident
,
804 // FIXME(jseyfried): positional field hygiene.
805 None
=> Ident
::new(sym
::integer(index
), f
.span
),
807 vis
: self.lower_visibility(&f
.vis
, None
),
812 fn lower_trait_item(&mut self, i
: &AssocItem
) -> hir
::TraitItem
<'hir
> {
813 let hir_id
= self.lower_node_id(i
.id
);
814 let trait_item_def_id
= hir_id
.expect_owner();
816 let (generics
, kind
) = match i
.kind
{
817 AssocItemKind
::Const(_
, ref ty
, ref default) => {
818 let ty
= self.lower_ty(ty
, ImplTraitContext
::disallowed());
819 let body
= default.as_ref().map(|x
| self.lower_const_body(i
.span
, Some(x
)));
820 (hir
::Generics
::empty(), hir
::TraitItemKind
::Const(ty
, body
))
822 AssocItemKind
::Fn(box FnKind(_
, ref sig
, ref generics
, None
)) => {
823 let names
= self.lower_fn_params_to_names(&sig
.decl
);
824 let (generics
, sig
) =
825 self.lower_method_sig(generics
, sig
, trait_item_def_id
, false, None
, i
.id
);
826 (generics
, hir
::TraitItemKind
::Fn(sig
, hir
::TraitFn
::Required(names
)))
828 AssocItemKind
::Fn(box FnKind(_
, ref sig
, ref generics
, Some(ref body
))) => {
829 let asyncness
= sig
.header
.asyncness
;
831 self.lower_maybe_async_body(i
.span
, &sig
.decl
, asyncness
, Some(&body
));
832 let (generics
, sig
) = self.lower_method_sig(
837 asyncness
.opt_return_id(),
840 (generics
, hir
::TraitItemKind
::Fn(sig
, hir
::TraitFn
::Provided(body_id
)))
842 AssocItemKind
::TyAlias(box TyAliasKind(_
, ref generics
, ref bounds
, ref default)) => {
843 let ty
= default.as_ref().map(|x
| self.lower_ty(x
, ImplTraitContext
::disallowed()));
844 let generics
= self.lower_generics(generics
, ImplTraitContext
::disallowed());
845 let kind
= hir
::TraitItemKind
::Type(
846 self.lower_param_bounds(bounds
, ImplTraitContext
::disallowed()),
852 AssocItemKind
::MacCall(..) => panic
!("macro item shouldn't exist at this point"),
855 self.lower_attrs(hir_id
, &i
.attrs
);
856 hir
::TraitItem { def_id: trait_item_def_id, ident: i.ident, generics, kind, span: i.span }
859 fn lower_trait_item_ref(&mut self, i
: &AssocItem
) -> hir
::TraitItemRef
{
860 let (kind
, has_default
) = match &i
.kind
{
861 AssocItemKind
::Const(_
, _
, default) => (hir
::AssocItemKind
::Const
, default.is_some()),
862 AssocItemKind
::TyAlias(box TyAliasKind(_
, _
, _
, default)) => {
863 (hir
::AssocItemKind
::Type
, default.is_some())
865 AssocItemKind
::Fn(box FnKind(_
, sig
, _
, default)) => {
866 (hir
::AssocItemKind
::Fn { has_self: sig.decl.has_self() }
, default.is_some())
868 AssocItemKind
::MacCall(..) => unimplemented
!(),
870 let id
= hir
::TraitItemId { def_id: self.lower_node_id(i.id).expect_owner() }
;
871 let defaultness
= hir
::Defaultness
::Default { has_value: has_default }
;
872 hir
::TraitItemRef { id, ident: i.ident, span: i.span, defaultness, kind }
875 /// Construct `ExprKind::Err` for the given `span`.
876 crate fn expr_err(&mut self, span
: Span
) -> hir
::Expr
<'hir
> {
877 self.expr(span
, hir
::ExprKind
::Err
, AttrVec
::new())
880 fn lower_impl_item(&mut self, i
: &AssocItem
) -> hir
::ImplItem
<'hir
> {
881 let impl_item_def_id
= self.resolver
.local_def_id(i
.id
);
883 let (generics
, kind
) = match &i
.kind
{
884 AssocItemKind
::Const(_
, ty
, expr
) => {
885 let ty
= self.lower_ty(ty
, ImplTraitContext
::disallowed());
887 hir
::Generics
::empty(),
888 hir
::ImplItemKind
::Const(ty
, self.lower_const_body(i
.span
, expr
.as_deref())),
891 AssocItemKind
::Fn(box FnKind(_
, sig
, generics
, body
)) => {
892 self.current_item
= Some(i
.span
);
893 let asyncness
= sig
.header
.asyncness
;
895 self.lower_maybe_async_body(i
.span
, &sig
.decl
, asyncness
, body
.as_deref());
896 let impl_trait_return_allow
= !self.is_in_trait_impl
;
897 let (generics
, sig
) = self.lower_method_sig(
901 impl_trait_return_allow
,
902 asyncness
.opt_return_id(),
906 (generics
, hir
::ImplItemKind
::Fn(sig
, body_id
))
908 AssocItemKind
::TyAlias(box TyAliasKind(_
, generics
, _
, ty
)) => {
909 let generics
= self.lower_generics(generics
, ImplTraitContext
::disallowed());
910 let kind
= match ty
{
912 let ty
= self.arena
.alloc(self.ty(i
.span
, hir
::TyKind
::Err
));
913 hir
::ImplItemKind
::TyAlias(ty
)
916 let ty
= self.lower_ty(
918 ImplTraitContext
::TypeAliasesOpaqueTy
{
919 capturable_lifetimes
: &mut FxHashSet
::default(),
922 hir
::ImplItemKind
::TyAlias(ty
)
927 AssocItemKind
::MacCall(..) => panic
!("`TyMac` should have been expanded by now"),
930 // Since `default impl` is not yet implemented, this is always true in impls.
931 let has_value
= true;
932 let (defaultness
, _
) = self.lower_defaultness(i
.kind
.defaultness(), has_value
);
933 let hir_id
= self.lower_node_id(i
.id
);
934 self.lower_attrs(hir_id
, &i
.attrs
);
936 def_id
: hir_id
.expect_owner(),
939 vis
: self.lower_visibility(&i
.vis
, None
),
946 fn lower_impl_item_ref(&mut self, i
: &AssocItem
) -> hir
::ImplItemRef
<'hir
> {
947 // Since `default impl` is not yet implemented, this is always true in impls.
948 let has_value
= true;
949 let (defaultness
, _
) = self.lower_defaultness(i
.kind
.defaultness(), has_value
);
951 id
: hir
::ImplItemId { def_id: self.lower_node_id(i.id).expect_owner() }
,
954 vis
: self.lower_visibility(&i
.vis
, Some(i
.id
)),
956 kind
: match &i
.kind
{
957 AssocItemKind
::Const(..) => hir
::AssocItemKind
::Const
,
958 AssocItemKind
::TyAlias(..) => hir
::AssocItemKind
::Type
,
959 AssocItemKind
::Fn(box FnKind(_
, sig
, ..)) => {
960 hir
::AssocItemKind
::Fn { has_self: sig.decl.has_self() }
962 AssocItemKind
::MacCall(..) => unimplemented
!(),
967 /// If an `explicit_owner` is given, this method allocates the `HirId` in
968 /// the address space of that item instead of the item currently being
969 /// lowered. This can happen during `lower_impl_item_ref()` where we need to
970 /// lower a `Visibility` value although we haven't lowered the owning
971 /// `ImplItem` in question yet.
975 explicit_owner
: Option
<NodeId
>,
976 ) -> hir
::Visibility
<'hir
> {
977 let node
= match v
.kind
{
978 VisibilityKind
::Public
=> hir
::VisibilityKind
::Public
,
979 VisibilityKind
::Crate(sugar
) => hir
::VisibilityKind
::Crate(sugar
),
980 VisibilityKind
::Restricted { ref path, id }
=> {
981 debug
!("lower_visibility: restricted path id = {:?}", id
);
982 let lowered_id
= if let Some(owner
) = explicit_owner
{
983 self.lower_node_id_with_owner(id
, owner
)
985 self.lower_node_id(id
)
987 let res
= self.expect_full_res(id
);
988 let res
= self.lower_res(res
);
989 hir
::VisibilityKind
::Restricted
{
990 path
: self.lower_path_extra(res
, path
, ParamMode
::Explicit
, explicit_owner
),
994 VisibilityKind
::Inherited
=> hir
::VisibilityKind
::Inherited
,
999 fn lower_defaultness(
1003 ) -> (hir
::Defaultness
, Option
<Span
>) {
1005 Defaultness
::Default(sp
) => (hir
::Defaultness
::Default { has_value }
, Some(sp
)),
1006 Defaultness
::Final
=> {
1008 (hir
::Defaultness
::Final
, None
)
1015 params
: &'hir
[hir
::Param
<'hir
>],
1016 value
: hir
::Expr
<'hir
>,
1018 let body
= hir
::Body { generator_kind: self.generator_kind, params, value }
;
1020 self.bodies
.insert(id
, body
);
1024 pub(super) fn lower_body(
1026 f
: impl FnOnce(&mut Self) -> (&'hir
[hir
::Param
<'hir
>], hir
::Expr
<'hir
>),
1028 let prev_gen_kind
= self.generator_kind
.take();
1029 let task_context
= self.task_context
.take();
1030 let (parameters
, result
) = f(self);
1031 let body_id
= self.record_body(parameters
, result
);
1032 self.task_context
= task_context
;
1033 self.generator_kind
= prev_gen_kind
;
1037 fn lower_param(&mut self, param
: &Param
) -> hir
::Param
<'hir
> {
1038 let hir_id
= self.lower_node_id(param
.id
);
1039 self.lower_attrs(hir_id
, ¶m
.attrs
);
1042 pat
: self.lower_pat(¶m
.pat
),
1043 ty_span
: param
.ty
.span
,
1048 pub(super) fn lower_fn_body(
1051 body
: impl FnOnce(&mut Self) -> hir
::Expr
<'hir
>,
1053 self.lower_body(|this
| {
1055 this
.arena
.alloc_from_iter(decl
.inputs
.iter().map(|x
| this
.lower_param(x
))),
1061 fn lower_fn_body_block(
1065 body
: Option
<&Block
>,
1067 self.lower_fn_body(decl
, |this
| this
.lower_block_expr_opt(span
, body
))
1070 fn lower_block_expr_opt(&mut self, span
: Span
, block
: Option
<&Block
>) -> hir
::Expr
<'hir
> {
1072 Some(block
) => self.lower_block_expr(block
),
1073 None
=> self.expr_err(span
),
1077 pub(super) fn lower_const_body(&mut self, span
: Span
, expr
: Option
<&Expr
>) -> hir
::BodyId
{
1078 self.lower_body(|this
| {
1082 Some(expr
) => this
.lower_expr_mut(expr
),
1083 None
=> this
.expr_err(span
),
1089 fn lower_maybe_async_body(
1094 body
: Option
<&Block
>,
1096 let closure_id
= match asyncness
{
1097 Async
::Yes { closure_id, .. }
=> closure_id
,
1098 Async
::No
=> return self.lower_fn_body_block(span
, decl
, body
),
1101 self.lower_body(|this
| {
1102 let mut parameters
: Vec
<hir
::Param
<'_
>> = Vec
::new();
1103 let mut statements
: Vec
<hir
::Stmt
<'_
>> = Vec
::new();
1105 // Async function parameters are lowered into the closure body so that they are
1106 // captured and so that the drop order matches the equivalent non-async functions.
1110 // async fn foo(<pattern>: <ty>, <pattern>: <ty>, <pattern>: <ty>) {
1116 // fn foo(__arg0: <ty>, __arg1: <ty>, __arg2: <ty>) {
1118 // let __arg2 = __arg2;
1119 // let <pattern> = __arg2;
1120 // let __arg1 = __arg1;
1121 // let <pattern> = __arg1;
1122 // let __arg0 = __arg0;
1123 // let <pattern> = __arg0;
1124 // drop-temps { <body> } // see comments later in fn for details
1128 // If `<pattern>` is a simple ident, then it is lowered to a single
1129 // `let <pattern> = <pattern>;` statement as an optimization.
1131 // Note that the body is embedded in `drop-temps`; an
1132 // equivalent desugaring would be `return { <body>
1133 // };`. The key point is that we wish to drop all the
1134 // let-bound variables and temporaries created in the body
1135 // (and its tail expression!) before we drop the
1136 // parameters (c.f. rust-lang/rust#64512).
1137 for (index
, parameter
) in decl
.inputs
.iter().enumerate() {
1138 let parameter
= this
.lower_param(parameter
);
1139 let span
= parameter
.pat
.span
;
1141 // Check if this is a binding pattern, if so, we can optimize and avoid adding a
1142 // `let <pat> = __argN;` statement. In this case, we do not rename the parameter.
1143 let (ident
, is_simple_parameter
) = match parameter
.pat
.kind
{
1144 hir
::PatKind
::Binding(
1145 hir
::BindingAnnotation
::Unannotated
| hir
::BindingAnnotation
::Mutable
,
1150 // For `ref mut` or wildcard arguments, we can't reuse the binding, but
1151 // we can keep the same name for the parameter.
1152 // This lets rustdoc render it correctly in documentation.
1153 hir
::PatKind
::Binding(_
, _
, ident
, _
) => (ident
, false),
1154 hir
::PatKind
::Wild
=> {
1155 (Ident
::with_dummy_span(rustc_span
::symbol
::kw
::Underscore
), false)
1158 // Replace the ident for bindings that aren't simple.
1159 let name
= format
!("__arg{}", index
);
1160 let ident
= Ident
::from_str(&name
);
1166 let desugared_span
= this
.mark_span_with_reason(DesugaringKind
::Async
, span
, None
);
1168 // Construct a parameter representing `__argN: <ty>` to replace the parameter of the
1171 // If this is the simple case, this parameter will end up being the same as the
1172 // original parameter, but with a different pattern id.
1173 let stmt_attrs
= this
.attrs
.get(¶meter
.hir_id
).copied();
1174 let (new_parameter_pat
, new_parameter_id
) = this
.pat_ident(desugared_span
, ident
);
1175 let new_parameter
= hir
::Param
{
1176 hir_id
: parameter
.hir_id
,
1177 pat
: new_parameter_pat
,
1178 ty_span
: parameter
.ty_span
,
1179 span
: parameter
.span
,
1182 if is_simple_parameter
{
1183 // If this is the simple case, then we only insert one statement that is
1184 // `let <pat> = <pat>;`. We re-use the original argument's pattern so that
1185 // `HirId`s are densely assigned.
1186 let expr
= this
.expr_ident(desugared_span
, ident
, new_parameter_id
);
1187 let stmt
= this
.stmt_let_pat(
1192 hir
::LocalSource
::AsyncFn
,
1194 statements
.push(stmt
);
1196 // If this is not the simple case, then we construct two statements:
1199 // let __argN = __argN;
1200 // let <pat> = __argN;
1203 // The first statement moves the parameter into the closure and thus ensures
1204 // that the drop order is correct.
1206 // The second statement creates the bindings that the user wrote.
1208 // Construct the `let mut __argN = __argN;` statement. It must be a mut binding
1209 // because the user may have specified a `ref mut` binding in the next
1211 let (move_pat
, move_id
) = this
.pat_ident_binding_mode(
1214 hir
::BindingAnnotation
::Mutable
,
1216 let move_expr
= this
.expr_ident(desugared_span
, ident
, new_parameter_id
);
1217 let move_stmt
= this
.stmt_let_pat(
1222 hir
::LocalSource
::AsyncFn
,
1225 // Construct the `let <pat> = __argN;` statement. We re-use the original
1226 // parameter's pattern so that `HirId`s are densely assigned.
1227 let pattern_expr
= this
.expr_ident(desugared_span
, ident
, move_id
);
1228 let pattern_stmt
= this
.stmt_let_pat(
1233 hir
::LocalSource
::AsyncFn
,
1236 statements
.push(move_stmt
);
1237 statements
.push(pattern_stmt
);
1240 parameters
.push(new_parameter
);
1243 let body_span
= body
.map_or(span
, |b
| b
.span
);
1244 let async_expr
= this
.make_async_expr(
1249 hir
::AsyncGeneratorKind
::Fn
,
1251 // Create a block from the user's function body:
1252 let user_body
= this
.lower_block_expr_opt(body_span
, body
);
1254 // Transform into `drop-temps { <user-body> }`, an expression:
1255 let desugared_span
=
1256 this
.mark_span_with_reason(DesugaringKind
::Async
, user_body
.span
, None
);
1257 let user_body
= this
.expr_drop_temps(
1259 this
.arena
.alloc(user_body
),
1263 // As noted above, create the final block like
1267 // let $param_pattern = $raw_param;
1269 // drop-temps { <user-body> }
1272 let body
= this
.block_all(
1274 this
.arena
.alloc_from_iter(statements
),
1278 this
.expr_block(body
, AttrVec
::new())
1283 this
.arena
.alloc_from_iter(parameters
),
1284 this
.expr(body_span
, async_expr
, AttrVec
::new()),
1289 fn lower_method_sig(
1291 generics
: &Generics
,
1293 fn_def_id
: LocalDefId
,
1294 impl_trait_return_allow
: bool
,
1295 is_async
: Option
<NodeId
>,
1297 ) -> (hir
::Generics
<'hir
>, hir
::FnSig
<'hir
>) {
1298 let header
= self.lower_fn_header(sig
.header
, sig
.span
, id
);
1299 let (generics
, decl
) = self.add_in_band_defs(
1302 AnonymousLifetimeMode
::PassThrough
,
1306 Some((fn_def_id
.to_def_id(), idty
)),
1307 impl_trait_return_allow
,
1312 (generics
, hir
::FnSig { header, decl, span: sig.span }
)
1315 fn lower_fn_header(&mut self, h
: FnHeader
, span
: Span
, id
: NodeId
) -> hir
::FnHeader
{
1317 unsafety
: self.lower_unsafety(h
.unsafety
),
1318 asyncness
: self.lower_asyncness(h
.asyncness
),
1319 constness
: self.lower_constness(h
.constness
),
1320 abi
: self.lower_extern(h
.ext
, span
, id
),
1324 pub(super) fn lower_abi(&mut self, abi
: StrLit
) -> abi
::Abi
{
1325 abi
::lookup(&abi
.symbol_unescaped
.as_str()).unwrap_or_else(|| {
1326 self.error_on_invalid_abi(abi
);
1331 pub(super) fn lower_extern(&mut self, ext
: Extern
, span
: Span
, id
: NodeId
) -> abi
::Abi
{
1333 Extern
::None
=> abi
::Abi
::Rust
,
1334 Extern
::Implicit
=> {
1335 self.maybe_lint_missing_abi(span
, id
, abi
::Abi
::C { unwind: false }
);
1336 abi
::Abi
::C { unwind: false }
1338 Extern
::Explicit(abi
) => self.lower_abi(abi
),
1342 fn error_on_invalid_abi(&self, abi
: StrLit
) {
1343 struct_span_err
!(self.sess
, abi
.span
, E0703
, "invalid ABI: found `{}`", abi
.symbol
)
1344 .span_label(abi
.span
, "invalid ABI")
1345 .help(&format
!("valid ABIs: {}", abi
::all_names().join(", ")))
1349 fn lower_asyncness(&mut self, a
: Async
) -> hir
::IsAsync
{
1351 Async
::Yes { .. }
=> hir
::IsAsync
::Async
,
1352 Async
::No
=> hir
::IsAsync
::NotAsync
,
1356 fn lower_constness(&mut self, c
: Const
) -> hir
::Constness
{
1358 Const
::Yes(_
) => hir
::Constness
::Const
,
1359 Const
::No
=> hir
::Constness
::NotConst
,
1363 pub(super) fn lower_unsafety(&mut self, u
: Unsafe
) -> hir
::Unsafety
{
1365 Unsafe
::Yes(_
) => hir
::Unsafety
::Unsafe
,
1366 Unsafe
::No
=> hir
::Unsafety
::Normal
,
1370 pub(super) fn lower_generics_mut(
1372 generics
: &Generics
,
1373 itctx
: ImplTraitContext
<'_
, 'hir
>,
1374 ) -> GenericsCtor
<'hir
> {
1375 // Collect `?Trait` bounds in where clause and move them to parameter definitions.
1376 let mut add_bounds
: NodeMap
<Vec
<_
>> = Default
::default();
1377 for pred
in &generics
.where_clause
.predicates
{
1378 if let WherePredicate
::BoundPredicate(ref bound_pred
) = *pred
{
1379 'next_bound
: for bound
in &bound_pred
.bounds
{
1380 if let GenericBound
::Trait(_
, TraitBoundModifier
::Maybe
) = *bound
{
1381 // Check if the where clause type is a plain type parameter.
1384 .get_partial_res(bound_pred
.bounded_ty
.id
)
1385 .map(|d
| (d
.base_res(), d
.unresolved_segments()))
1387 Some((Res
::Def(DefKind
::TyParam
, def_id
), 0))
1388 if bound_pred
.bound_generic_params
.is_empty() =>
1390 for param
in &generics
.params
{
1391 if def_id
== self.resolver
.local_def_id(param
.id
).to_def_id() {
1392 add_bounds
.entry(param
.id
).or_default().push(bound
.clone());
1393 continue 'next_bound
;
1399 self.diagnostic().span_err(
1400 bound_pred
.bounded_ty
.span
,
1401 "`?Trait` bounds are only permitted at the \
1402 point where a type parameter is declared",
1410 params
: self.lower_generic_params_mut(&generics
.params
, &add_bounds
, itctx
).collect(),
1411 where_clause
: self.lower_where_clause(&generics
.where_clause
),
1412 span
: generics
.span
,
1416 pub(super) fn lower_generics(
1418 generics
: &Generics
,
1419 itctx
: ImplTraitContext
<'_
, 'hir
>,
1420 ) -> hir
::Generics
<'hir
> {
1421 let generics_ctor
= self.lower_generics_mut(generics
, itctx
);
1422 generics_ctor
.into_generics(self.arena
)
1425 fn lower_where_clause(&mut self, wc
: &WhereClause
) -> hir
::WhereClause
<'hir
> {
1426 self.with_anonymous_lifetime_mode(AnonymousLifetimeMode
::ReportError
, |this
| {
1428 predicates
: this
.arena
.alloc_from_iter(
1429 wc
.predicates
.iter().map(|predicate
| this
.lower_where_predicate(predicate
)),
1436 fn lower_where_predicate(&mut self, pred
: &WherePredicate
) -> hir
::WherePredicate
<'hir
> {
1438 WherePredicate
::BoundPredicate(WhereBoundPredicate
{
1439 ref bound_generic_params
,
1444 self.with_in_scope_lifetime_defs(&bound_generic_params
, |this
| {
1445 hir
::WherePredicate
::BoundPredicate(hir
::WhereBoundPredicate
{
1446 bound_generic_params
: this
.lower_generic_params(
1447 bound_generic_params
,
1448 &NodeMap
::default(),
1449 ImplTraitContext
::disallowed(),
1451 bounded_ty
: this
.lower_ty(bounded_ty
, ImplTraitContext
::disallowed()),
1452 bounds
: this
.arena
.alloc_from_iter(bounds
.iter().filter_map(|bound
| {
1454 // Ignore `?Trait` bounds.
1455 // They were copied into type parameters already.
1456 GenericBound
::Trait(_
, TraitBoundModifier
::Maybe
) => None
,
1458 this
.lower_param_bound(bound
, ImplTraitContext
::disallowed()),
1466 WherePredicate
::RegionPredicate(WhereRegionPredicate
{
1470 }) => hir
::WherePredicate
::RegionPredicate(hir
::WhereRegionPredicate
{
1472 lifetime
: self.lower_lifetime(lifetime
),
1473 bounds
: self.lower_param_bounds(bounds
, ImplTraitContext
::disallowed()),
1475 WherePredicate
::EqPredicate(WhereEqPredicate { id, ref lhs_ty, ref rhs_ty, span }
) => {
1476 hir
::WherePredicate
::EqPredicate(hir
::WhereEqPredicate
{
1477 hir_id
: self.lower_node_id(id
),
1478 lhs_ty
: self.lower_ty(lhs_ty
, ImplTraitContext
::disallowed()),
1479 rhs_ty
: self.lower_ty(rhs_ty
, ImplTraitContext
::disallowed()),
1487 /// Helper struct for delayed construction of Generics.
1488 pub(super) struct GenericsCtor
<'hir
> {
1489 pub(super) params
: SmallVec
<[hir
::GenericParam
<'hir
>; 4]>,
1490 where_clause
: hir
::WhereClause
<'hir
>,
1494 impl<'hir
> GenericsCtor
<'hir
> {
1495 pub(super) fn into_generics(self, arena
: &'hir Arena
<'hir
>) -> hir
::Generics
<'hir
> {
1497 params
: arena
.alloc_from_iter(self.params
),
1498 where_clause
: self.where_clause
,