Skip to content

Commit 1f259ae

Browse files
committed
rustc_hir: Change representation of import paths to support multiple resolutions
1 parent 6cd4dd3 commit 1f259ae

File tree

19 files changed

+134
-112
lines changed

19 files changed

+134
-112
lines changed

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
508508
let mut resolutions = self.expect_full_res_from_use(id).fuse();
509509
// We want to return *something* from this function, so hold onto the first item
510510
// for later.
511-
let ret_res = self.lower_res(resolutions.next().unwrap_or(Res::Err));
511+
let ret_res = smallvec![self.lower_res(resolutions.next().unwrap_or(Res::Err))];
512512

513513
// Here, we are looping over namespaces, if they exist for the definition
514514
// being imported. We only handle type and value namespaces because we
@@ -538,8 +538,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
538538
let span = path.span;
539539

540540
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);
541+
let res = smallvec![this.lower_res(res)];
542+
let path = this.lower_use_path(res, &path, ParamMode::Explicit);
543543
let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
544544
if let Some(attrs) = attrs {
545545
this.attrs.insert(hir::ItemLocalId::new(0), attrs);
@@ -556,15 +556,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
556556
});
557557
}
558558

559-
let path = self.lower_path_extra(ret_res, &path, ParamMode::Explicit);
559+
let path = self.lower_use_path(ret_res, &path, ParamMode::Explicit);
560560
hir::ItemKind::Use(path, hir::UseKind::Single)
561561
}
562562
UseTreeKind::Glob => {
563-
let path = self.lower_path(
564-
id,
565-
&Path { segments, span: path.span, tokens: None },
566-
ParamMode::Explicit,
567-
);
563+
let res = self.expect_full_res(id);
564+
let res = smallvec![self.lower_res(res)];
565+
let path = Path { segments, span: path.span, tokens: None };
566+
let path = self.lower_use_path(res, &path, ParamMode::Explicit);
568567
hir::ItemKind::Use(path, hir::UseKind::Glob)
569568
}
570569
UseTreeKind::Nested(ref trees) => {
@@ -635,8 +634,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
635634
}
636635

637636
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);
637+
let res = smallvec![self.lower_res(res)];
638+
let path = self.lower_use_path(res, &prefix, ParamMode::Explicit);
640639
hir::ItemKind::Use(path, hir::UseKind::ListStem)
641640
}
642641
}

compiler/rustc_ast_lowering/src/path.rs

Lines changed: 5 additions & 16 deletions
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_data_structures/src/stable_hasher.rs

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 6 additions & 3 deletions
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

Lines changed: 6 additions & 3 deletions
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>) {
@@ -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>) {

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 1 addition & 1 deletion
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_passes/src/hir_stats.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
369369
hir_visit::walk_fn(self, fk, fd, b, id)
370370
}
371371

372-
fn visit_use(&mut self, p: &'v hir::Path<'v>, hir_id: hir::HirId) {
372+
fn visit_use(&mut self, p: &'v hir::UsePath<'v>, hir_id: hir::HirId) {
373373
// This is `visit_use`, but the type is `Path` so record it that way.
374374
self.record("Path", Id::None, p);
375375
hir_visit::walk_use(self, p, hir_id)

compiler/rustc_save_analysis/src/dump_visitor.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,13 +185,13 @@ impl<'tcx> DumpVisitor<'tcx> {
185185
}
186186
}
187187

188-
fn write_sub_paths(&mut self, path: &'tcx hir::Path<'tcx>) {
188+
fn write_sub_paths<R>(&mut self, path: &'tcx hir::Path<'tcx, R>) {
189189
self.write_segments(path.segments)
190190
}
191191

192192
// As write_sub_paths, but does not process the last ident in the path (assuming it
193193
// will be processed elsewhere). See note on write_sub_paths about global.
194-
fn write_sub_paths_truncated(&mut self, path: &'tcx hir::Path<'tcx>) {
194+
fn write_sub_paths_truncated<R>(&mut self, path: &'tcx hir::Path<'tcx, R>) {
195195
if let [segments @ .., _] = path.segments {
196196
self.write_segments(segments)
197197
}

compiler/rustc_save_analysis/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,9 @@ impl<'tcx> SaveContext<'tcx> {
594594
match self.tcx.hir().get(hir_id) {
595595
Node::TraitRef(tr) => tr.path.res,
596596

597-
Node::Item(&hir::Item { kind: hir::ItemKind::Use(path, _), .. }) => path.res,
597+
Node::Item(&hir::Item { kind: hir::ItemKind::Use(path, _), .. }) => {
598+
path.res.get(0).copied().unwrap_or(Res::Err)
599+
}
598600
Node::PathSegment(seg) => {
599601
if seg.res != Res::Err {
600602
seg.res

0 commit comments

Comments
 (0)