Skip to content

Commit 56ecb15

Browse files
authored
Rollup merge of #153630 - arferreira:fix-doc-hidden-reexport-diagnostic-path, r=jackh726
Deprioritize doc(hidden) re-exports in diagnostic paths Fixes #153477. This is the other half of #99698, which fixed the case where the *parent module* is `#[doc(hidden)]` but left the case where the re-export itself is `#[doc(hidden)]` as a FIXME (with a tracking test in `dont-suggest-doc-hidden-variant-for-enum/hidden-child.rs`). The problem: when a crate does `#[doc(hidden)] pub use core::error::Error`, diagnostics pick up the hidden re-export path instead of the canonical one. For example, `snafu::Error` instead of `std::error::Error`. Two changes: In `visible_parent_map`, the `add_child` closure now checks whether the re-export itself is `#[doc(hidden)]` via `reexport_chain` and sends it to `fallback_map`, same treatment as doc-hidden parents and underscore re-exports. `should_encode_attrs` now returns `true` for `DefKind::Use`. Without this, `#[doc(hidden)]` on `use` items was never written to crate metadata, so `is_doc_hidden` always returned `false` cross-crate. This was the actual root cause, the check in `visible_parent_map` alone isn't enough if the attribute isn't in the metadata. The existing FIXME test now serves as the regression test. The `.stderr` goes from suggesting `hidden_child::__private::Some(1i32)` to just `Some(1i32)`. cc @eggyal
2 parents 8bd2996 + 4d3f0db commit 56ecb15

4 files changed

Lines changed: 29 additions & 11 deletions

File tree

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -455,10 +455,11 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
455455

456456
let mut visible_parent_map: DefIdMap<DefId> = Default::default();
457457
// This is a secondary visible_parent_map, storing the DefId of
458-
// parents that re-export the child as `_` or module parents
459-
// which are `#[doc(hidden)]`. Since we prefer paths that don't
460-
// do this, merge this map at the end, only if we're missing
461-
// keys from the former.
458+
// parents that re-export the child as `_`, module parents
459+
// which are `#[doc(hidden)]`, or `use` items that are themselves
460+
// `#[doc(hidden)]`. Since we prefer paths that don't do this,
461+
// merge this map at the end, only if we're missing keys from
462+
// the former.
462463
// This is a rudimentary check that does not catch all cases,
463464
// just the easiest.
464465
let mut fallback_map: Vec<(DefId, DefId)> = Default::default();
@@ -500,6 +501,18 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
500501
return;
501502
}
502503

504+
// If the re-export itself is `#[doc(hidden)]`, deprioritize it.
505+
// See PR #99698 for the case where the *parent* is doc-hidden.
506+
if child
507+
.reexport_chain
508+
.first()
509+
.and_then(|r| r.id())
510+
.is_some_and(|id| tcx.is_doc_hidden(id))
511+
{
512+
fallback_map.push((def_id, parent));
513+
return;
514+
}
515+
503516
match visible_parent_map.entry(def_id) {
504517
Entry::Occupied(mut entry) => {
505518
// If `child` is defined in crate `cnum`, ensure

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,10 @@ fn should_encode_attrs(def_kind: DefKind) -> bool {
943943
| DefKind::Macro(_)
944944
| DefKind::Field
945945
| DefKind::Impl { .. } => true,
946+
// Encoding attrs for `Use` items allows `#[doc(hidden)]` on re-exports
947+
// to be read cross-crate, which is needed for diagnostic path selection
948+
// in `visible_parent_map`. See #153477.
949+
DefKind::Use => true,
946950
// Tools may want to be able to detect their tool lints on
947951
// closures from upstream crates, too. This is used by
948952
// https://github.com/model-checking/kani and is not a performance
@@ -953,7 +957,6 @@ fn should_encode_attrs(def_kind: DefKind) -> bool {
953957
| DefKind::ConstParam
954958
| DefKind::Ctor(..)
955959
| DefKind::ExternCrate
956-
| DefKind::Use
957960
| DefKind::ForeignMod
958961
| DefKind::AnonConst
959962
| DefKind::InlineConst

tests/ui/suggestions/dont-suggest-doc-hidden-variant-for-enum/hidden-child.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
//@ aux-build:hidden-child.rs
22

3-
// FIXME(compiler-errors): This currently suggests the wrong thing.
4-
// UI test exists to track the problem.
3+
// Regression test for #153477.
4+
// When a re-export is #[doc(hidden)], diagnostics should prefer
5+
// the canonical path (e.g. `Some`) over the hidden re-export path
6+
// (e.g. `hidden_child::__private::Some`).
57

68
extern crate hidden_child;
79

tests/ui/suggestions/dont-suggest-doc-hidden-variant-for-enum/hidden-child.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0308]: mismatched types
2-
--> $DIR/hidden-child.rs:9:26
2+
--> $DIR/hidden-child.rs:11:26
33
|
44
LL | let x: Option<i32> = 1i32;
55
| ----------- ^^^^ expected `Option<i32>`, found `i32`
@@ -8,10 +8,10 @@ LL | let x: Option<i32> = 1i32;
88
|
99
= note: expected enum `Option<i32>`
1010
found type `i32`
11-
help: try wrapping the expression in `hidden_child::__private::Some`
11+
help: try wrapping the expression in `Some`
1212
|
13-
LL | let x: Option<i32> = hidden_child::__private::Some(1i32);
14-
| ++++++++++++++++++++++++++++++ +
13+
LL | let x: Option<i32> = Some(1i32);
14+
| +++++ +
1515

1616
error: aborting due to 1 previous error
1717

0 commit comments

Comments
 (0)