1 use super::LoweringContext
;
2 use super::ImplTraitContext
;
3 use super::ImplTraitPosition
;
4 use super::ImplTraitTypeIdVisitor
;
5 use super::AnonymousLifetimeMode
;
8 use crate::hir
::{self, HirVec}
;
9 use crate::hir
::ptr
::P
;
10 use crate::hir
::def_id
::DefId
;
11 use crate::hir
::def
::{Res, DefKind}
;
12 use crate::util
::nodemap
::NodeMap
;
14 use rustc_data_structures
::thin_vec
::ThinVec
;
16 use std
::collections
::BTreeSet
;
17 use smallvec
::SmallVec
;
20 use syntax
::visit
::{self, Visitor}
;
21 use syntax
::expand
::SpecialDerives
;
22 use syntax
::source_map
::{respan, DesugaringKind, Spanned}
;
23 use syntax
::symbol
::{kw, sym}
;
26 pub(super) struct ItemLowerer
<'tcx
, 'interner
> {
27 pub(super) lctx
: &'tcx
mut LoweringContext
<'interner
>,
30 impl<'tcx
, 'interner
> ItemLowerer
<'tcx
, 'interner
> {
31 fn with_trait_impl_ref
<F
>(&mut self, trait_impl_ref
: &Option
<TraitRef
>, f
: F
)
35 let old
= self.lctx
.is_in_trait_impl
;
36 self.lctx
.is_in_trait_impl
= if let &None
= trait_impl_ref
{
42 self.lctx
.is_in_trait_impl
= old
;
46 impl<'tcx
, 'interner
> Visitor
<'tcx
> for ItemLowerer
<'tcx
, 'interner
> {
47 fn visit_mod(&mut self, m
: &'tcx Mod
, _s
: Span
, _attrs
: &[Attribute
], n
: NodeId
) {
48 let hir_id
= self.lctx
.lower_node_id(n
);
50 self.lctx
.modules
.insert(hir_id
, hir
::ModuleItems
{
51 items
: BTreeSet
::new(),
52 trait_items
: BTreeSet
::new(),
53 impl_items
: BTreeSet
::new(),
56 let old
= self.lctx
.current_module
;
57 self.lctx
.current_module
= hir_id
;
58 visit
::walk_mod(self, m
);
59 self.lctx
.current_module
= old
;
62 fn visit_item(&mut self, item
: &'tcx Item
) {
63 let mut item_hir_id
= None
;
64 self.lctx
.with_hir_id_owner(item
.id
, |lctx
| {
65 lctx
.without_in_scope_lifetime_defs(|lctx
| {
66 if let Some(hir_item
) = lctx
.lower_item(item
) {
67 item_hir_id
= Some(hir_item
.hir_id
);
68 lctx
.insert_item(hir_item
);
73 if let Some(hir_id
) = item_hir_id
{
74 self.lctx
.with_parent_item_lifetime_defs(hir_id
, |this
| {
75 let this
= &mut ItemLowerer { lctx: this }
;
76 if let ItemKind
::Impl(.., ref opt_trait_ref
, _
, _
) = item
.kind
{
77 this
.with_trait_impl_ref(opt_trait_ref
, |this
| {
78 visit
::walk_item(this
, item
)
81 visit
::walk_item(this
, item
);
87 fn visit_trait_item(&mut self, item
: &'tcx TraitItem
) {
88 self.lctx
.with_hir_id_owner(item
.id
, |lctx
| {
89 let hir_item
= lctx
.lower_trait_item(item
);
90 let id
= hir
::TraitItemId { hir_id: hir_item.hir_id }
;
91 lctx
.trait_items
.insert(id
, hir_item
);
92 lctx
.modules
.get_mut(&lctx
.current_module
).unwrap().trait_items
.insert(id
);
95 visit
::walk_trait_item(self, item
);
98 fn visit_impl_item(&mut self, item
: &'tcx ImplItem
) {
99 self.lctx
.with_hir_id_owner(item
.id
, |lctx
| {
100 let hir_item
= lctx
.lower_impl_item(item
);
101 let id
= hir
::ImplItemId { hir_id: hir_item.hir_id }
;
102 lctx
.impl_items
.insert(id
, hir_item
);
103 lctx
.modules
.get_mut(&lctx
.current_module
).unwrap().impl_items
.insert(id
);
105 visit
::walk_impl_item(self, item
);
109 impl LoweringContext
<'_
> {
110 // Same as the method above, but accepts `hir::GenericParam`s
111 // instead of `ast::GenericParam`s.
112 // This should only be used with generics that have already had their
113 // in-band lifetimes added. In practice, this means that this function is
114 // only used when lowering a child item of a trait or impl.
115 fn with_parent_item_lifetime_defs
<T
>(
117 parent_hir_id
: hir
::HirId
,
118 f
: impl FnOnce(&mut LoweringContext
<'_
>) -> T
,
120 let old_len
= self.in_scope_lifetimes
.len();
122 let parent_generics
= match self.items
.get(&parent_hir_id
).unwrap().kind
{
123 hir
::ItemKind
::Impl(_
, _
, _
, ref generics
, ..)
124 | hir
::ItemKind
::Trait(_
, _
, ref generics
, ..) => {
129 let lt_def_names
= parent_generics
.iter().filter_map(|param
| match param
.kind
{
130 hir
::GenericParamKind
::Lifetime { .. }
=> Some(param
.name
.modern()),
133 self.in_scope_lifetimes
.extend(lt_def_names
);
137 self.in_scope_lifetimes
.truncate(old_len
);
141 // Clears (and restores) the `in_scope_lifetimes` field. Used when
142 // visiting nested items, which never inherit in-scope lifetimes
143 // from their surrounding environment.
144 fn without_in_scope_lifetime_defs
<T
>(
146 f
: impl FnOnce(&mut LoweringContext
<'_
>) -> T
,
148 let old_in_scope_lifetimes
= std
::mem
::replace(&mut self.in_scope_lifetimes
, vec
![]);
150 // this vector is only used when walking over impl headers,
151 // input types, and the like, and should not be non-empty in
153 assert
!(self.lifetimes_to_define
.is_empty());
157 assert
!(self.in_scope_lifetimes
.is_empty());
158 self.in_scope_lifetimes
= old_in_scope_lifetimes
;
163 pub(super) fn lower_mod(&mut self, m
: &Mod
) -> hir
::Mod
{
166 item_ids
: m
.items
.iter().flat_map(|x
| self.lower_item_id(x
)).collect(),
170 pub(super) fn lower_item_id(&mut self, i
: &Item
) -> SmallVec
<[hir
::ItemId
; 1]> {
171 let node_ids
= match i
.kind
{
172 ItemKind
::Use(ref use_tree
) => {
173 let mut vec
= smallvec
![i
.id
];
174 self.lower_item_id_use_tree(use_tree
, i
.id
, &mut vec
);
177 ItemKind
::MacroDef(..) => SmallVec
::new(),
179 ItemKind
::Impl(.., None
, _
, _
) => smallvec
![i
.id
],
180 ItemKind
::Static(ref ty
, ..) => {
181 let mut ids
= smallvec
![i
.id
];
182 if self.sess
.features_untracked().impl_trait_in_bindings
{
183 let mut visitor
= ImplTraitTypeIdVisitor { ids: &mut ids }
;
184 visitor
.visit_ty(ty
);
188 ItemKind
::Const(ref ty
, ..) => {
189 let mut ids
= smallvec
![i
.id
];
190 if self.sess
.features_untracked().impl_trait_in_bindings
{
191 let mut visitor
= ImplTraitTypeIdVisitor { ids: &mut ids }
;
192 visitor
.visit_ty(ty
);
196 _
=> smallvec
![i
.id
],
199 node_ids
.into_iter().map(|node_id
| hir
::ItemId
{
200 id
: self.allocate_hir_id_counter(node_id
)
204 fn lower_item_id_use_tree(
208 vec
: &mut SmallVec
<[NodeId
; 1]>
211 UseTreeKind
::Nested(ref nested_vec
) => for &(ref nested
, id
) in nested_vec
{
213 self.lower_item_id_use_tree(nested
, id
, vec
);
215 UseTreeKind
::Glob
=> {}
216 UseTreeKind
::Simple(_
, id1
, id2
) => {
217 for (_
, &id
) in self.expect_full_res_from_use(base_id
)
219 .zip([id1
, id2
].iter())
227 pub fn lower_item(&mut self, i
: &Item
) -> Option
<hir
::Item
> {
228 let mut ident
= i
.ident
;
229 let mut vis
= self.lower_visibility(&i
.vis
, None
);
230 let mut attrs
= self.lower_attrs_extendable(&i
.attrs
);
231 if self.resolver
.has_derives(i
.id
, SpecialDerives
::PARTIAL_EQ
| SpecialDerives
::EQ
) {
232 // Add `#[structural_match]` if the item derived both `PartialEq` and `Eq`.
233 let ident
= Ident
::new(sym
::structural_match
, i
.span
);
234 attrs
.push(attr
::mk_attr_outer(attr
::mk_word_item(ident
)));
236 let attrs
= attrs
.into();
238 if let ItemKind
::MacroDef(ref def
) = i
.kind
{
239 if !def
.legacy
|| attr
::contains_name(&i
.attrs
, sym
::macro_export
) {
240 let body
= self.lower_token_stream(def
.stream());
241 let hir_id
= self.lower_node_id(i
.id
);
242 self.exported_macros
.push(hir
::MacroDef
{
252 self.non_exported_macro_attrs
.extend(attrs
.into_iter());
257 let kind
= self.lower_item_kind(i
.id
, &mut ident
, &attrs
, &mut vis
, &i
.kind
);
260 hir_id
: self.lower_node_id(i
.id
),
273 attrs
: &hir
::HirVec
<Attribute
>,
274 vis
: &mut hir
::Visibility
,
278 ItemKind
::ExternCrate(orig_name
) => hir
::ItemKind
::ExternCrate(orig_name
),
279 ItemKind
::Use(ref use_tree
) => {
280 // Start with an empty prefix.
286 self.lower_use_tree(use_tree
, &prefix
, id
, vis
, ident
, attrs
)
288 ItemKind
::Static(ref t
, m
, ref e
) => {
289 hir
::ItemKind
::Static(
292 if self.sess
.features_untracked().impl_trait_in_bindings
{
293 ImplTraitContext
::OpaqueTy(None
)
295 ImplTraitContext
::Disallowed(ImplTraitPosition
::Binding
)
298 self.lower_mutability(m
),
299 self.lower_const_body(e
),
302 ItemKind
::Const(ref t
, ref e
) => {
303 hir
::ItemKind
::Const(
306 if self.sess
.features_untracked().impl_trait_in_bindings
{
307 ImplTraitContext
::OpaqueTy(None
)
309 ImplTraitContext
::Disallowed(ImplTraitPosition
::Binding
)
312 self.lower_const_body(e
)
315 ItemKind
::Fn(ref decl
, header
, ref generics
, ref body
) => {
316 let fn_def_id
= self.resolver
.definitions().local_def_id(id
);
317 self.with_new_scopes(|this
| {
318 this
.current_item
= Some(ident
.span
);
320 // Note: we don't need to change the return type from `T` to
321 // `impl Future<Output = T>` here because lower_body
322 // only cares about the input argument patterns in the function
323 // declaration (decl), not the return types.
324 let body_id
= this
.lower_maybe_async_body(&decl
, header
.asyncness
.node
, body
);
326 let (generics
, fn_decl
) = this
.add_in_band_defs(
329 AnonymousLifetimeMode
::PassThrough
,
330 |this
, idty
| this
.lower_fn_decl(
332 Some((fn_def_id
, idty
)),
334 header
.asyncness
.node
.opt_return_id()
340 this
.lower_fn_header(header
),
346 ItemKind
::Mod(ref m
) => hir
::ItemKind
::Mod(self.lower_mod(m
)),
347 ItemKind
::ForeignMod(ref nm
) => hir
::ItemKind
::ForeignMod(self.lower_foreign_mod(nm
)),
348 ItemKind
::GlobalAsm(ref ga
) => hir
::ItemKind
::GlobalAsm(self.lower_global_asm(ga
)),
349 ItemKind
::TyAlias(ref t
, ref generics
) => hir
::ItemKind
::TyAlias(
350 self.lower_ty(t
, ImplTraitContext
::disallowed()),
351 self.lower_generics(generics
, ImplTraitContext
::disallowed()),
353 ItemKind
::OpaqueTy(ref b
, ref generics
) => hir
::ItemKind
::OpaqueTy(
355 generics
: self.lower_generics(generics
,
356 ImplTraitContext
::OpaqueTy(None
)),
357 bounds
: self.lower_param_bounds(b
,
358 ImplTraitContext
::OpaqueTy(None
)),
360 origin
: hir
::OpaqueTyOrigin
::TypeAlias
,
363 ItemKind
::Enum(ref enum_definition
, ref generics
) => {
366 variants
: enum_definition
369 .map(|x
| self.lower_variant(x
))
372 self.lower_generics(generics
, ImplTraitContext
::disallowed()),
375 ItemKind
::Struct(ref struct_def
, ref generics
) => {
376 let struct_def
= self.lower_variant_data(struct_def
);
377 hir
::ItemKind
::Struct(
379 self.lower_generics(generics
, ImplTraitContext
::disallowed()),
382 ItemKind
::Union(ref vdata
, ref generics
) => {
383 let vdata
= self.lower_variant_data(vdata
);
384 hir
::ItemKind
::Union(
386 self.lower_generics(generics
, ImplTraitContext
::disallowed()),
398 let def_id
= self.resolver
.definitions().local_def_id(id
);
400 // Lower the "impl header" first. This ordering is important
401 // for in-band lifetimes! Consider `'a` here:
403 // impl Foo<'a> for u32 {
404 // fn method(&'a self) { .. }
407 // Because we start by lowering the `Foo<'a> for u32`
408 // part, we will add `'a` to the list of generics on
409 // the impl. When we then encounter it later in the
410 // method, it will not be considered an in-band
411 // lifetime to be added, but rather a reference to a
413 let lowered_trait_impl_id
= self.lower_node_id(id
);
414 let (generics
, (trait_ref
, lowered_ty
)) = self.add_in_band_defs(
417 AnonymousLifetimeMode
::CreateParameter
,
419 let trait_ref
= trait_ref
.as_ref().map(|trait_ref
| {
420 this
.lower_trait_ref(trait_ref
, ImplTraitContext
::disallowed())
423 if let Some(ref trait_ref
) = trait_ref
{
424 if let Res
::Def(DefKind
::Trait
, def_id
) = trait_ref
.path
.res
{
425 this
.trait_impls
.entry(def_id
).or_default().push(
426 lowered_trait_impl_id
);
430 let lowered_ty
= this
.lower_ty(ty
, ImplTraitContext
::disallowed());
432 (trait_ref
, lowered_ty
)
436 let new_impl_items
= self.with_in_scope_lifetime_defs(
437 &ast_generics
.params
,
441 .map(|item
| this
.lower_impl_item_ref(item
))
447 self.lower_unsafety(unsafety
),
448 self.lower_impl_polarity(polarity
),
449 self.lower_defaultness(defaultness
, true /* [1] */),
456 ItemKind
::Trait(is_auto
, unsafety
, ref generics
, ref bounds
, ref items
) => {
457 let bounds
= self.lower_param_bounds(bounds
, ImplTraitContext
::disallowed());
460 .map(|item
| self.lower_trait_item_ref(item
))
462 hir
::ItemKind
::Trait(
463 self.lower_is_auto(is_auto
),
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(..)
475 | ItemKind
::Mac(..) => bug
!("`TyMac` should have been expanded by now"),
478 // [1] `defaultness.has_value()` is never called for an `impl`, always `true` in order to
479 // not cause an assertion failure inside the `lower_defaultness` function.
487 vis
: &mut hir
::Visibility
,
489 attrs
: &hir
::HirVec
<Attribute
>,
491 debug
!("lower_use_tree(tree={:?})", tree
);
492 debug
!("lower_use_tree: vis = {:?}", vis
);
494 let path
= &tree
.prefix
;
495 let segments
= prefix
498 .chain(path
.segments
.iter())
503 UseTreeKind
::Simple(rename
, id1
, id2
) => {
504 *ident
= tree
.ident();
506 // First, apply the prefix to the path.
507 let mut path
= Path
{
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 resolutions
.zip([id1
, id2
].iter()) {
534 let mut path
= path
.clone();
535 for seg
in &mut path
.segments
{
536 seg
.id
= self.sess
.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
);
544 this
.lower_path_extra(res
, &path
, ParamMode
::Explicit
, None
);
545 let kind
= hir
::ItemKind
::Use(P(path
), hir
::UseKind
::Single
);
546 let vis
= this
.rebuild_vis(&vis
);
552 attrs
: attrs
.into_iter().cloned().collect(),
561 let path
= P(self.lower_path_extra(ret_res
, &path
, ParamMode
::Explicit
, None
));
562 hir
::ItemKind
::Use(path
, hir
::UseKind
::Single
)
564 UseTreeKind
::Glob
=> {
565 let path
= P(self.lower_path(
573 hir
::ItemKind
::Use(path
, hir
::UseKind
::Glob
)
575 UseTreeKind
::Nested(ref trees
) => {
576 // Nested imports are desugared into simple imports.
577 // So, if we start with
580 // pub(x) use foo::{a, b};
583 // we will create three items:
586 // pub(x) use foo::a;
587 // pub(x) use foo::b;
588 // pub(x) use foo::{}; // <-- this is called the `ListStem`
591 // The first two are produced by recursively invoking
592 // `lower_use_tree` (and indeed there may be things
593 // like `use foo::{a::{b, c}}` and so forth). They
594 // wind up being directly added to
595 // `self.items`. However, the structure of this
596 // function also requires us to return one item, and
597 // for that we return the `{}` import (called the
602 span
: prefix
.span
.to(path
.span
),
605 // Add all the nested `PathListItem`s to the HIR.
606 for &(ref use_tree
, id
) in trees
{
607 let new_hir_id
= self.lower_node_id(id
);
609 let mut prefix
= prefix
.clone();
611 // Give the segments new node-ids since they are being cloned.
612 for seg
in &mut prefix
.segments
{
613 seg
.id
= self.sess
.next_node_id();
616 // Each `use` import is an item and thus are owners of the
617 // names in the path. Up to this point the nested import is
618 // the current owner, since we want each desugared import to
619 // own its own names, we have to adjust the owner before
620 // lowering the rest of the import.
621 self.with_hir_id_owner(id
, |this
| {
622 let mut vis
= this
.rebuild_vis(&vis
);
623 let mut ident
= *ident
;
625 let kind
= this
.lower_use_tree(use_tree
,
636 attrs
: attrs
.into_iter().cloned().collect(),
645 // Subtle and a bit hacky: we lower the privacy level
646 // of the list stem to "private" most of the time, but
647 // not for "restricted" paths. The key thing is that
648 // we don't want it to stay as `pub` (with no caveats)
649 // because that affects rustdoc and also the lints
650 // about `pub` items. But we can't *always* make it
651 // private -- particularly not for restricted paths --
652 // because it contains node-ids that would then be
653 // unused, failing the check that HirIds are "densely
656 hir
::VisibilityKind
::Public
|
657 hir
::VisibilityKind
::Crate(_
) |
658 hir
::VisibilityKind
::Inherited
=> {
659 *vis
= respan(prefix
.span
.shrink_to_lo(), hir
::VisibilityKind
::Inherited
);
661 hir
::VisibilityKind
::Restricted { .. }
=> {
662 // Do nothing here, as described in the comment on the match.
666 let res
= self.expect_full_res_from_use(id
).next().unwrap_or(Res
::Err
);
667 let res
= self.lower_res(res
);
668 let path
= P(self.lower_path_extra(res
, &prefix
, ParamMode
::Explicit
, None
));
669 hir
::ItemKind
::Use(path
, hir
::UseKind
::ListStem
)
674 /// Paths like the visibility path in `pub(super) use foo::{bar, baz}` are repeated
675 /// many times in the HIR tree; for each occurrence, we need to assign distinct
676 /// `NodeId`s. (See, e.g., #56128.)
677 fn rebuild_use_path(&mut self, path
: &hir
::Path
) -> hir
::Path
{
678 debug
!("rebuild_use_path(path = {:?})", path
);
679 let segments
= path
.segments
.iter().map(|seg
| hir
::PathSegment
{
681 hir_id
: seg
.hir_id
.map(|_
| self.next_id()),
684 infer_args
: seg
.infer_args
,
693 fn rebuild_vis(&mut self, vis
: &hir
::Visibility
) -> hir
::Visibility
{
694 let vis_kind
= match vis
.node
{
695 hir
::VisibilityKind
::Public
=> hir
::VisibilityKind
::Public
,
696 hir
::VisibilityKind
::Crate(sugar
) => hir
::VisibilityKind
::Crate(sugar
),
697 hir
::VisibilityKind
::Inherited
=> hir
::VisibilityKind
::Inherited
,
698 hir
::VisibilityKind
::Restricted { ref path, hir_id: _ }
=> {
699 hir
::VisibilityKind
::Restricted
{
700 path
: P(self.rebuild_use_path(path
)),
701 hir_id
: self.next_id(),
705 respan(vis
.span
, vis_kind
)
708 fn lower_foreign_item(&mut self, i
: &ForeignItem
) -> hir
::ForeignItem
{
709 let def_id
= self.resolver
.definitions().local_def_id(i
.id
);
711 hir_id
: self.lower_node_id(i
.id
),
713 attrs
: self.lower_attrs(&i
.attrs
),
715 ForeignItemKind
::Fn(ref fdec
, ref generics
) => {
716 let (generics
, (fn_dec
, fn_args
)) = self.add_in_band_defs(
719 AnonymousLifetimeMode
::PassThrough
,
722 // Disallow `impl Trait` in foreign items.
723 this
.lower_fn_decl(fdec
, None
, false, None
),
724 this
.lower_fn_params_to_names(fdec
),
729 hir
::ForeignItemKind
::Fn(fn_dec
, fn_args
, generics
)
731 ForeignItemKind
::Static(ref t
, m
) => {
732 hir
::ForeignItemKind
::Static(
733 self.lower_ty(t
, ImplTraitContext
::disallowed()), self.lower_mutability(m
))
735 ForeignItemKind
::Ty
=> hir
::ForeignItemKind
::Type
,
736 ForeignItemKind
::Macro(_
) => panic
!("macro shouldn't exist here"),
738 vis
: self.lower_visibility(&i
.vis
, None
),
743 fn lower_foreign_mod(&mut self, fm
: &ForeignMod
) -> hir
::ForeignMod
{
748 .map(|x
| self.lower_foreign_item(x
))
753 fn lower_global_asm(&mut self, ga
: &GlobalAsm
) -> P
<hir
::GlobalAsm
> {
754 P(hir
::GlobalAsm { asm: ga.asm }
)
757 fn lower_variant(&mut self, v
: &Variant
) -> hir
::Variant
{
759 attrs
: self.lower_attrs(&v
.attrs
),
760 data
: self.lower_variant_data(&v
.data
),
761 disr_expr
: v
.disr_expr
.as_ref().map(|e
| self.lower_anon_const(e
)),
762 id
: self.lower_node_id(v
.id
),
768 fn lower_variant_data(&mut self, vdata
: &VariantData
) -> hir
::VariantData
{
770 VariantData
::Struct(ref fields
, recovered
) => hir
::VariantData
::Struct(
771 fields
.iter().enumerate().map(|f
| self.lower_struct_field(f
)).collect(),
774 VariantData
::Tuple(ref fields
, id
) => {
775 hir
::VariantData
::Tuple(
779 .map(|f
| self.lower_struct_field(f
))
781 self.lower_node_id(id
),
784 VariantData
::Unit(id
) => {
785 hir
::VariantData
::Unit(self.lower_node_id(id
))
790 fn lower_struct_field(&mut self, (index
, f
): (usize, &StructField
)) -> hir
::StructField
{
791 let ty
= if let TyKind
::Path(ref qself
, ref path
) = f
.ty
.kind
{
792 let t
= self.lower_path_ty(
796 ParamMode
::ExplicitNamed
, // no `'_` in declarations (Issue #61124)
797 ImplTraitContext
::disallowed()
801 self.lower_ty(&f
.ty
, ImplTraitContext
::disallowed())
805 hir_id
: self.lower_node_id(f
.id
),
806 ident
: match f
.ident
{
807 Some(ident
) => ident
,
808 // FIXME(jseyfried): positional field hygiene.
809 None
=> Ident
::new(sym
::integer(index
), f
.span
),
811 vis
: self.lower_visibility(&f
.vis
, None
),
813 attrs
: self.lower_attrs(&f
.attrs
),
817 fn lower_trait_item(&mut self, i
: &TraitItem
) -> hir
::TraitItem
{
818 let trait_item_def_id
= self.resolver
.definitions().local_def_id(i
.id
);
820 let (generics
, kind
) = match i
.kind
{
821 TraitItemKind
::Const(ref ty
, ref default) => (
822 self.lower_generics(&i
.generics
, ImplTraitContext
::disallowed()),
823 hir
::TraitItemKind
::Const(
824 self.lower_ty(ty
, ImplTraitContext
::disallowed()),
827 .map(|x
| self.lower_const_body(x
)),
830 TraitItemKind
::Method(ref sig
, None
) => {
831 let names
= self.lower_fn_params_to_names(&sig
.decl
);
832 let (generics
, sig
) = self.lower_method_sig(
839 (generics
, hir
::TraitItemKind
::Method(sig
, hir
::TraitMethod
::Required(names
)))
841 TraitItemKind
::Method(ref sig
, Some(ref body
)) => {
842 let body_id
= self.lower_fn_body_block(&sig
.decl
, body
);
843 let (generics
, sig
) = self.lower_method_sig(
850 (generics
, hir
::TraitItemKind
::Method(sig
, hir
::TraitMethod
::Provided(body_id
)))
852 TraitItemKind
::Type(ref bounds
, ref default) => {
853 let generics
= self.lower_generics(&i
.generics
, ImplTraitContext
::disallowed());
854 let kind
= hir
::TraitItemKind
::Type(
855 self.lower_param_bounds(bounds
, ImplTraitContext
::disallowed()),
858 .map(|x
| self.lower_ty(x
, ImplTraitContext
::disallowed())),
863 TraitItemKind
::Macro(..) => bug
!("macro item shouldn't exist at this point"),
867 hir_id
: self.lower_node_id(i
.id
),
869 attrs
: self.lower_attrs(&i
.attrs
),
876 fn lower_trait_item_ref(&mut self, i
: &TraitItem
) -> hir
::TraitItemRef
{
877 let (kind
, has_default
) = match i
.kind
{
878 TraitItemKind
::Const(_
, ref default) => {
879 (hir
::AssocItemKind
::Const
, default.is_some())
881 TraitItemKind
::Type(_
, ref default) => {
882 (hir
::AssocItemKind
::Type
, default.is_some())
884 TraitItemKind
::Method(ref sig
, ref default) => (
885 hir
::AssocItemKind
::Method
{
886 has_self
: sig
.decl
.has_self(),
890 TraitItemKind
::Macro(..) => unimplemented
!(),
893 id
: hir
::TraitItemId { hir_id: self.lower_node_id(i.id) }
,
896 defaultness
: self.lower_defaultness(Defaultness
::Default
, has_default
),
901 fn lower_impl_item(&mut self, i
: &ImplItem
) -> hir
::ImplItem
{
902 let impl_item_def_id
= self.resolver
.definitions().local_def_id(i
.id
);
904 let (generics
, kind
) = match i
.kind
{
905 ImplItemKind
::Const(ref ty
, ref expr
) => (
906 self.lower_generics(&i
.generics
, ImplTraitContext
::disallowed()),
907 hir
::ImplItemKind
::Const(
908 self.lower_ty(ty
, ImplTraitContext
::disallowed()),
909 self.lower_const_body(expr
),
912 ImplItemKind
::Method(ref sig
, ref body
) => {
913 self.current_item
= Some(i
.span
);
914 let body_id
= self.lower_maybe_async_body(
915 &sig
.decl
, sig
.header
.asyncness
.node
, body
917 let impl_trait_return_allow
= !self.is_in_trait_impl
;
918 let (generics
, sig
) = self.lower_method_sig(
922 impl_trait_return_allow
,
923 sig
.header
.asyncness
.node
.opt_return_id(),
926 (generics
, hir
::ImplItemKind
::Method(sig
, body_id
))
928 ImplItemKind
::TyAlias(ref ty
) => (
929 self.lower_generics(&i
.generics
, ImplTraitContext
::disallowed()),
930 hir
::ImplItemKind
::TyAlias(self.lower_ty(ty
, ImplTraitContext
::disallowed())),
932 ImplItemKind
::OpaqueTy(ref bounds
) => (
933 self.lower_generics(&i
.generics
, ImplTraitContext
::disallowed()),
934 hir
::ImplItemKind
::OpaqueTy(
935 self.lower_param_bounds(bounds
, ImplTraitContext
::disallowed()),
938 ImplItemKind
::Macro(..) => bug
!("`TyMac` should have been expanded by now"),
942 hir_id
: self.lower_node_id(i
.id
),
944 attrs
: self.lower_attrs(&i
.attrs
),
946 vis
: self.lower_visibility(&i
.vis
, None
),
947 defaultness
: self.lower_defaultness(i
.defaultness
, true /* [1] */),
952 // [1] since `default impl` is not yet implemented, this is always true in impls
955 fn lower_impl_item_ref(&mut self, i
: &ImplItem
) -> hir
::ImplItemRef
{
957 id
: hir
::ImplItemId { hir_id: self.lower_node_id(i.id) }
,
960 vis
: self.lower_visibility(&i
.vis
, Some(i
.id
)),
961 defaultness
: self.lower_defaultness(i
.defaultness
, true /* [1] */),
963 ImplItemKind
::Const(..) => hir
::AssocItemKind
::Const
,
964 ImplItemKind
::TyAlias(..) => hir
::AssocItemKind
::Type
,
965 ImplItemKind
::OpaqueTy(..) => hir
::AssocItemKind
::OpaqueTy
,
966 ImplItemKind
::Method(ref sig
, _
) => hir
::AssocItemKind
::Method
{
967 has_self
: sig
.decl
.has_self(),
969 ImplItemKind
::Macro(..) => unimplemented
!(),
973 // [1] since `default impl` is not yet implemented, this is always true in impls
976 /// If an `explicit_owner` is given, this method allocates the `HirId` in
977 /// the address space of that item instead of the item currently being
978 /// lowered. This can happen during `lower_impl_item_ref()` where we need to
979 /// lower a `Visibility` value although we haven't lowered the owning
980 /// `ImplItem` in question yet.
984 explicit_owner
: Option
<NodeId
>,
985 ) -> hir
::Visibility
{
986 let node
= match v
.node
{
987 VisibilityKind
::Public
=> hir
::VisibilityKind
::Public
,
988 VisibilityKind
::Crate(sugar
) => hir
::VisibilityKind
::Crate(sugar
),
989 VisibilityKind
::Restricted { ref path, id }
=> {
990 debug
!("lower_visibility: restricted path id = {:?}", id
);
991 let lowered_id
= if let Some(owner
) = explicit_owner
{
992 self.lower_node_id_with_owner(id
, owner
)
994 self.lower_node_id(id
)
996 let res
= self.expect_full_res(id
);
997 let res
= self.lower_res(res
);
998 hir
::VisibilityKind
::Restricted
{
999 path
: P(self.lower_path_extra(
1002 ParamMode
::Explicit
,
1008 VisibilityKind
::Inherited
=> hir
::VisibilityKind
::Inherited
,
1010 respan(v
.span
, node
)
1013 fn lower_defaultness(&self, d
: Defaultness
, has_value
: bool
) -> hir
::Defaultness
{
1015 Defaultness
::Default
=> hir
::Defaultness
::Default
{
1016 has_value
: has_value
,
1018 Defaultness
::Final
=> {
1020 hir
::Defaultness
::Final
1025 fn lower_impl_polarity(&mut self, i
: ImplPolarity
) -> hir
::ImplPolarity
{
1027 ImplPolarity
::Positive
=> hir
::ImplPolarity
::Positive
,
1028 ImplPolarity
::Negative
=> hir
::ImplPolarity
::Negative
,
1032 fn record_body(&mut self, params
: HirVec
<hir
::Param
>, value
: hir
::Expr
) -> hir
::BodyId
{
1033 let body
= hir
::Body
{
1034 generator_kind
: self.generator_kind
,
1039 self.bodies
.insert(id
, body
);
1045 f
: impl FnOnce(&mut LoweringContext
<'_
>) -> (HirVec
<hir
::Param
>, hir
::Expr
),
1047 let prev_gen_kind
= self.generator_kind
.take();
1048 let (parameters
, result
) = f(self);
1049 let body_id
= self.record_body(parameters
, result
);
1050 self.generator_kind
= prev_gen_kind
;
1054 fn lower_param(&mut self, param
: &Param
) -> hir
::Param
{
1056 attrs
: self.lower_attrs(¶m
.attrs
),
1057 hir_id
: self.lower_node_id(param
.id
),
1058 pat
: self.lower_pat(¶m
.pat
),
1063 pub(super) fn lower_fn_body(
1066 body
: impl FnOnce(&mut LoweringContext
<'_
>) -> hir
::Expr
,
1068 self.lower_body(|this
| (
1069 decl
.inputs
.iter().map(|x
| this
.lower_param(x
)).collect(),
1074 fn lower_fn_body_block(&mut self, decl
: &FnDecl
, body
: &Block
) -> hir
::BodyId
{
1075 self.lower_fn_body(decl
, |this
| this
.lower_block_expr(body
))
1078 pub(super) fn lower_const_body(&mut self, expr
: &Expr
) -> hir
::BodyId
{
1079 self.lower_body(|this
| (hir_vec
![], this
.lower_expr(expr
)))
1082 fn lower_maybe_async_body(
1088 let closure_id
= match asyncness
{
1089 IsAsync
::Async { closure_id, .. }
=> closure_id
,
1090 IsAsync
::NotAsync
=> return self.lower_fn_body_block(decl
, body
),
1093 self.lower_body(|this
| {
1094 let mut parameters
: Vec
<hir
::Param
> = Vec
::new();
1095 let mut statements
: Vec
<hir
::Stmt
> = Vec
::new();
1097 // Async function parameters are lowered into the closure body so that they are
1098 // captured and so that the drop order matches the equivalent non-async functions.
1102 // async fn foo(<pattern>: <ty>, <pattern>: <ty>, <pattern>: <ty>) {
1108 // fn foo(__arg0: <ty>, __arg1: <ty>, __arg2: <ty>) {
1110 // let __arg2 = __arg2;
1111 // let <pattern> = __arg2;
1112 // let __arg1 = __arg1;
1113 // let <pattern> = __arg1;
1114 // let __arg0 = __arg0;
1115 // let <pattern> = __arg0;
1116 // drop-temps { <body> } // see comments later in fn for details
1120 // If `<pattern>` is a simple ident, then it is lowered to a single
1121 // `let <pattern> = <pattern>;` statement as an optimization.
1123 // Note that the body is embedded in `drop-temps`; an
1124 // equivalent desugaring would be `return { <body>
1125 // };`. The key point is that we wish to drop all the
1126 // let-bound variables and temporaries created in the body
1127 // (and its tail expression!) before we drop the
1128 // parameters (c.f. rust-lang/rust#64512).
1129 for (index
, parameter
) in decl
.inputs
.iter().enumerate() {
1130 let parameter
= this
.lower_param(parameter
);
1131 let span
= parameter
.pat
.span
;
1133 // Check if this is a binding pattern, if so, we can optimize and avoid adding a
1134 // `let <pat> = __argN;` statement. In this case, we do not rename the parameter.
1135 let (ident
, is_simple_parameter
) = match parameter
.pat
.kind
{
1136 hir
::PatKind
::Binding(hir
::BindingAnnotation
::Unannotated
, _
, ident
, _
) =>
1139 // Replace the ident for bindings that aren't simple.
1140 let name
= format
!("__arg{}", index
);
1141 let ident
= Ident
::from_str(&name
);
1147 let desugared_span
=
1148 this
.mark_span_with_reason(DesugaringKind
::Async
, span
, None
);
1150 // Construct a parameter representing `__argN: <ty>` to replace the parameter of the
1153 // If this is the simple case, this parameter will end up being the same as the
1154 // original parameter, but with a different pattern id.
1155 let mut stmt_attrs
= ThinVec
::new();
1156 stmt_attrs
.extend(parameter
.attrs
.iter().cloned());
1157 let (new_parameter_pat
, new_parameter_id
) = this
.pat_ident(desugared_span
, ident
);
1158 let new_parameter
= hir
::Param
{
1159 attrs
: parameter
.attrs
,
1160 hir_id
: parameter
.hir_id
,
1161 pat
: new_parameter_pat
,
1162 span
: parameter
.span
,
1166 if is_simple_parameter
{
1167 // If this is the simple case, then we only insert one statement that is
1168 // `let <pat> = <pat>;`. We re-use the original argument's pattern so that
1169 // `HirId`s are densely assigned.
1170 let expr
= this
.expr_ident(desugared_span
, ident
, new_parameter_id
);
1171 let stmt
= this
.stmt_let_pat(
1176 hir
::LocalSource
::AsyncFn
1178 statements
.push(stmt
);
1180 // If this is not the simple case, then we construct two statements:
1183 // let __argN = __argN;
1184 // let <pat> = __argN;
1187 // The first statement moves the parameter into the closure and thus ensures
1188 // that the drop order is correct.
1190 // The second statement creates the bindings that the user wrote.
1192 // Construct the `let mut __argN = __argN;` statement. It must be a mut binding
1193 // because the user may have specified a `ref mut` binding in the next
1195 let (move_pat
, move_id
) = this
.pat_ident_binding_mode(
1196 desugared_span
, ident
, hir
::BindingAnnotation
::Mutable
);
1197 let move_expr
= this
.expr_ident(desugared_span
, ident
, new_parameter_id
);
1198 let move_stmt
= this
.stmt_let_pat(
1203 hir
::LocalSource
::AsyncFn
1206 // Construct the `let <pat> = __argN;` statement. We re-use the original
1207 // parameter's pattern so that `HirId`s are densely assigned.
1208 let pattern_expr
= this
.expr_ident(desugared_span
, ident
, move_id
);
1209 let pattern_stmt
= this
.stmt_let_pat(
1212 Some(P(pattern_expr
)),
1214 hir
::LocalSource
::AsyncFn
1217 statements
.push(move_stmt
);
1218 statements
.push(pattern_stmt
);
1221 parameters
.push(new_parameter
);
1224 let async_expr
= this
.make_async_expr(
1229 hir
::AsyncGeneratorKind
::Fn
,
1231 // Create a block from the user's function body:
1232 let user_body
= this
.lower_block_expr(body
);
1234 // Transform into `drop-temps { <user-body> }`, an expression:
1235 let desugared_span
= this
.mark_span_with_reason(
1236 DesugaringKind
::Async
,
1240 let user_body
= this
.expr_drop_temps(
1246 // As noted above, create the final block like
1250 // let $param_pattern = $raw_param;
1252 // drop-temps { <user-body> }
1255 let body
= this
.block_all(
1260 this
.expr_block(P(body
), ThinVec
::new())
1262 (HirVec
::from(parameters
), this
.expr(body
.span
, async_expr
, ThinVec
::new()))
1266 fn lower_method_sig(
1268 generics
: &Generics
,
1271 impl_trait_return_allow
: bool
,
1272 is_async
: Option
<NodeId
>,
1273 ) -> (hir
::Generics
, hir
::MethodSig
) {
1274 let header
= self.lower_fn_header(sig
.header
);
1275 let (generics
, decl
) = self.add_in_band_defs(
1278 AnonymousLifetimeMode
::PassThrough
,
1279 |this
, idty
| this
.lower_fn_decl(
1281 Some((fn_def_id
, idty
)),
1282 impl_trait_return_allow
,
1286 (generics
, hir
::MethodSig { header, decl }
)
1289 fn lower_is_auto(&mut self, a
: IsAuto
) -> hir
::IsAuto
{
1291 IsAuto
::Yes
=> hir
::IsAuto
::Yes
,
1292 IsAuto
::No
=> hir
::IsAuto
::No
,
1296 fn lower_fn_header(&mut self, h
: FnHeader
) -> hir
::FnHeader
{
1298 unsafety
: self.lower_unsafety(h
.unsafety
),
1299 asyncness
: self.lower_asyncness(h
.asyncness
.node
),
1300 constness
: self.lower_constness(h
.constness
),
1305 pub(super) fn lower_unsafety(&mut self, u
: Unsafety
) -> hir
::Unsafety
{
1307 Unsafety
::Unsafe
=> hir
::Unsafety
::Unsafe
,
1308 Unsafety
::Normal
=> hir
::Unsafety
::Normal
,
1312 fn lower_constness(&mut self, c
: Spanned
<Constness
>) -> hir
::Constness
{
1314 Constness
::Const
=> hir
::Constness
::Const
,
1315 Constness
::NotConst
=> hir
::Constness
::NotConst
,
1319 fn lower_asyncness(&mut self, a
: IsAsync
) -> hir
::IsAsync
{
1321 IsAsync
::Async { .. }
=> hir
::IsAsync
::Async
,
1322 IsAsync
::NotAsync
=> hir
::IsAsync
::NotAsync
,
1326 pub(super) fn lower_generics(
1328 generics
: &Generics
,
1329 itctx
: ImplTraitContext
<'_
>)
1332 // Collect `?Trait` bounds in where clause and move them to parameter definitions.
1333 // FIXME: this could probably be done with less rightward drift. It also looks like two
1334 // control paths where `report_error` is called are the only paths that advance to after the
1335 // match statement, so the error reporting could probably just be moved there.
1336 let mut add_bounds
: NodeMap
<Vec
<_
>> = Default
::default();
1337 for pred
in &generics
.where_clause
.predicates
{
1338 if let WherePredicate
::BoundPredicate(ref bound_pred
) = *pred
{
1339 'next_bound
: for bound
in &bound_pred
.bounds
{
1340 if let GenericBound
::Trait(_
, TraitBoundModifier
::Maybe
) = *bound
{
1341 let report_error
= |this
: &mut Self| {
1342 this
.diagnostic().span_err(
1343 bound_pred
.bounded_ty
.span
,
1344 "`?Trait` bounds are only permitted at the \
1345 point where a type parameter is declared",
1348 // Check if the where clause type is a plain type parameter.
1349 match bound_pred
.bounded_ty
.kind
{
1350 TyKind
::Path(None
, ref path
)
1351 if path
.segments
.len() == 1
1352 && bound_pred
.bound_generic_params
.is_empty() =>
1354 if let Some(Res
::Def(DefKind
::TyParam
, def_id
)) = self.resolver
1355 .get_partial_res(bound_pred
.bounded_ty
.id
)
1356 .map(|d
| d
.base_res())
1358 if let Some(node_id
) =
1359 self.resolver
.definitions().as_local_node_id(def_id
)
1361 for param
in &generics
.params
{
1363 GenericParamKind
::Type { .. }
=> {
1364 if node_id
== param
.id
{
1365 add_bounds
.entry(param
.id
)
1367 .push(bound
.clone());
1368 continue 'next_bound
;
1378 _
=> report_error(self),
1386 params
: self.lower_generic_params(&generics
.params
, &add_bounds
, itctx
),
1387 where_clause
: self.lower_where_clause(&generics
.where_clause
),
1388 span
: generics
.span
,
1392 fn lower_where_clause(&mut self, wc
: &WhereClause
) -> hir
::WhereClause
{
1393 self.with_anonymous_lifetime_mode(
1394 AnonymousLifetimeMode
::ReportError
,
1397 predicates
: wc
.predicates
1399 .map(|predicate
| this
.lower_where_predicate(predicate
))
1407 fn lower_where_predicate(&mut self, pred
: &WherePredicate
) -> hir
::WherePredicate
{
1409 WherePredicate
::BoundPredicate(WhereBoundPredicate
{
1410 ref bound_generic_params
,
1415 self.with_in_scope_lifetime_defs(
1416 &bound_generic_params
,
1418 hir
::WherePredicate
::BoundPredicate(hir
::WhereBoundPredicate
{
1419 bound_generic_params
: this
.lower_generic_params(
1420 bound_generic_params
,
1421 &NodeMap
::default(),
1422 ImplTraitContext
::disallowed(),
1424 bounded_ty
: this
.lower_ty(bounded_ty
, ImplTraitContext
::disallowed()),
1427 .filter_map(|bound
| match *bound
{
1428 // Ignore `?Trait` bounds.
1429 // They were copied into type parameters already.
1430 GenericBound
::Trait(_
, TraitBoundModifier
::Maybe
) => None
,
1431 _
=> Some(this
.lower_param_bound(
1433 ImplTraitContext
::disallowed(),
1442 WherePredicate
::RegionPredicate(WhereRegionPredicate
{
1446 }) => hir
::WherePredicate
::RegionPredicate(hir
::WhereRegionPredicate
{
1448 lifetime
: self.lower_lifetime(lifetime
),
1449 bounds
: self.lower_param_bounds(bounds
, ImplTraitContext
::disallowed()),
1451 WherePredicate
::EqPredicate(WhereEqPredicate
{
1457 hir
::WherePredicate
::EqPredicate(hir
::WhereEqPredicate
{
1458 hir_id
: self.lower_node_id(id
),
1459 lhs_ty
: self.lower_ty(lhs_ty
, ImplTraitContext
::disallowed()),
1460 rhs_ty
: self.lower_ty(rhs_ty
, ImplTraitContext
::disallowed()),