Skip to content

Commit

Permalink
Error on conflicting #[doc(inline)]/#[doc(no_inline)] attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
LeSeulArtichaut committed May 8, 2021
1 parent 245f582 commit f2077c7
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 64 deletions.
100 changes: 74 additions & 26 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use rustc_session::lint::builtin::{
};
use rustc_session::parse::feature_err;
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>(
tcx: TyCtxt<'tcx>,
Expand Down Expand Up @@ -67,6 +67,7 @@ impl CheckAttrVisitor<'tcx> {
item: Option<ItemLike<'_>>,
) {
let mut is_valid = true;
let mut specified_inline = None;
let attrs = self.tcx.hir().attrs(hir_id);
for attr in attrs {
is_valid &= match attr.name_or_empty() {
Expand All @@ -77,7 +78,7 @@ impl CheckAttrVisitor<'tcx> {
sym::track_caller => {
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::export_name => self.check_export_name(hir_id, &attr, span, target),
sym::rustc_args_required_const => {
Expand Down Expand Up @@ -564,6 +565,60 @@ impl CheckAttrVisitor<'tcx> {
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(
&self,
meta: &NestedMetaItem,
Expand Down Expand Up @@ -628,7 +683,13 @@ impl CheckAttrVisitor<'tcx> {
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;

if let Some(list) = attr.meta().and_then(|mi| mi.meta_item_list().map(|l| l.to_vec())) {
Expand Down Expand Up @@ -661,33 +722,18 @@ impl CheckAttrVisitor<'tcx> {
is_valid = false;
}

sym::inline | sym::no_inline if target != Target::Use => {
self.tcx.struct_span_lint_hir(
INVALID_DOC_ATTRIBUTES,
sym::inline | sym::no_inline
if !self.check_doc_inline(
&attr,
&meta,
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();
},
);
target,
specified_inline,
) =>
{
is_valid = false;
}

sym::inline | sym::no_inline => {
// FIXME(#80275): conflicting inline attributes
}

// no_default_passes: deprecated
// passes: deprecated
// plugins: removed, but rustdoc warns about it itself
Expand All @@ -700,10 +746,12 @@ impl CheckAttrVisitor<'tcx> {
| sym::html_playground_url
| sym::html_root_url
| sym::include
| sym::inline
| sym::issue_tracker_base_url
| sym::keyword
| sym::masked
| sym::no_default_passes
| sym::no_inline
| sym::notable_trait
| sym::passes
| sym::plugins
Expand Down
6 changes: 6 additions & 0 deletions src/test/rustdoc-ui/invalid-doc-attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,9 @@ pub mod bar {
//~| 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;
12 changes: 11 additions & 1 deletion src/test/rustdoc-ui/invalid-doc-attr.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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: 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
|
Expand All @@ -64,5 +74,5 @@ LL | pub fn baz() {}
= 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 5 previous errors
error: aborting due to 6 previous errors

11 changes: 0 additions & 11 deletions src/test/ui/attributes/doc-attr2.rs

This file was deleted.

26 changes: 0 additions & 26 deletions src/test/ui/attributes/doc-attr2.stderr

This file was deleted.

32 changes: 32 additions & 0 deletions src/test/ui/attributes/invalid-doc-attr.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 78 additions & 0 deletions src/test/ui/attributes/invalid-doc-attr.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit f2077c7

Please sign in to comment.