Fix empty_line_after_outer_attribute false positive

This commit is contained in:
Samuel E. Moelius III 2022-05-25 19:22:44 -04:00
parent 3cc50a4a08
commit 9ee211af9f
5 changed files with 41 additions and 13 deletions

View file

@ -40,6 +40,7 @@ filetime = "0.2"
rustc-workspace-hack = "1.0"
# UI test dependencies
clap = { version = "3.1", features = ["derive"] }
clippy_utils = { path = "clippy_utils" }
derive-new = "0.5"
if_chain = "1.0"

View file

@ -585,15 +585,21 @@ impl EarlyLintPass for EarlyAttributes {
}
fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
for attr in &item.attrs {
let mut iter = item.attrs.iter().peekable();
while let Some(attr) = iter.next() {
if matches!(attr.kind, AttrKind::Normal(..))
&& attr.style == AttrStyle::Outer
&& is_present_in_source(cx, attr.span)
{
let begin_of_attr_to_item = Span::new(attr.span.lo(), item.span.lo(), item.span.ctxt(), item.span.parent());
let end_of_attr_to_item = Span::new(attr.span.hi(), item.span.lo(), item.span.ctxt(), item.span.parent());
let end_of_attr_to_next_attr_or_item = Span::new(
attr.span.hi(),
iter.peek().map_or(item.span.lo(), |next_attr| next_attr.span.lo()),
item.span.ctxt(),
item.span.parent(),
);
if let Some(snippet) = snippet_opt(cx, end_of_attr_to_item) {
if let Some(snippet) = snippet_opt(cx, end_of_attr_to_next_attr_or_item) {
let lines = snippet.split('\n').collect::<Vec<_>>();
let lines = without_block_comments(lines);
@ -623,8 +629,15 @@ fn check_deprecated_cfg_attr(cx: &EarlyContext<'_>, attr: &Attribute, msrv: Opti
if feature_item.has_name(sym::rustfmt);
// check for `rustfmt_skip` and `rustfmt::skip`
if let Some(skip_item) = &items[1].meta_item();
if skip_item.has_name(sym!(rustfmt_skip)) ||
skip_item.path.segments.last().expect("empty path in attribute").ident.name == sym::skip;
if skip_item.has_name(sym!(rustfmt_skip))
|| skip_item
.path
.segments
.last()
.expect("empty path in attribute")
.ident
.name
== sym::skip;
// Only lint outer attributes, because custom inner attributes are unstable
// Tracking issue: https://github.com/rust-lang/rust/issues/54726
if attr.style == AttrStyle::Outer;

View file

@ -22,6 +22,7 @@ const RUN_INTERNAL_TESTS: bool = cfg!(feature = "internal");
/// All crates used in UI tests are listed here
static TEST_DEPENDENCIES: &[&str] = &[
"clap",
"clippy_utils",
"derive_new",
"futures",
@ -40,6 +41,8 @@ static TEST_DEPENDENCIES: &[&str] = &[
// Test dependencies may need an `extern crate` here to ensure that they show up
// in the depinfo file (otherwise cargo thinks they are unused)
#[allow(unused_extern_crates)]
extern crate clap;
#[allow(unused_extern_crates)]
extern crate clippy_utils;
#[allow(unused_extern_crates)]
extern crate derive_new;
@ -109,8 +112,9 @@ static EXTERN_FLAGS: SyncLazy<String> = SyncLazy::new(|| {
not_found.is_empty(),
"dependencies not found in depinfo: {:?}\n\
help: Make sure the `-Z binary-dep-depinfo` rust flag is enabled\n\
help: Try adding to dev-dependencies in Cargo.toml",
not_found
help: Try adding to dev-dependencies in Cargo.toml\n\
help: Be sure to also add `extern crate ...;` to tests/compile-test.rs",
not_found,
);
crates
.into_iter()

View file

@ -4,6 +4,9 @@
#![feature(custom_inner_attributes)]
#![rustfmt::skip]
#[macro_use]
extern crate clap;
#[macro_use]
extern crate proc_macro_attr;
@ -110,4 +113,11 @@ pub trait Bazz {
}
}
#[derive(clap::Parser)]
#[clap(after_help = "This ia a help message.
You're welcome.
")]
pub struct Args;
fn main() {}

View file

@ -1,5 +1,5 @@
error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
--> $DIR/empty_line_after_outer_attribute.rs:11:1
--> $DIR/empty_line_after_outer_attribute.rs:14:1
|
LL | / #[crate_type = "lib"]
LL | |
@ -10,7 +10,7 @@ LL | | fn with_one_newline_and_comment() { assert!(true) }
= note: `-D clippy::empty-line-after-outer-attr` implied by `-D warnings`
error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
--> $DIR/empty_line_after_outer_attribute.rs:23:1
--> $DIR/empty_line_after_outer_attribute.rs:26:1
|
LL | / #[crate_type = "lib"]
LL | |
@ -18,7 +18,7 @@ LL | | fn with_one_newline() { assert!(true) }
| |_
error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
--> $DIR/empty_line_after_outer_attribute.rs:28:1
--> $DIR/empty_line_after_outer_attribute.rs:31:1
|
LL | / #[crate_type = "lib"]
LL | |
@ -27,7 +27,7 @@ LL | | fn with_two_newlines() { assert!(true) }
| |_
error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
--> $DIR/empty_line_after_outer_attribute.rs:35:1
--> $DIR/empty_line_after_outer_attribute.rs:38:1
|
LL | / #[crate_type = "lib"]
LL | |
@ -35,7 +35,7 @@ LL | | enum Baz {
| |_
error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
--> $DIR/empty_line_after_outer_attribute.rs:43:1
--> $DIR/empty_line_after_outer_attribute.rs:46:1
|
LL | / #[crate_type = "lib"]
LL | |
@ -43,7 +43,7 @@ LL | | struct Foo {
| |_
error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
--> $DIR/empty_line_after_outer_attribute.rs:51:1
--> $DIR/empty_line_after_outer_attribute.rs:54:1
|
LL | / #[crate_type = "lib"]
LL | |