Skip to content

Commit 245f582

Browse files
Emit invalid_doc_attributes warnings in more cases
1 parent 50e1dc1 commit 245f582

File tree

5 files changed

+169
-49
lines changed

5 files changed

+169
-49
lines changed

compiler/rustc_passes/src/check_attr.rs

+75-12
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_middle::hir::map::Map;
88
use rustc_middle::ty::query::Providers;
99
use rustc_middle::ty::TyCtxt;
1010

11-
use rustc_ast::{Attribute, Lit, LitKind, NestedMetaItem};
11+
use rustc_ast::{AttrStyle, Attribute, Lit, LitKind, NestedMetaItem};
1212
use rustc_errors::{pluralize, struct_span_err, Applicability};
1313
use rustc_hir as hir;
1414
use rustc_hir::def_id::LocalDefId;
@@ -564,7 +564,7 @@ impl CheckAttrVisitor<'tcx> {
564564
true
565565
}
566566

567-
fn check_attr_crate_level(
567+
fn check_attr_not_crate_level(
568568
&self,
569569
meta: &NestedMetaItem,
570570
hir_id: HirId,
@@ -586,6 +586,48 @@ impl CheckAttrVisitor<'tcx> {
586586
true
587587
}
588588

589+
fn check_attr_crate_level(
590+
&self,
591+
attr: &Attribute,
592+
meta: &NestedMetaItem,
593+
hir_id: HirId,
594+
) -> bool {
595+
if hir_id != CRATE_HIR_ID {
596+
self.tcx.struct_span_lint_hir(
597+
INVALID_DOC_ATTRIBUTES,
598+
hir_id,
599+
meta.span(),
600+
|lint| {
601+
let mut err = lint.build(
602+
"this attribute can only be applied at the crate level",
603+
);
604+
if attr.style == AttrStyle::Outer && self.tcx.hir().get_parent_item(hir_id) == CRATE_HIR_ID {
605+
if let Ok(mut src) =
606+
self.tcx.sess.source_map().span_to_snippet(attr.span)
607+
{
608+
src.insert(1, '!');
609+
err.span_suggestion_verbose(
610+
attr.span,
611+
"to apply to the crate, use an inner attribute",
612+
src,
613+
Applicability::MaybeIncorrect,
614+
);
615+
} else {
616+
err.span_help(
617+
attr.span,
618+
"to apply to the crate, use an inner attribute",
619+
);
620+
}
621+
}
622+
err.note("read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information")
623+
.emit();
624+
},
625+
);
626+
return false;
627+
}
628+
true
629+
}
630+
589631
fn check_doc_attrs(&self, attr: &Attribute, hir_id: HirId, target: Target) -> bool {
590632
let mut is_valid = true;
591633

@@ -594,35 +636,58 @@ impl CheckAttrVisitor<'tcx> {
594636
if let Some(i_meta) = meta.meta_item() {
595637
match i_meta.name_or_empty() {
596638
sym::alias
597-
if !self.check_attr_crate_level(&meta, hir_id, "alias")
639+
if !self.check_attr_not_crate_level(&meta, hir_id, "alias")
598640
|| !self.check_doc_alias(&meta, hir_id, target) =>
599641
{
600642
is_valid = false
601643
}
602644

603645
sym::keyword
604-
if !self.check_attr_crate_level(&meta, hir_id, "keyword")
646+
if !self.check_attr_not_crate_level(&meta, hir_id, "keyword")
605647
|| !self.check_doc_keyword(&meta, hir_id) =>
606648
{
607649
is_valid = false
608650
}
609651

610-
sym::test if CRATE_HIR_ID != hir_id => {
652+
sym::html_favicon_url
653+
| sym::html_logo_url
654+
| sym::html_playground_url
655+
| sym::issue_tracker_base_url
656+
| sym::html_root_url
657+
| sym::html_no_source
658+
| sym::test
659+
if !self.check_attr_crate_level(&attr, &meta, hir_id) =>
660+
{
661+
is_valid = false;
662+
}
663+
664+
sym::inline | sym::no_inline if target != Target::Use => {
611665
self.tcx.struct_span_lint_hir(
612666
INVALID_DOC_ATTRIBUTES,
613667
hir_id,
614668
meta.span(),
615669
|lint| {
616-
lint.build(
617-
"`#![doc(test(...)]` is only allowed \
618-
as a crate-level attribute",
619-
)
620-
.emit();
670+
let mut err = lint.build(
671+
"this attribute can only be applied to a `use` item",
672+
);
673+
err.span_label(meta.span(), "only applicable on `use` items");
674+
if attr.style == AttrStyle::Outer {
675+
err.span_label(
676+
self.tcx.hir().span(hir_id),
677+
"not a `use` item",
678+
);
679+
}
680+
err.note("read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#docno_inlinedocinline for more information")
681+
.emit();
621682
},
622683
);
623684
is_valid = false;
624685
}
625686

687+
sym::inline | sym::no_inline => {
688+
// FIXME(#80275): conflicting inline attributes
689+
}
690+
626691
// no_default_passes: deprecated
627692
// passes: deprecated
628693
// plugins: removed, but rustdoc warns about it itself
@@ -635,12 +700,10 @@ impl CheckAttrVisitor<'tcx> {
635700
| sym::html_playground_url
636701
| sym::html_root_url
637702
| sym::include
638-
| sym::inline
639703
| sym::issue_tracker_base_url
640704
| sym::keyword
641705
| sym::masked
642706
| sym::no_default_passes
643-
| sym::no_inline
644707
| sym::notable_trait
645708
| sym::passes
646709
| sym::plugins

src/test/rustdoc-ui/doc-attr2.rs

-11
This file was deleted.

src/test/rustdoc-ui/doc-attr2.stderr

-26
This file was deleted.
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#![crate_type = "lib"]
2+
#![deny(warnings)]
3+
4+
#[doc(test(no_crate_inject))]
5+
//~^ ERROR can only be applied at the crate level
6+
//~| WARN is being phased out
7+
//~| HELP to apply to the crate, use an inner attribute
8+
//~| SUGGESTION #![doc(test(no_crate_inject))]
9+
#[doc(inline)]
10+
//~^ ERROR can only be applied to a `use` item
11+
//~| WARN is being phased out
12+
pub fn foo() {}
13+
14+
pub mod bar {
15+
#![doc(test(no_crate_inject))]
16+
//~^ ERROR can only be applied at the crate level
17+
//~| WARN is being phased out
18+
19+
#[doc(test(no_crate_inject))]
20+
//~^ ERROR can only be applied at the crate level
21+
//~| WARN is being phased out
22+
#[doc(inline)]
23+
//~^ ERROR can only be applied to a `use` item
24+
//~| WARN is being phased out
25+
pub fn baz() {}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
error: this attribute can only be applied at the crate level
2+
--> $DIR/invalid-doc-attr.rs:4:7
3+
|
4+
LL | #[doc(test(no_crate_inject))]
5+
| ^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: the lint level is defined here
8+
--> $DIR/invalid-doc-attr.rs:2:9
9+
|
10+
LL | #![deny(warnings)]
11+
| ^^^^^^^^
12+
= note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
13+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
14+
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
15+
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information
16+
help: to apply to the crate, use an inner attribute
17+
|
18+
LL | #![doc(test(no_crate_inject))]
19+
|
20+
21+
error: this attribute can only be applied to a `use` item
22+
--> $DIR/invalid-doc-attr.rs:9:7
23+
|
24+
LL | #[doc(inline)]
25+
| ^^^^^^ only applicable on `use` items
26+
...
27+
LL | pub fn foo() {}
28+
| ------------ not a `use` item
29+
|
30+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
31+
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
32+
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#docno_inlinedocinline for more information
33+
34+
error: this attribute can only be applied at the crate level
35+
--> $DIR/invalid-doc-attr.rs:15:12
36+
|
37+
LL | #![doc(test(no_crate_inject))]
38+
| ^^^^^^^^^^^^^^^^^^^^^
39+
|
40+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
41+
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
42+
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information
43+
44+
error: this attribute can only be applied at the crate level
45+
--> $DIR/invalid-doc-attr.rs:19:11
46+
|
47+
LL | #[doc(test(no_crate_inject))]
48+
| ^^^^^^^^^^^^^^^^^^^^^
49+
|
50+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
51+
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
52+
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information
53+
54+
error: this attribute can only be applied to a `use` item
55+
--> $DIR/invalid-doc-attr.rs:22:11
56+
|
57+
LL | #[doc(inline)]
58+
| ^^^^^^ only applicable on `use` items
59+
...
60+
LL | pub fn baz() {}
61+
| ------------ not a `use` item
62+
|
63+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
64+
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
65+
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#docno_inlinedocinline for more information
66+
67+
error: aborting due to 5 previous errors
68+

0 commit comments

Comments
 (0)