Skip to content

Commit

Permalink
Auto merge of rust-lang#8892 - smoelius:fix-empty-line-false-positive…
Browse files Browse the repository at this point in the history
…, 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.
  • Loading branch information
bors committed May 27, 2022
2 parents 461a661 + 9ee211a commit 1dd5547
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 13 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
23 changes: 18 additions & 5 deletions clippy_lints/src/attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand Down
8 changes: 6 additions & 2 deletions tests/compile-test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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;
Expand Down Expand Up @@ -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()
Expand Down
10 changes: 10 additions & 0 deletions tests/ui/empty_line_after_outer_attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
#![feature(custom_inner_attributes)]
#![rustfmt::skip]

#[macro_use]
extern crate clap;

#[macro_use]
extern crate proc_macro_attr;

Expand Down Expand Up @@ -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() {}
12 changes: 6 additions & 6 deletions tests/ui/empty_line_after_outer_attribute.stderr
Original file line number Diff line number Diff line change
@@ -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 | |
Expand All @@ -10,15 +10,15 @@ 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 | |
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 | |
Expand All @@ -27,23 +27,23 @@ 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 | |
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 | |
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 | |
Expand Down

0 comments on commit 1dd5547

Please sign in to comment.