Skip to content

Commit 11663b1

Browse files
committed
Auto merge of #104963 - petrochenkov:noaddids2, r=cjgillot
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.
2 parents 56c241c + b32a4ed commit 11663b1

File tree

56 files changed

+227
-324
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+227
-324
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

+15-80
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,66 +490,16 @@ 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 = 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 = this.lower_res(res);
542-
let path = this.lower_path_extra(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_path_extra(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 => {
563-
let path = self.lower_path(
564-
id,
565-
&Path { segments, span: path.span, tokens: None },
566-
ParamMode::Explicit,
567-
);
499+
let res = self.expect_full_res(id);
500+
let res = smallvec![self.lower_res(res)];
501+
let path = Path { segments, span: path.span, tokens: None };
502+
let path = self.lower_use_path(res, &path, ParamMode::Explicit);
568503
hir::ItemKind::Use(path, hir::UseKind::Glob)
569504
}
570505
UseTreeKind::Nested(ref trees) => {
@@ -634,9 +569,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
634569
});
635570
}
636571

637-
let res = self.expect_full_res_from_use(id).next().unwrap_or(Res::Err);
638-
let res = self.lower_res(res);
639-
let path = self.lower_path_extra(res, &prefix, ParamMode::Explicit);
572+
let res =
573+
self.expect_full_res_from_use(id).map(|res| self.lower_res(res)).collect();
574+
let path = self.lower_use_path(res, &prefix, ParamMode::Explicit);
640575
hir::ItemKind::Use(path, hir::UseKind::ListStem)
641576
}
642577
}

compiler/rustc_ast_lowering/src/path.rs

+5-16
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_hir::GenericArg;
1212
use rustc_span::symbol::{kw, Ident};
1313
use rustc_span::{BytePos, Span, DUMMY_SP};
1414

15-
use smallvec::smallvec;
15+
use smallvec::{smallvec, SmallVec};
1616

1717
impl<'a, 'hir> LoweringContext<'a, 'hir> {
1818
#[instrument(level = "trace", skip(self))]
@@ -144,13 +144,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
144144
);
145145
}
146146

147-
pub(crate) fn lower_path_extra(
147+
pub(crate) fn lower_use_path(
148148
&mut self,
149-
res: Res,
149+
res: SmallVec<[Res; 3]>,
150150
p: &Path,
151151
param_mode: ParamMode,
152-
) -> &'hir hir::Path<'hir> {
153-
self.arena.alloc(hir::Path {
152+
) -> &'hir hir::UsePath<'hir> {
153+
self.arena.alloc(hir::UsePath {
154154
res,
155155
segments: self.arena.alloc_from_iter(p.segments.iter().map(|segment| {
156156
self.lower_path_segment(
@@ -165,17 +165,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
165165
})
166166
}
167167

168-
pub(crate) fn lower_path(
169-
&mut self,
170-
id: NodeId,
171-
p: &Path,
172-
param_mode: ParamMode,
173-
) -> &'hir hir::Path<'hir> {
174-
let res = self.expect_full_res(id);
175-
let res = self.lower_res(res);
176-
self.lower_path_extra(res, p, param_mode)
177-
}
178-
179168
pub(crate) fn lower_path_segment(
180169
&mut self,
181170
path_span: Span,

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_data_structures/src/stable_hasher.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ where
399399
}
400400
}
401401

402-
impl<A, CTX> HashStable<CTX> for SmallVec<[A; 1]>
402+
impl<A, const N: usize, CTX> HashStable<CTX> for SmallVec<[A; N]>
403403
where
404404
A: HashStable<CTX>,
405405
{

compiler/rustc_hir/src/arena.rs

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ macro_rules! arena_types {
3939
[] param: rustc_hir::Param<'tcx>,
4040
[] pat: rustc_hir::Pat<'tcx>,
4141
[] path: rustc_hir::Path<'tcx>,
42+
[] use_path: rustc_hir::UsePath<'tcx>,
4243
[] path_segment: rustc_hir::PathSegment<'tcx>,
4344
[] poly_trait_ref: rustc_hir::PolyTraitRef<'tcx>,
4445
[] qpath: rustc_hir::QPath<'tcx>,

compiler/rustc_hir/src/hir.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -183,14 +183,17 @@ impl Lifetime {
183183
/// `std::cmp::PartialEq`. It's represented as a sequence of identifiers,
184184
/// along with a bunch of supporting information.
185185
#[derive(Debug, HashStable_Generic)]
186-
pub struct Path<'hir> {
186+
pub struct Path<'hir, R = Res> {
187187
pub span: Span,
188188
/// The resolution for the path.
189-
pub res: Res,
189+
pub res: R,
190190
/// The segments in the path: the things separated by `::`.
191191
pub segments: &'hir [PathSegment<'hir>],
192192
}
193193

194+
/// Up to three resolutions for type, value and macro namespaces.
195+
pub type UsePath<'hir> = Path<'hir, SmallVec<[Res; 3]>>;
196+
194197
impl Path<'_> {
195198
pub fn is_global(&self) -> bool {
196199
!self.segments.is_empty() && self.segments[0].ident.name == kw::PathRoot
@@ -3068,7 +3071,7 @@ pub enum ItemKind<'hir> {
30683071
/// or just
30693072
///
30703073
/// `use foo::bar::baz;` (with `as baz` implicitly on the right).
3071-
Use(&'hir Path<'hir>, UseKind),
3074+
Use(&'hir UsePath<'hir>, UseKind),
30723075

30733076
/// A `static` item.
30743077
Static(&'hir Ty<'hir>, Mutability, BodyId),

compiler/rustc_hir/src/intravisit.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ pub trait Visitor<'v>: Sized {
367367
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl<'v>, b: BodyId, _: Span, id: HirId) {
368368
walk_fn(self, fk, fd, b, id)
369369
}
370-
fn visit_use(&mut self, path: &'v Path<'v>, hir_id: HirId) {
370+
fn visit_use(&mut self, path: &'v UsePath<'v>, hir_id: HirId) {
371371
walk_use(self, path, hir_id)
372372
}
373373
fn visit_trait_item(&mut self, ti: &'v TraitItem<'v>) {
@@ -422,7 +422,7 @@ pub trait Visitor<'v>: Sized {
422422
fn visit_qpath(&mut self, qpath: &'v QPath<'v>, id: HirId, _span: Span) {
423423
walk_qpath(self, qpath, id)
424424
}
425-
fn visit_path(&mut self, path: &'v Path<'v>, _id: HirId) {
425+
fn visit_path(&mut self, path: &Path<'v>, _id: HirId) {
426426
walk_path(self, path)
427427
}
428428
fn visit_path_segment(&mut self, path_segment: &'v PathSegment<'v>) {
@@ -938,9 +938,12 @@ pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'
938938
}
939939
}
940940

941-
pub fn walk_use<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path<'v>, hir_id: HirId) {
941+
pub fn walk_use<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v UsePath<'v>, hir_id: HirId) {
942942
visitor.visit_id(hir_id);
943-
visitor.visit_path(path, hir_id);
943+
let UsePath { segments, ref res, span } = *path;
944+
for &res in res {
945+
visitor.visit_path(&Path { segments, res, span }, hir_id);
946+
}
944947
}
945948

946949
pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem<'v>) {
@@ -1126,7 +1129,7 @@ pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, qpath: &'v QPath<'v>, id:
11261129
}
11271130
}
11281131

1129-
pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path<'v>) {
1132+
pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &Path<'v>) {
11301133
for segment in path.segments {
11311134
visitor.visit_path_segment(segment);
11321135
}

compiler/rustc_hir_analysis/src/collect/lifetimes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
814814
}
815815
}
816816

817-
fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, _: hir::HirId) {
817+
fn visit_path(&mut self, path: &hir::Path<'tcx>, _: hir::HirId) {
818818
for (i, segment) in path.segments.iter().enumerate() {
819819
let depth = path.segments.len() - i - 1;
820820
if let Some(ref args) = segment.args {

compiler/rustc_hir_pretty/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1591,7 +1591,7 @@ impl<'a> State<'a> {
15911591
self.print_ident(Ident::with_dummy_span(name))
15921592
}
15931593

1594-
pub fn print_path(&mut self, path: &hir::Path<'_>, colons_before_params: bool) {
1594+
pub fn print_path<R>(&mut self, path: &hir::Path<'_, R>, colons_before_params: bool) {
15951595
self.maybe_print_comment(path.span.lo());
15961596

15971597
for (i, segment) in path.segments.iter().enumerate() {

compiler/rustc_lint/src/internal.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
117117
fn check_path(
118118
&mut self,
119119
cx: &LateContext<'tcx>,
120-
path: &'tcx rustc_hir::Path<'tcx>,
120+
path: &rustc_hir::Path<'tcx>,
121121
_: rustc_hir::HirId,
122122
) {
123123
if let Some(segment) = path.segments.iter().nth_back(1)

compiler/rustc_lint/src/late.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
292292
hir_visit::walk_lifetime(self, lt);
293293
}
294294

295-
fn visit_path(&mut self, p: &'tcx hir::Path<'tcx>, id: hir::HirId) {
295+
fn visit_path(&mut self, p: &hir::Path<'tcx>, id: hir::HirId) {
296296
lint_callback!(self, check_path, p, id);
297297
hir_visit::walk_path(self, p);
298298
}

compiler/rustc_lint/src/passes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ macro_rules! late_lint_methods {
4444
fn check_struct_def(a: &$hir hir::VariantData<$hir>);
4545
fn check_field_def(a: &$hir hir::FieldDef<$hir>);
4646
fn check_variant(a: &$hir hir::Variant<$hir>);
47-
fn check_path(a: &$hir hir::Path<$hir>, b: hir::HirId);
47+
fn check_path(a: &hir::Path<$hir>, b: hir::HirId);
4848
fn check_attribute(a: &$hir ast::Attribute);
4949

5050
/// Called when entering a syntax node that can have lint attributes such

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;

0 commit comments

Comments
 (0)