Error on conflicting #[doc(inline)]
/#[doc(no_inline)]
attributes
This commit is contained in:
parent
245f582139
commit
f2077c728c
7 changed files with 201 additions and 64 deletions
|
@ -22,7 +22,7 @@ use rustc_session::lint::builtin::{
|
||||||
};
|
};
|
||||||
use rustc_session::parse::feature_err;
|
use rustc_session::parse::feature_err;
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::{sym, Symbol};
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{MultiSpan, Span, DUMMY_SP};
|
||||||
|
|
||||||
pub(crate) fn target_from_impl_item<'tcx>(
|
pub(crate) fn target_from_impl_item<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
|
@ -67,6 +67,7 @@ impl CheckAttrVisitor<'tcx> {
|
||||||
item: Option<ItemLike<'_>>,
|
item: Option<ItemLike<'_>>,
|
||||||
) {
|
) {
|
||||||
let mut is_valid = true;
|
let mut is_valid = true;
|
||||||
|
let mut specified_inline = None;
|
||||||
let attrs = self.tcx.hir().attrs(hir_id);
|
let attrs = self.tcx.hir().attrs(hir_id);
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
is_valid &= match attr.name_or_empty() {
|
is_valid &= match attr.name_or_empty() {
|
||||||
|
@ -77,7 +78,7 @@ impl CheckAttrVisitor<'tcx> {
|
||||||
sym::track_caller => {
|
sym::track_caller => {
|
||||||
self.check_track_caller(hir_id, &attr.span, attrs, span, target)
|
self.check_track_caller(hir_id, &attr.span, attrs, span, target)
|
||||||
}
|
}
|
||||||
sym::doc => self.check_doc_attrs(attr, hir_id, target),
|
sym::doc => self.check_doc_attrs(attr, hir_id, target, &mut specified_inline),
|
||||||
sym::no_link => self.check_no_link(hir_id, &attr, span, target),
|
sym::no_link => self.check_no_link(hir_id, &attr, span, target),
|
||||||
sym::export_name => self.check_export_name(hir_id, &attr, span, target),
|
sym::export_name => self.check_export_name(hir_id, &attr, span, target),
|
||||||
sym::rustc_args_required_const => {
|
sym::rustc_args_required_const => {
|
||||||
|
@ -564,6 +565,60 @@ impl CheckAttrVisitor<'tcx> {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_doc_inline(
|
||||||
|
&self,
|
||||||
|
attr: &Attribute,
|
||||||
|
meta: &NestedMetaItem,
|
||||||
|
hir_id: HirId,
|
||||||
|
target: Target,
|
||||||
|
specified_inline: &mut Option<(bool, Span)>,
|
||||||
|
) -> bool {
|
||||||
|
if target == Target::Use {
|
||||||
|
let do_inline = meta.name_or_empty() == sym::inline;
|
||||||
|
if let Some((prev_inline, prev_span)) = *specified_inline {
|
||||||
|
if do_inline != prev_inline {
|
||||||
|
let mut spans = MultiSpan::from_spans(vec![prev_span, meta.span()]);
|
||||||
|
spans.push_span_label(prev_span, String::from("this attribute..."));
|
||||||
|
spans.push_span_label(
|
||||||
|
meta.span(),
|
||||||
|
String::from("...conflicts with this attribute"),
|
||||||
|
);
|
||||||
|
self.tcx
|
||||||
|
.sess
|
||||||
|
.struct_span_err(spans, "conflicting doc inlining attributes")
|
||||||
|
.help("remove one of the conflicting attributes")
|
||||||
|
.emit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
*specified_inline = Some((do_inline, meta.span()));
|
||||||
|
true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.tcx.struct_span_lint_hir(
|
||||||
|
INVALID_DOC_ATTRIBUTES,
|
||||||
|
hir_id,
|
||||||
|
meta.span(),
|
||||||
|
|lint| {
|
||||||
|
let mut err = lint.build(
|
||||||
|
"this attribute can only be applied to a `use` item",
|
||||||
|
);
|
||||||
|
err.span_label(meta.span(), "only applicable on `use` items");
|
||||||
|
if attr.style == AttrStyle::Outer {
|
||||||
|
err.span_label(
|
||||||
|
self.tcx.hir().span(hir_id),
|
||||||
|
"not a `use` item",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
err.note("read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#docno_inlinedocinline for more information")
|
||||||
|
.emit();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn check_attr_not_crate_level(
|
fn check_attr_not_crate_level(
|
||||||
&self,
|
&self,
|
||||||
meta: &NestedMetaItem,
|
meta: &NestedMetaItem,
|
||||||
|
@ -628,7 +683,13 @@ impl CheckAttrVisitor<'tcx> {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_doc_attrs(&self, attr: &Attribute, hir_id: HirId, target: Target) -> bool {
|
fn check_doc_attrs(
|
||||||
|
&self,
|
||||||
|
attr: &Attribute,
|
||||||
|
hir_id: HirId,
|
||||||
|
target: Target,
|
||||||
|
specified_inline: &mut Option<(bool, Span)>,
|
||||||
|
) -> bool {
|
||||||
let mut is_valid = true;
|
let mut is_valid = true;
|
||||||
|
|
||||||
if let Some(list) = attr.meta().and_then(|mi| mi.meta_item_list().map(|l| l.to_vec())) {
|
if let Some(list) = attr.meta().and_then(|mi| mi.meta_item_list().map(|l| l.to_vec())) {
|
||||||
|
@ -661,33 +722,18 @@ impl CheckAttrVisitor<'tcx> {
|
||||||
is_valid = false;
|
is_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::inline | sym::no_inline if target != Target::Use => {
|
sym::inline | sym::no_inline
|
||||||
self.tcx.struct_span_lint_hir(
|
if !self.check_doc_inline(
|
||||||
INVALID_DOC_ATTRIBUTES,
|
&attr,
|
||||||
|
&meta,
|
||||||
hir_id,
|
hir_id,
|
||||||
meta.span(),
|
target,
|
||||||
|lint| {
|
specified_inline,
|
||||||
let mut err = lint.build(
|
) =>
|
||||||
"this attribute can only be applied to a `use` item",
|
{
|
||||||
);
|
|
||||||
err.span_label(meta.span(), "only applicable on `use` items");
|
|
||||||
if attr.style == AttrStyle::Outer {
|
|
||||||
err.span_label(
|
|
||||||
self.tcx.hir().span(hir_id),
|
|
||||||
"not a `use` item",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
err.note("read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#docno_inlinedocinline for more information")
|
|
||||||
.emit();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
is_valid = false;
|
is_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
sym::inline | sym::no_inline => {
|
|
||||||
// FIXME(#80275): conflicting inline attributes
|
|
||||||
}
|
|
||||||
|
|
||||||
// no_default_passes: deprecated
|
// no_default_passes: deprecated
|
||||||
// passes: deprecated
|
// passes: deprecated
|
||||||
// plugins: removed, but rustdoc warns about it itself
|
// plugins: removed, but rustdoc warns about it itself
|
||||||
|
@ -700,10 +746,12 @@ impl CheckAttrVisitor<'tcx> {
|
||||||
| sym::html_playground_url
|
| sym::html_playground_url
|
||||||
| sym::html_root_url
|
| sym::html_root_url
|
||||||
| sym::include
|
| sym::include
|
||||||
|
| sym::inline
|
||||||
| sym::issue_tracker_base_url
|
| sym::issue_tracker_base_url
|
||||||
| sym::keyword
|
| sym::keyword
|
||||||
| sym::masked
|
| sym::masked
|
||||||
| sym::no_default_passes
|
| sym::no_default_passes
|
||||||
|
| sym::no_inline
|
||||||
| sym::notable_trait
|
| sym::notable_trait
|
||||||
| sym::passes
|
| sym::passes
|
||||||
| sym::plugins
|
| sym::plugins
|
||||||
|
|
|
@ -24,3 +24,9 @@ pub mod bar {
|
||||||
//~| WARN is being phased out
|
//~| WARN is being phased out
|
||||||
pub fn baz() {}
|
pub fn baz() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(inline)]
|
||||||
|
#[doc(no_inline)]
|
||||||
|
//~^^ ERROR conflicting doc inlining attributes
|
||||||
|
//~| HELP remove one of the conflicting attributes
|
||||||
|
pub use bar::baz;
|
||||||
|
|
|
@ -41,6 +41,16 @@ LL | #![doc(test(no_crate_inject))]
|
||||||
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
|
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
|
||||||
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information
|
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information
|
||||||
|
|
||||||
|
error: conflicting doc inlining attributes
|
||||||
|
--> $DIR/invalid-doc-attr.rs:28:7
|
||||||
|
|
|
||||||
|
LL | #[doc(inline)]
|
||||||
|
| ^^^^^^ this attribute...
|
||||||
|
LL | #[doc(no_inline)]
|
||||||
|
| ^^^^^^^^^ ...conflicts with this attribute
|
||||||
|
|
|
||||||
|
= help: remove one of the conflicting attributes
|
||||||
|
|
||||||
error: this attribute can only be applied at the crate level
|
error: this attribute can only be applied at the crate level
|
||||||
--> $DIR/invalid-doc-attr.rs:19:11
|
--> $DIR/invalid-doc-attr.rs:19:11
|
||||||
|
|
|
|
||||||
|
@ -64,5 +74,5 @@ LL | pub fn baz() {}
|
||||||
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
|
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
|
||||||
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#docno_inlinedocinline for more information
|
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#docno_inlinedocinline for more information
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
#![crate_type = "lib"]
|
|
||||||
#![deny(warnings)]
|
|
||||||
|
|
||||||
#[doc(test(no_crate_inject))] //~ ERROR
|
|
||||||
//~^ WARN
|
|
||||||
pub fn foo() {}
|
|
||||||
|
|
||||||
pub mod bar {
|
|
||||||
#![doc(test(no_crate_inject))] //~ ERROR
|
|
||||||
//~^ WARN
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
error: `#![doc(test(...)]` is only allowed as a crate-level attribute
|
|
||||||
--> $DIR/doc-attr2.rs:4:7
|
|
||||||
|
|
|
||||||
LL | #[doc(test(no_crate_inject))]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/doc-attr2.rs:2:9
|
|
||||||
|
|
|
||||||
LL | #![deny(warnings)]
|
|
||||||
| ^^^^^^^^
|
|
||||||
= note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
|
|
||||||
|
|
||||||
error: `#![doc(test(...)]` is only allowed as a crate-level attribute
|
|
||||||
--> $DIR/doc-attr2.rs:9:12
|
|
||||||
|
|
|
||||||
LL | #![doc(test(no_crate_inject))]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
32
src/test/ui/attributes/invalid-doc-attr.rs
Normal file
32
src/test/ui/attributes/invalid-doc-attr.rs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
#![deny(warnings)]
|
||||||
|
|
||||||
|
#[doc(test(no_crate_inject))]
|
||||||
|
//~^ ERROR can only be applied at the crate level
|
||||||
|
//~| WARN is being phased out
|
||||||
|
//~| HELP to apply to the crate, use an inner attribute
|
||||||
|
//~| SUGGESTION #![doc(test(no_crate_inject))]
|
||||||
|
#[doc(inline)]
|
||||||
|
//~^ ERROR can only be applied to a `use` item
|
||||||
|
//~| WARN is being phased out
|
||||||
|
pub fn foo() {}
|
||||||
|
|
||||||
|
pub mod bar {
|
||||||
|
#![doc(test(no_crate_inject))]
|
||||||
|
//~^ ERROR can only be applied at the crate level
|
||||||
|
//~| WARN is being phased out
|
||||||
|
|
||||||
|
#[doc(test(no_crate_inject))]
|
||||||
|
//~^ ERROR can only be applied at the crate level
|
||||||
|
//~| WARN is being phased out
|
||||||
|
#[doc(inline)]
|
||||||
|
//~^ ERROR can only be applied to a `use` item
|
||||||
|
//~| WARN is being phased out
|
||||||
|
pub fn baz() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(inline)]
|
||||||
|
#[doc(no_inline)]
|
||||||
|
//~^^ ERROR conflicting doc inlining attributes
|
||||||
|
//~| HELP remove one of the conflicting attributes
|
||||||
|
pub use bar::baz;
|
78
src/test/ui/attributes/invalid-doc-attr.stderr
Normal file
78
src/test/ui/attributes/invalid-doc-attr.stderr
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
error: this attribute can only be applied at the crate level
|
||||||
|
--> $DIR/invalid-doc-attr.rs:4:7
|
||||||
|
|
|
||||||
|
LL | #[doc(test(no_crate_inject))]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/invalid-doc-attr.rs:2:9
|
||||||
|
|
|
||||||
|
LL | #![deny(warnings)]
|
||||||
|
| ^^^^^^^^
|
||||||
|
= note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
|
||||||
|
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information
|
||||||
|
help: to apply to the crate, use an inner attribute
|
||||||
|
|
|
||||||
|
LL | #![doc(test(no_crate_inject))]
|
||||||
|
|
|
||||||
|
|
||||||
|
error: this attribute can only be applied to a `use` item
|
||||||
|
--> $DIR/invalid-doc-attr.rs:9:7
|
||||||
|
|
|
||||||
|
LL | #[doc(inline)]
|
||||||
|
| ^^^^^^ only applicable on `use` items
|
||||||
|
...
|
||||||
|
LL | pub fn foo() {}
|
||||||
|
| ------------ not a `use` item
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
|
||||||
|
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#docno_inlinedocinline for more information
|
||||||
|
|
||||||
|
error: this attribute can only be applied at the crate level
|
||||||
|
--> $DIR/invalid-doc-attr.rs:15:12
|
||||||
|
|
|
||||||
|
LL | #![doc(test(no_crate_inject))]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
|
||||||
|
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information
|
||||||
|
|
||||||
|
error: conflicting doc inlining attributes
|
||||||
|
--> $DIR/invalid-doc-attr.rs:28:7
|
||||||
|
|
|
||||||
|
LL | #[doc(inline)]
|
||||||
|
| ^^^^^^ this attribute...
|
||||||
|
LL | #[doc(no_inline)]
|
||||||
|
| ^^^^^^^^^ ...conflicts with this attribute
|
||||||
|
|
|
||||||
|
= help: remove one of the conflicting attributes
|
||||||
|
|
||||||
|
error: this attribute can only be applied at the crate level
|
||||||
|
--> $DIR/invalid-doc-attr.rs:19:11
|
||||||
|
|
|
||||||
|
LL | #[doc(test(no_crate_inject))]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
|
||||||
|
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level for more information
|
||||||
|
|
||||||
|
error: this attribute can only be applied to a `use` item
|
||||||
|
--> $DIR/invalid-doc-attr.rs:22:11
|
||||||
|
|
|
||||||
|
LL | #[doc(inline)]
|
||||||
|
| ^^^^^^ only applicable on `use` items
|
||||||
|
...
|
||||||
|
LL | pub fn baz() {}
|
||||||
|
| ------------ not a `use` item
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
|
||||||
|
= note: read https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#docno_inlinedocinline for more information
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue