Skip to content

Commit b32a4ed

Browse files
committed
rustc_ast_lowering: Stop lowering imports into multiple items
Lower them into a single item with multiple resolutions instead. This also allows to remove additional `NodId`s and `DefId`s related to those additional items.
1 parent 1f259ae commit b32a4ed

File tree

25 files changed

+79
-198
lines changed

25 files changed

+79
-198
lines changed

compiler/rustc_ast/src/ast.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -2517,10 +2517,7 @@ pub struct Variant {
25172517
#[derive(Clone, Encodable, Decodable, Debug)]
25182518
pub enum UseTreeKind {
25192519
/// `use prefix` or `use prefix as rename`
2520-
///
2521-
/// The extra `NodeId`s are for HIR lowering, when additional statements are created for each
2522-
/// namespace.
2523-
Simple(Option<Ident>, NodeId, NodeId),
2520+
Simple(Option<Ident>),
25242521
/// `use prefix::{...}`
25252522
Nested(Vec<(UseTree, NodeId)>),
25262523
/// `use prefix::*`
@@ -2539,8 +2536,8 @@ pub struct UseTree {
25392536
impl UseTree {
25402537
pub fn ident(&self) -> Ident {
25412538
match self.kind {
2542-
UseTreeKind::Simple(Some(rename), ..) => rename,
2543-
UseTreeKind::Simple(None, ..) => {
2539+
UseTreeKind::Simple(Some(rename)) => rename,
2540+
UseTreeKind::Simple(None) => {
25442541
self.prefix.segments.last().expect("empty prefix in a simple import").ident
25452542
}
25462543
_ => panic!("`UseTree::ident` can only be used on a simple import"),

compiler/rustc_ast/src/mut_visit.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -410,11 +410,7 @@ pub fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) {
410410
let UseTree { prefix, kind, span } = use_tree;
411411
vis.visit_path(prefix);
412412
match kind {
413-
UseTreeKind::Simple(rename, id1, id2) => {
414-
visit_opt(rename, |rename| vis.visit_ident(rename));
415-
vis.visit_id(id1);
416-
vis.visit_id(id2);
417-
}
413+
UseTreeKind::Simple(rename) => visit_opt(rename, |rename| vis.visit_ident(rename)),
418414
UseTreeKind::Nested(items) => {
419415
for (tree, id) in items {
420416
vis.visit_use_tree(tree);

compiler/rustc_ast/src/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ pub fn walk_path<'a, V: Visitor<'a>>(visitor: &mut V, path: &'a Path) {
439439
pub fn walk_use_tree<'a, V: Visitor<'a>>(visitor: &mut V, use_tree: &'a UseTree, id: NodeId) {
440440
visitor.visit_path(&use_tree.prefix, id);
441441
match &use_tree.kind {
442-
UseTreeKind::Simple(rename, ..) => {
442+
UseTreeKind::Simple(rename) => {
443443
// The extra IDs are handled during HIR lowering.
444444
if let &Some(rename) = rename {
445445
visitor.visit_ident(rename);

compiler/rustc_ast_lowering/src/item.rs

+10-74
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use rustc_span::symbol::{kw, sym, Ident};
1919
use rustc_span::{Span, Symbol};
2020
use rustc_target::spec::abi;
2121
use smallvec::{smallvec, SmallVec};
22-
use std::iter;
2322
use thin_vec::ThinVec;
2423

2524
pub(super) struct ItemLowerer<'a, 'hir> {
@@ -179,36 +178,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
179178
let mut node_ids =
180179
smallvec![hir::ItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } }];
181180
if let ItemKind::Use(use_tree) = &i.kind {
182-
self.lower_item_id_use_tree(use_tree, i.id, &mut node_ids);
181+
self.lower_item_id_use_tree(use_tree, &mut node_ids);
183182
}
184183
node_ids
185184
}
186185

187-
fn lower_item_id_use_tree(
188-
&mut self,
189-
tree: &UseTree,
190-
base_id: NodeId,
191-
vec: &mut SmallVec<[hir::ItemId; 1]>,
192-
) {
186+
fn lower_item_id_use_tree(&mut self, tree: &UseTree, vec: &mut SmallVec<[hir::ItemId; 1]>) {
193187
match &tree.kind {
194188
UseTreeKind::Nested(nested_vec) => {
195189
for &(ref nested, id) in nested_vec {
196190
vec.push(hir::ItemId {
197191
owner_id: hir::OwnerId { def_id: self.local_def_id(id) },
198192
});
199-
self.lower_item_id_use_tree(nested, id, vec);
200-
}
201-
}
202-
UseTreeKind::Glob => {}
203-
UseTreeKind::Simple(_, id1, id2) => {
204-
for (_, id) in
205-
iter::zip(self.expect_full_res_from_use(base_id).skip(1), [*id1, *id2])
206-
{
207-
vec.push(hir::ItemId {
208-
owner_id: hir::OwnerId { def_id: self.local_def_id(id) },
209-
});
193+
self.lower_item_id_use_tree(nested, vec);
210194
}
211195
}
196+
UseTreeKind::Simple(..) | UseTreeKind::Glob => {}
212197
}
213198
}
214199

@@ -489,7 +474,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
489474
let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect();
490475

491476
match tree.kind {
492-
UseTreeKind::Simple(rename, id1, id2) => {
477+
UseTreeKind::Simple(rename) => {
493478
*ident = tree.ident();
494479

495480
// First, apply the prefix to the path.
@@ -505,58 +490,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
505490
}
506491
}
507492

508-
let mut resolutions = self.expect_full_res_from_use(id).fuse();
509-
// We want to return *something* from this function, so hold onto the first item
510-
// for later.
511-
let ret_res = smallvec![self.lower_res(resolutions.next().unwrap_or(Res::Err))];
512-
513-
// Here, we are looping over namespaces, if they exist for the definition
514-
// being imported. We only handle type and value namespaces because we
515-
// won't be dealing with macros in the rest of the compiler.
516-
// Essentially a single `use` which imports two names is desugared into
517-
// two imports.
518-
for new_node_id in [id1, id2] {
519-
let new_id = self.local_def_id(new_node_id);
520-
let Some(res) = resolutions.next() else {
521-
debug_assert!(self.children.iter().find(|(id, _)| id == &new_id).is_none());
522-
// Associate an HirId to both ids even if there is no resolution.
523-
self.children.push((
524-
new_id,
525-
hir::MaybeOwner::NonOwner(hir::HirId::make_owner(new_id))),
526-
);
527-
continue;
528-
};
529-
let ident = *ident;
530-
let mut path = path.clone();
531-
for seg in &mut path.segments {
532-
// Give the cloned segment the same resolution information
533-
// as the old one (this is needed for stability checking).
534-
let new_id = self.next_node_id();
535-
self.resolver.clone_res(seg.id, new_id);
536-
seg.id = new_id;
537-
}
538-
let span = path.span;
539-
540-
self.with_hir_id_owner(new_node_id, |this| {
541-
let res = smallvec![this.lower_res(res)];
542-
let path = this.lower_use_path(res, &path, ParamMode::Explicit);
543-
let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
544-
if let Some(attrs) = attrs {
545-
this.attrs.insert(hir::ItemLocalId::new(0), attrs);
546-
}
547-
548-
let item = hir::Item {
549-
owner_id: hir::OwnerId { def_id: new_id },
550-
ident: this.lower_ident(ident),
551-
kind,
552-
vis_span,
553-
span: this.lower_span(span),
554-
};
555-
hir::OwnerNode::Item(this.arena.alloc(item))
556-
});
557-
}
558-
559-
let path = self.lower_use_path(ret_res, &path, ParamMode::Explicit);
493+
let res =
494+
self.expect_full_res_from_use(id).map(|res| self.lower_res(res)).collect();
495+
let path = self.lower_use_path(res, &path, ParamMode::Explicit);
560496
hir::ItemKind::Use(path, hir::UseKind::Single)
561497
}
562498
UseTreeKind::Glob => {
@@ -633,8 +569,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
633569
});
634570
}
635571

636-
let res = self.expect_full_res_from_use(id).next().unwrap_or(Res::Err);
637-
let res = smallvec![self.lower_res(res)];
572+
let res =
573+
self.expect_full_res_from_use(id).map(|res| self.lower_res(res)).collect();
638574
let path = self.lower_use_path(res, &prefix, ParamMode::Explicit);
639575
hir::ItemKind::Use(path, hir::UseKind::ListStem)
640576
}

compiler/rustc_ast_pretty/src/pprust/state/item.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ impl<'a> State<'a> {
663663

664664
fn print_use_tree(&mut self, tree: &ast::UseTree) {
665665
match &tree.kind {
666-
ast::UseTreeKind::Simple(rename, ..) => {
666+
ast::UseTreeKind::Simple(rename) => {
667667
self.print_path(&tree.prefix, false, 0);
668668
if let &Some(rename) = rename {
669669
self.nbsp();

compiler/rustc_builtin_macros/src/assert/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
106106
(
107107
UseTree {
108108
prefix: this.cx.path(this.span, vec![Ident::with_dummy_span(sym)]),
109-
kind: UseTreeKind::Simple(None, DUMMY_NODE_ID, DUMMY_NODE_ID),
109+
kind: UseTreeKind::Simple(None),
110110
span: this.span,
111111
},
112112
DUMMY_NODE_ID,

compiler/rustc_lint/src/unused.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1264,7 +1264,7 @@ impl UnusedImportBraces {
12641264

12651265
// Trigger the lint if the nested item is a non-self single item
12661266
let node_name = match items[0].0.kind {
1267-
ast::UseTreeKind::Simple(rename, ..) => {
1267+
ast::UseTreeKind::Simple(rename) => {
12681268
let orig_ident = items[0].0.prefix.segments.last().unwrap().ident;
12691269
if orig_ident.name == kw::SelfLower {
12701270
return;

compiler/rustc_parse/src/parser/item.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,7 @@ impl<'a> Parser<'a> {
10121012
prefix.span = lo.to(self.prev_token.span);
10131013
}
10141014

1015-
UseTreeKind::Simple(self.parse_rename()?, DUMMY_NODE_ID, DUMMY_NODE_ID)
1015+
UseTreeKind::Simple(self.parse_rename()?)
10161016
}
10171017
};
10181018

compiler/rustc_resolve/src/build_reduced_graph.rs

+2-13
Original file line numberDiff line numberDiff line change
@@ -445,19 +445,13 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
445445
prefix.is_empty() || prefix.len() == 1 && prefix[0].ident.name == kw::PathRoot
446446
};
447447
match use_tree.kind {
448-
ast::UseTreeKind::Simple(rename, id1, id2) => {
448+
ast::UseTreeKind::Simple(rename) => {
449449
let mut ident = use_tree.ident();
450450
let mut module_path = prefix;
451451
let mut source = module_path.pop().unwrap();
452452
let mut type_ns_only = false;
453453

454454
self.r.visibilities.insert(self.r.local_def_id(id), vis);
455-
if id1 != ast::DUMMY_NODE_ID {
456-
self.r.visibilities.insert(self.r.local_def_id(id1), vis);
457-
}
458-
if id2 != ast::DUMMY_NODE_ID {
459-
self.r.visibilities.insert(self.r.local_def_id(id2), vis);
460-
}
461455

462456
if nested {
463457
// Correctly handle `self`
@@ -565,7 +559,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
565559
type_ns_only,
566560
nested,
567561
id,
568-
additional_ids: (id1, id2),
569562
};
570563

571564
self.add_import(module_path, kind, use_tree.span, item, root_span, item.id, vis);
@@ -621,11 +614,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
621614
let new_span = prefix[prefix.len() - 1].ident.span;
622615
let tree = ast::UseTree {
623616
prefix: ast::Path::from_ident(Ident::new(kw::SelfLower, new_span)),
624-
kind: ast::UseTreeKind::Simple(
625-
Some(Ident::new(kw::Underscore, new_span)),
626-
ast::DUMMY_NODE_ID,
627-
ast::DUMMY_NODE_ID,
628-
),
617+
kind: ast::UseTreeKind::Simple(Some(Ident::new(kw::Underscore, new_span))),
629618
span: use_tree.span,
630619
};
631620
self.build_reduced_graph_for_use_tree(

compiler/rustc_resolve/src/def_collector.rs

-8
Original file line numberDiff line numberDiff line change
@@ -158,14 +158,6 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> {
158158

159159
fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) {
160160
self.create_def(id, DefPathData::Use, use_tree.span);
161-
match use_tree.kind {
162-
UseTreeKind::Simple(_, id1, id2) => {
163-
self.create_def(id1, DefPathData::Use, use_tree.prefix.span);
164-
self.create_def(id2, DefPathData::Use, use_tree.prefix.span);
165-
}
166-
UseTreeKind::Glob => (),
167-
UseTreeKind::Nested(..) => {}
168-
}
169161
visit::walk_use_tree(self, use_tree, id);
170162
}
171163

compiler/rustc_resolve/src/effective_visibilities.rs

+6-23
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{ImportKind, NameBinding, NameBindingKind, Resolver, ResolverTree};
1+
use crate::{NameBinding, NameBindingKind, Resolver, ResolverTree};
22
use rustc_ast::ast;
33
use rustc_ast::visit;
44
use rustc_ast::visit::Visitor;
@@ -104,28 +104,11 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
104104
for (binding, eff_vis) in visitor.import_effective_visibilities.iter() {
105105
let NameBindingKind::Import { import, .. } = binding.kind else { unreachable!() };
106106
if let Some(node_id) = import.id() {
107-
let mut update = |node_id| {
108-
r.effective_visibilities.update_eff_vis(
109-
r.local_def_id(node_id),
110-
eff_vis,
111-
ResolverTree(&r.definitions, &r.crate_loader),
112-
)
113-
};
114-
update(node_id);
115-
if let ImportKind::Single { additional_ids: (id1, id2), .. } = import.kind {
116-
// In theory all the single import IDs have individual visibilities and
117-
// effective visibilities, but in practice these IDs go straight to HIR
118-
// where all their few uses assume that their (effective) visibility
119-
// applies to the whole syntactic `use` item. So they all get the same
120-
// value which is the maximum of all bindings. Maybe HIR for imports
121-
// shouldn't use three IDs at all.
122-
if id1 != ast::DUMMY_NODE_ID {
123-
update(id1);
124-
}
125-
if id2 != ast::DUMMY_NODE_ID {
126-
update(id2);
127-
}
128-
}
107+
r.effective_visibilities.update_eff_vis(
108+
r.local_def_id(node_id),
109+
eff_vis,
110+
ResolverTree(&r.definitions, &r.crate_loader),
111+
)
129112
}
130113
}
131114

compiler/rustc_resolve/src/imports.rs

-5
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,6 @@ pub enum ImportKind<'a> {
5656
/// If this is the import for `foo::bar::a`, we would have the ID of the `UseTree`
5757
/// for `a` in this field.
5858
id: NodeId,
59-
/// Additional `NodeId`s allocated to a `ast::UseTree` for automatically generated `use` statement
60-
/// (eg. implicit struct constructors)
61-
additional_ids: (NodeId, NodeId),
6259
},
6360
Glob {
6461
is_prelude: bool,
@@ -88,7 +85,6 @@ impl<'a> std::fmt::Debug for ImportKind<'a> {
8885
ref type_ns_only,
8986
ref nested,
9087
ref id,
91-
ref additional_ids,
9288
// Ignore the following to avoid an infinite loop while printing.
9389
source_bindings: _,
9490
target_bindings: _,
@@ -99,7 +95,6 @@ impl<'a> std::fmt::Debug for ImportKind<'a> {
9995
.field("type_ns_only", type_ns_only)
10096
.field("nested", nested)
10197
.field("id", id)
102-
.field("additional_ids", additional_ids)
10398
.finish_non_exhaustive(),
10499
Glob { ref is_prelude, ref max_vis, ref id } => f
105100
.debug_struct("Glob")

src/librustdoc/json/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,10 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
225225

226226
types::ItemEnum::Function(_)
227227
| types::ItemEnum::Module(_)
228+
| types::ItemEnum::Import(_)
228229
| types::ItemEnum::AssocConst { .. }
229230
| types::ItemEnum::AssocType { .. } => true,
230231
types::ItemEnum::ExternCrate { .. }
231-
| types::ItemEnum::Import(_)
232232
| types::ItemEnum::StructField(_)
233233
| types::ItemEnum::Variant(_)
234234
| types::ItemEnum::TraitAlias(_)

src/test/ui/consts/miri_unleashed/tls.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ error[E0080]: could not evaluate static initializer
22
--> $DIR/tls.rs:11:25
33
|
44
LL | unsafe { let _val = A; }
5-
| ^ cannot access thread local static (DefId(0:6 ~ tls[78b0]::A))
5+
| ^ cannot access thread local static (DefId(0:4 ~ tls[78b0]::A))
66

77
error[E0080]: could not evaluate static initializer
88
--> $DIR/tls.rs:18:26
99
|
1010
LL | unsafe { let _val = &A; }
11-
| ^ cannot access thread local static (DefId(0:6 ~ tls[78b0]::A))
11+
| ^ cannot access thread local static (DefId(0:4 ~ tls[78b0]::A))
1212

1313
warning: skipping const checks
1414
|

src/test/ui/generator/print/generator-print-verbose-1.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ note: generator is not `Send` as this value is used across a yield
99
--> $DIR/generator-print-verbose-1.rs:35:9
1010
|
1111
LL | let _non_send_gen = make_non_send_generator();
12-
| ------------- has type `Opaque(DefId(0:44 ~ generator_print_verbose_1[749a]::make_non_send_generator::{opaque#0}), [])` which is not `Send`
12+
| ------------- has type `Opaque(DefId(0:34 ~ generator_print_verbose_1[749a]::make_non_send_generator::{opaque#0}), [])` which is not `Send`
1313
LL | yield;
1414
| ^^^^^ yield occurs here, with `_non_send_gen` maybe used later
1515
LL | };
@@ -35,17 +35,17 @@ note: required because it's used within this generator
3535
|
3636
LL | || {
3737
| ^^
38-
note: required because it appears within the type `Opaque(DefId(0:45 ~ generator_print_verbose_1[749a]::make_gen2::{opaque#0}), [std::sync::Arc<std::cell::RefCell<i32>>])`
38+
note: required because it appears within the type `Opaque(DefId(0:35 ~ generator_print_verbose_1[749a]::make_gen2::{opaque#0}), [std::sync::Arc<std::cell::RefCell<i32>>])`
3939
--> $DIR/generator-print-verbose-1.rs:41:30
4040
|
4141
LL | pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
4242
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
43-
note: required because it appears within the type `Opaque(DefId(0:46 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`
43+
note: required because it appears within the type `Opaque(DefId(0:36 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`
4444
--> $DIR/generator-print-verbose-1.rs:47:34
4545
|
4646
LL | fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> {
4747
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
48-
= note: required because it captures the following types: `Opaque(DefId(0:46 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`, `()`
48+
= note: required because it captures the following types: `Opaque(DefId(0:36 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`, `()`
4949
note: required because it's used within this generator
5050
--> $DIR/generator-print-verbose-1.rs:52:20
5151
|

0 commit comments

Comments
 (0)