Skip to content

Commit a6bd524

Browse files
committed
Auto merge of #80267 - 0urobor0s:ouro/61592, r=jyn514
Rustdoc render public underscore_imports as Re-exports Fixes #61592
2 parents 8b002d5 + cb4553b commit a6bd524

File tree

11 files changed

+109
-2
lines changed

11 files changed

+109
-2
lines changed

compiler/rustc_error_codes/src/error_codes.rs

+1
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,7 @@ E0776: include_str!("./error_codes/E0776.md"),
464464
E0777: include_str!("./error_codes/E0777.md"),
465465
E0778: include_str!("./error_codes/E0778.md"),
466466
E0779: include_str!("./error_codes/E0779.md"),
467+
E0780: include_str!("./error_codes/E0780.md"),
467468
;
468469
// E0006, // merged with E0005
469470
// E0008, // cannot bind by-move into a pattern guard
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Cannot use `doc(inline)` with anonymous imports
2+
3+
Erroneous code example:
4+
5+
```ignore (cannot-doctest-multicrate-project)
6+
7+
#[doc(inline)] // error: invalid doc argument
8+
pub use foo::Foo as _;
9+
```
10+
11+
Anonymous imports are always rendered with `#[doc(no_inline)]`. To fix this
12+
error, remove the `#[doc(inline)]` attribute.
13+
14+
Example:
15+
16+
```ignore (cannot-doctest-multicrate-project)
17+
18+
pub use foo::Foo as _;
19+
```

src/librustdoc/clean/mod.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -2173,11 +2173,26 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
21732173
return Vec::new();
21742174
}
21752175

2176+
let (doc_meta_item, please_inline) = self.attrs.lists(sym::doc).get_word_attr(sym::inline);
2177+
let pub_underscore = self.vis.node.is_pub() && self.name == kw::Underscore;
2178+
2179+
if pub_underscore && please_inline {
2180+
rustc_errors::struct_span_err!(
2181+
cx.tcx.sess,
2182+
doc_meta_item.unwrap().span(),
2183+
E0780,
2184+
"anonymous imports cannot be inlined"
2185+
)
2186+
.span_label(self.span, "anonymous import")
2187+
.emit();
2188+
}
2189+
21762190
// We consider inlining the documentation of `pub use` statements, but we
21772191
// forcefully don't inline if this is not public or if the
21782192
// #[doc(no_inline)] attribute is present.
21792193
// Don't inline doc(hidden) imports so they can be stripped at a later stage.
21802194
let mut denied = !self.vis.node.is_pub()
2195+
|| pub_underscore
21812196
|| self.attrs.iter().any(|a| {
21822197
a.has_name(sym::doc)
21832198
&& match a.meta_item_list() {
@@ -2190,7 +2205,6 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
21902205
});
21912206
// Also check whether imports were asked to be inlined, in case we're trying to re-export a
21922207
// crate in Rust 2018+
2193-
let please_inline = self.attrs.lists(sym::doc).has_word(sym::inline);
21942208
let path = self.path.clean(cx);
21952209
let inner = if self.glob {
21962210
if !denied {

src/librustdoc/clean/types.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -439,12 +439,22 @@ impl AttributesExt for [ast::Attribute] {
439439
crate trait NestedAttributesExt {
440440
/// Returns `true` if the attribute list contains a specific `Word`
441441
fn has_word(self, word: Symbol) -> bool;
442+
fn get_word_attr(self, word: Symbol) -> (Option<ast::NestedMetaItem>, bool);
442443
}
443444

444-
impl<I: IntoIterator<Item = ast::NestedMetaItem>> NestedAttributesExt for I {
445+
impl<I: Iterator<Item = ast::NestedMetaItem> + IntoIterator<Item = ast::NestedMetaItem>>
446+
NestedAttributesExt for I
447+
{
445448
fn has_word(self, word: Symbol) -> bool {
446449
self.into_iter().any(|attr| attr.is_word() && attr.has_name(word))
447450
}
451+
452+
fn get_word_attr(mut self, word: Symbol) -> (Option<ast::NestedMetaItem>, bool) {
453+
match self.find(|attr| attr.is_word() && attr.has_name(word)) {
454+
Some(a) => (Some(a), true),
455+
None => (None, false),
456+
}
457+
}
448458
}
449459

450460
/// A portion of documentation, extracted from a `#[doc]` attribute.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#![crate_name = "foo"]
2+
3+
pub trait Foo {}

src/test/rustdoc-ui/issue-61592-2.rs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// aux-build:issue-61592.rs
2+
3+
extern crate foo;
4+
5+
#[doc = "bar"]
6+
#[doc(inline)] //~ ERROR
7+
#[doc = "baz"]
8+
pub use foo::Foo as _;
9+
10+
fn main() {}
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0780]: anonymous imports cannot be inlined
2+
--> $DIR/issue-61592-2.rs:6:7
3+
|
4+
LL | #[doc(inline)]
5+
| ^^^^^^
6+
LL | #[doc = "baz"]
7+
LL | pub use foo::Foo as _;
8+
| ---------------------- anonymous import
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0780`.

src/test/rustdoc-ui/issue-61592.rs

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// aux-build:issue-61592.rs
2+
3+
extern crate foo;
4+
5+
#[doc(inline)] //~ ERROR
6+
pub use foo::Foo as _;
7+
8+
fn main() {}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0780]: anonymous imports cannot be inlined
2+
--> $DIR/issue-61592.rs:5:7
3+
|
4+
LL | #[doc(inline)]
5+
| ^^^^^^
6+
LL | pub use foo::Foo as _;
7+
| ---------------------- anonymous import
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0780`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#![crate_name = "foo"]
2+
3+
pub trait FooTrait {}
4+
pub struct FooStruct;

src/test/rustdoc/issue-61592.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// aux-build:issue-61592.rs
2+
3+
extern crate foo;
4+
5+
// @has issue_61592/index.html
6+
// @has - '//a[@href="#reexports"]' 'Re-exports'
7+
// @has - '//code' 'pub use foo::FooTrait as _;'
8+
// @!has - '//a[@href="trait._.html"]'
9+
pub use foo::FooTrait as _;
10+
11+
// @has issue_61592/index.html
12+
// @has - '//a[@href="#reexports"]' 'Re-exports'
13+
// @has - '//code' 'pub use foo::FooStruct as _;'
14+
// @!has - '//a[@href="struct._.html"]'
15+
pub use foo::FooStruct as _;

0 commit comments

Comments
 (0)