Skip to content
40 changes: 23 additions & 17 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2752,7 +2752,7 @@ impl<'a> LoweringContext<'a> {
id: NodeId,
name: &mut Name,
attrs: &hir::HirVec<Attribute>,
vis: &mut hir::Visibility,
vis: &hir::Visibility,
i: &ItemKind,
) -> hir::ItemKind {
match *i {
Expand Down Expand Up @@ -2955,7 +2955,7 @@ impl<'a> LoweringContext<'a> {
tree: &UseTree,
prefix: &Path,
id: NodeId,
vis: &mut hir::Visibility,
vis: &hir::Visibility,
name: &mut Name,
attrs: &hir::HirVec<Attribute>,
) -> hir::ItemKind {
Expand Down Expand Up @@ -3029,12 +3029,7 @@ impl<'a> LoweringContext<'a> {
hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
hir::VisibilityKind::Restricted { ref path, id: _, hir_id: _ } => {
let id = this.next_id();
let mut path = path.clone();
for seg in path.segments.iter_mut() {
if seg.id.is_some() {
seg.id = Some(this.next_id().node_id);
}
}
let path = this.renumber_segment_ids(path);
hir::VisibilityKind::Restricted {
path,
id: id.node_id,
Expand Down Expand Up @@ -3091,7 +3086,7 @@ impl<'a> LoweringContext<'a> {
hir_id: new_hir_id,
} = self.lower_node_id(id);

let mut vis = vis.clone();
let vis = vis.clone();
let mut name = name.clone();
let mut prefix = prefix.clone();

Expand All @@ -3109,7 +3104,7 @@ impl<'a> LoweringContext<'a> {
let item = this.lower_use_tree(use_tree,
&prefix,
new_id,
&mut vis,
&vis,
&mut name,
attrs);

Expand All @@ -3119,8 +3114,9 @@ impl<'a> LoweringContext<'a> {
hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
hir::VisibilityKind::Restricted { ref path, id: _, hir_id: _ } => {
let id = this.next_id();
let path = this.renumber_segment_ids(path);
hir::VisibilityKind::Restricted {
path: path.clone(),
path: path,
id: id.node_id,
hir_id: id.hir_id,
}
Expand All @@ -3143,17 +3139,27 @@ impl<'a> LoweringContext<'a> {
});
}

// Privatize the degenerate import base, used only to check
// the stability of `use a::{};`, to avoid it showing up as
// a re-export by accident when `pub`, e.g. in documentation.
let def = self.expect_full_def_from_use(id).next().unwrap_or(Def::Err);
let path = P(self.lower_path_extra(def, &prefix, ParamMode::Explicit, None));
*vis = respan(prefix.span.shrink_to_lo(), hir::VisibilityKind::Inherited);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, you still need to reset at least pub (hir::VisibilityKind::Public) into something more private, otherwise you'll get a lot of noise from rustdoc (the stem is emitted for all braced imports).

This way the hack for UnreachablePub can be avoided as well.

This should be ok since hir::VisibilityKind::Public doesn't have a path with node IDs inside it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything except for VisibilityKind::Restricted can be reset to VisibilityKind::Inherited basically.

hir::ItemKind::Use(path, hir::UseKind::ListStem)
}
}
}

/// Paths like the visibility path in `pub(super) use foo::{bar, baz}` are repeated
/// many times in the HIR tree; for each occurrence, we need to assign distinct
/// node-ids. (See e.g. #56128.)
fn renumber_segment_ids(&mut self, path: &P<hir::Path>) -> P<hir::Path> {
debug!("renumber_segment_ids(path = {:?})", path);
let mut path = path.clone();
for seg in path.segments.iter_mut() {
if seg.id.is_some() {
seg.id = Some(self.next_id().node_id);
}
}
path
}

fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id);
let trait_item_def_id = self.resolver.definitions().local_def_id(node_id);
Expand Down Expand Up @@ -3378,7 +3384,7 @@ impl<'a> LoweringContext<'a> {

pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item> {
let mut name = i.ident.name;
let mut vis = self.lower_visibility(&i.vis, None);
let vis = self.lower_visibility(&i.vis, None);
let attrs = self.lower_attrs(&i.attrs);
if let ItemKind::MacroDef(ref def) = i.node {
if !def.legacy || attr::contains_name(&i.attrs, "macro_export") ||
Expand All @@ -3397,7 +3403,7 @@ impl<'a> LoweringContext<'a> {
return None;
}

let node = self.lower_item_kind(i.id, &mut name, &attrs, &mut vis, &i.node);
let node = self.lower_item_kind(i.id, &mut name, &attrs, &vis, &i.node);

let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id);

Expand Down
10 changes: 9 additions & 1 deletion src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1136,7 +1136,15 @@ impl UnreachablePub {

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnreachablePub {
fn check_item(&mut self, cx: &LateContext, item: &hir::Item) {
self.perform_lint(cx, "item", item.id, &item.vis, item.span, true);
match item.node {
hir::ItemKind::Use(_, hir::UseKind::ListStem) => {
// Hack: ignore these `use foo::{}` remnants which are just a figment
// our IR.
}
_ => {
self.perform_lint(cx, "item", item.id, &item.vis, item.span, true);
}
}
}

fn check_foreign_item(&mut self, cx: &LateContext, foreign_item: &hir::ForeignItem) {
Expand Down
15 changes: 15 additions & 0 deletions src/test/ui/issues/issue-56128.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Regression test for #56128. When this `pub(super) use...` gets
// exploded in the HIR, we were not handling ids correctly.
//
// compile-pass

mod bar {
pub(super) use self::baz::{x, y};

mod baz {
pub fn x() { }
pub fn y() { }
}
}

fn main() { }