Skip to content

Commit 1dd5547

Browse files
committed
Auto merge of #8892 - smoelius:fix-empty-line-false-positive, r=Manishearth
Fix `empty_line_after_outer_attribute` false positive This PR fixes a false positive in `empty_line_after_outer_attribute`. Here is a minimal example that trigger the FP: ```rust #[derive(clap::Parser)] #[clap(after_help = "This ia a help message. You're welcome. ")] pub struct Args; ``` changelog: PF: [`empty_line_after_outer_attribute`]: No longer lints empty lines in inner string values.
2 parents 461a661 + 9ee211a commit 1dd5547

File tree

5 files changed

+41
-13
lines changed

5 files changed

+41
-13
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ filetime = "0.2"
4040
rustc-workspace-hack = "1.0"
4141

4242
# UI test dependencies
43+
clap = { version = "3.1", features = ["derive"] }
4344
clippy_utils = { path = "clippy_utils" }
4445
derive-new = "0.5"
4546
if_chain = "1.0"

clippy_lints/src/attrs.rs

+18-5
Original file line numberDiff line numberDiff line change
@@ -585,15 +585,21 @@ impl EarlyLintPass for EarlyAttributes {
585585
}
586586

587587
fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
588-
for attr in &item.attrs {
588+
let mut iter = item.attrs.iter().peekable();
589+
while let Some(attr) = iter.next() {
589590
if matches!(attr.kind, AttrKind::Normal(..))
590591
&& attr.style == AttrStyle::Outer
591592
&& is_present_in_source(cx, attr.span)
592593
{
593594
let begin_of_attr_to_item = Span::new(attr.span.lo(), item.span.lo(), item.span.ctxt(), item.span.parent());
594-
let end_of_attr_to_item = Span::new(attr.span.hi(), item.span.lo(), item.span.ctxt(), item.span.parent());
595+
let end_of_attr_to_next_attr_or_item = Span::new(
596+
attr.span.hi(),
597+
iter.peek().map_or(item.span.lo(), |next_attr| next_attr.span.lo()),
598+
item.span.ctxt(),
599+
item.span.parent(),
600+
);
595601

596-
if let Some(snippet) = snippet_opt(cx, end_of_attr_to_item) {
602+
if let Some(snippet) = snippet_opt(cx, end_of_attr_to_next_attr_or_item) {
597603
let lines = snippet.split('\n').collect::<Vec<_>>();
598604
let lines = without_block_comments(lines);
599605

@@ -623,8 +629,15 @@ fn check_deprecated_cfg_attr(cx: &EarlyContext<'_>, attr: &Attribute, msrv: Opti
623629
if feature_item.has_name(sym::rustfmt);
624630
// check for `rustfmt_skip` and `rustfmt::skip`
625631
if let Some(skip_item) = &items[1].meta_item();
626-
if skip_item.has_name(sym!(rustfmt_skip)) ||
627-
skip_item.path.segments.last().expect("empty path in attribute").ident.name == sym::skip;
632+
if skip_item.has_name(sym!(rustfmt_skip))
633+
|| skip_item
634+
.path
635+
.segments
636+
.last()
637+
.expect("empty path in attribute")
638+
.ident
639+
.name
640+
== sym::skip;
628641
// Only lint outer attributes, because custom inner attributes are unstable
629642
// Tracking issue: https://github.com/rust-lang/rust/issues/54726
630643
if attr.style == AttrStyle::Outer;

tests/compile-test.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const RUN_INTERNAL_TESTS: bool = cfg!(feature = "internal");
2222

2323
/// All crates used in UI tests are listed here
2424
static TEST_DEPENDENCIES: &[&str] = &[
25+
"clap",
2526
"clippy_utils",
2627
"derive_new",
2728
"futures",
@@ -40,6 +41,8 @@ static TEST_DEPENDENCIES: &[&str] = &[
4041
// Test dependencies may need an `extern crate` here to ensure that they show up
4142
// in the depinfo file (otherwise cargo thinks they are unused)
4243
#[allow(unused_extern_crates)]
44+
extern crate clap;
45+
#[allow(unused_extern_crates)]
4346
extern crate clippy_utils;
4447
#[allow(unused_extern_crates)]
4548
extern crate derive_new;
@@ -109,8 +112,9 @@ static EXTERN_FLAGS: SyncLazy<String> = SyncLazy::new(|| {
109112
not_found.is_empty(),
110113
"dependencies not found in depinfo: {:?}\n\
111114
help: Make sure the `-Z binary-dep-depinfo` rust flag is enabled\n\
112-
help: Try adding to dev-dependencies in Cargo.toml",
113-
not_found
115+
help: Try adding to dev-dependencies in Cargo.toml\n\
116+
help: Be sure to also add `extern crate ...;` to tests/compile-test.rs",
117+
not_found,
114118
);
115119
crates
116120
.into_iter()

tests/ui/empty_line_after_outer_attribute.rs

+10
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
#![feature(custom_inner_attributes)]
55
#![rustfmt::skip]
66

7+
#[macro_use]
8+
extern crate clap;
9+
710
#[macro_use]
811
extern crate proc_macro_attr;
912

@@ -110,4 +113,11 @@ pub trait Bazz {
110113
}
111114
}
112115

116+
#[derive(clap::Parser)]
117+
#[clap(after_help = "This ia a help message.
118+
119+
You're welcome.
120+
")]
121+
pub struct Args;
122+
113123
fn main() {}

tests/ui/empty_line_after_outer_attribute.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
2-
--> $DIR/empty_line_after_outer_attribute.rs:11:1
2+
--> $DIR/empty_line_after_outer_attribute.rs:14:1
33
|
44
LL | / #[crate_type = "lib"]
55
LL | |
@@ -10,15 +10,15 @@ LL | | fn with_one_newline_and_comment() { assert!(true) }
1010
= note: `-D clippy::empty-line-after-outer-attr` implied by `-D warnings`
1111

1212
error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
13-
--> $DIR/empty_line_after_outer_attribute.rs:23:1
13+
--> $DIR/empty_line_after_outer_attribute.rs:26:1
1414
|
1515
LL | / #[crate_type = "lib"]
1616
LL | |
1717
LL | | fn with_one_newline() { assert!(true) }
1818
| |_
1919

2020
error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
21-
--> $DIR/empty_line_after_outer_attribute.rs:28:1
21+
--> $DIR/empty_line_after_outer_attribute.rs:31:1
2222
|
2323
LL | / #[crate_type = "lib"]
2424
LL | |
@@ -27,23 +27,23 @@ LL | | fn with_two_newlines() { assert!(true) }
2727
| |_
2828

2929
error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
30-
--> $DIR/empty_line_after_outer_attribute.rs:35:1
30+
--> $DIR/empty_line_after_outer_attribute.rs:38:1
3131
|
3232
LL | / #[crate_type = "lib"]
3333
LL | |
3434
LL | | enum Baz {
3535
| |_
3636

3737
error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
38-
--> $DIR/empty_line_after_outer_attribute.rs:43:1
38+
--> $DIR/empty_line_after_outer_attribute.rs:46:1
3939
|
4040
LL | / #[crate_type = "lib"]
4141
LL | |
4242
LL | | struct Foo {
4343
| |_
4444

4545
error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
46-
--> $DIR/empty_line_after_outer_attribute.rs:51:1
46+
--> $DIR/empty_line_after_outer_attribute.rs:54:1
4747
|
4848
LL | / #[crate_type = "lib"]
4949
LL | |

0 commit comments

Comments
 (0)