Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upWarn on empty lines after outer attributes #2340
Conversation
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
phansch
Jan 9, 2018
Collaborator
Looks like by reusing the is_relevant_item method, it only works for functions currently. I will have another look once I'm back from vacation on the 18th. I plan to spend more time on rust-clippy, it has been really nice so far
|
Looks like by reusing the |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
oli-obk
Jan 12, 2018
Collaborator
error: Found an empty line after an outer attribute. Perhaps you forgot to add a '!' to make it an inner attribute?
--> tests/cc_seme.rs:1:1
|
1 | / #![feature(plugin)]
2 | | #![plugin(clippy)]
3 | |
4 | | #[allow(dead_code)]
... |
14 | |
15 | | fn main() {
| |_
|
= note: `-D empty-line-after-outer-attr` implied by `-D clippy`
= help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.179/index.html#empty_line_after_outer_attr
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
clarcharr
Jan 14, 2018
Contributor
There should also be a test case for items with a comment between the attribute and item.
|
There should also be a test case for items with a comment between the attribute and item. |
phansch
changed the title from
Warn on empty lines after outer attributes
to
WIP: Warn on empty lines after outer attributes
Jan 18, 2018
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
phansch
Jan 23, 2018
Collaborator
The lint now works for all members of syntax::ast::Item_, I added test cases for enum, struct and mod. Should I add test cases for all the other Item_ kinds as well or would that be too much?
|
The lint now works for all members of syntax::ast::Item_, I added test cases for |
phansch
changed the title from
WIP: Warn on empty lines after outer attributes
to
Warn on empty lines after outer attributes
Jan 23, 2018
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
phansch
Jan 23, 2018
Collaborator
I'm not really sure why cc_seme.rs produces the warning, I tried to reproduce it in a UI test, but there it seems to work. It also only seems to happen during compilation: when I run cargo test a second time, the warning is gone. Do you have some ideas how I could debug it? @oli-obk
edit: ok, nevermind I found out how to reproduce it locally:
cargo build --features debugging
cp target/debug/cargo-clippy ~/rust/cargo/bin/cargo-clippy
cp target/debug/clippy-driver ~/rust/cargo/bin/clippy-driver
~/rust/cargo/bin/cargo-clippy clippy --all -- -D clippy|
I'm not really sure why edit: ok, nevermind I found out how to reproduce it locally: cargo build --features debugging
cp target/debug/cargo-clippy ~/rust/cargo/bin/cargo-clippy
cp target/debug/clippy-driver ~/rust/cargo/bin/clippy-driver
~/rust/cargo/bin/cargo-clippy clippy --all -- -D clippy |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
oli-obk
Jan 24, 2018
Collaborator
Should I add test cases for all the other Item_ kinds as well or would that be too much?
Nah, the current tests are sufficient
Do you have some ideas how I could debug it?
That is very weird. Something must be converting the inner attribute into an outer attribute. You can try dumping the crate AST and look at that
Nah, the current tests are sufficient
That is very weird. Something must be converting the inner attribute into an outer attribute. You can try dumping the crate AST and look at that |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
phansch
Jan 24, 2018
Collaborator
Ok this seems like a weird problem.
I managed to dump the AST of cc_seme, but both attributes are inner attributes as expected.
Next I included the meta_item_list of the attribute in the error message and this is what I got:
warning: Found an empty line after an outer attribute. Perhaps you forgot to add a '!' to make it an inner attribute?
Some([Spanned { node: MetaItem(MetaItem { name: dead_code, node: Word, span: tests/cc_seme.rs:1:1: 1:1 }), span: tests/cc_seme.rs:1:1: 1:1 }])
The attribute seems to be an allow(dead_code) with a span from 1 to 1. I managed to rule out feature(plugin) as a cause because it works if there is only feature(plugin) and plugin(clippy) in the file.
I did some more shots in the dark and now I'm sure that this is caused by the main method, in combination with feature(plugin) and plugin(clippy). For example this test will cause the warning to appear:
// ./test/weird_spans.rs
#![feature(plugin)]
#![plugin(clippy)]
fn main() {
assert!(true);
}So, somewhere an allow(dead_code) or deny(dead_code) with a span of 1:1 is inserted that does not seem to show up in the AST. That causes the warning. And this only happens if there is a main method. Naming the main method something else will not cause the warning.
I will try to dig deeper in the next days, but it looks like it will take some more time to get this merged ![]()
|
Ok this seems like a weird problem. I managed to dump the AST of
The attribute seems to be an I did some more shots in the dark and now I'm sure that this is caused by the // ./test/weird_spans.rs
#![feature(plugin)]
#![plugin(clippy)]
fn main() {
assert!(true);
}So, somewhere an I will try to dig deeper in the next days, but it looks like it will take some more time to get this merged |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
oli-obk
Jan 24, 2018
Collaborator
Oh... just throw in a macro check for now. The attribute should probably have some expansion info.
|
Oh... just throw in a macro check for now. The attribute should probably have some expansion info. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
phansch
Jan 26, 2018
Collaborator
Unfortunately, I was unable to find any macro expansion info in the spans I'm using. The is_macro check didn't catch that attribute, either. So I added a check for spans that have both locations at 0. I'm not sure that's the best way to do it, but it seems to fix the warning.
|
Unfortunately, I was unable to find any macro expansion info in the spans I'm using. The |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
oli-obk
Jan 26, 2018
Collaborator
What will happen if somebody makes a file like
#[allow(foo)]
fn main() {}|
What will happen if somebody makes a file like #[allow(foo)]
fn main() {} |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
phansch
Jan 26, 2018
Collaborator
duh, you are right, that would not be detected then
I added a debugging commit, because I'm running out of time for today and want to pick it up again on Sunday.
Travis should show all kinds of information about the attribute. One thing that stands out to me is attr.span.end_point(): tests/weird_hidden_attribute.rs:1:1: 9:4287916127, but I'm not sure how to use that information, yet. I will try to figure out what happens during compilation.
I also added a separate test file at tests/weird_hidden_attribute.rs and it can be executed separately with CARGO_INCREMENTAL=1 TESTNAME=weird_hidden_attribute cargo test
|
duh, you are right, that would not be detected then I added a debugging commit, because I'm running out of time for today and want to pick it up again on Sunday. I also added a separate test file at |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
phansch
Jan 27, 2018
Collaborator
Looking at the output and the Attribute docs again, it says:
attr.span.end_point() tests/weird_hidden_attribute.rs:1:1: 9:4287916577
attr.span.next_point() tests/weird_hidden_attribute.rs:1:2: 1:2
So, maybe it makes sense to check if the attribute span end_point is after the next_point, which should not happen with normal attributes, I guess?
|
Looking at the output and the Attribute docs again, it says:
So, maybe it makes sense to check if the attribute span |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
phansch
Jan 28, 2018
Collaborator
I will update this comment for the next few hours.
Starting with this piece of code:
#![feature(plugin)]
#![plugin(clippy)]
fn main() {
"hmm"
}I managed to get the expanded macro with rustc -Z unstable-options --pretty=expanded and this contains an #[allow(dead_code)] above the main function
#![feature(prelude_import)]
#![no_std]
#![feature(plugin)]
#![plugin(clippy)]
#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate std as std;
#[allow(dead_code)]
fn main() { "hmm" }
<snip>So, when iterating over the items, it picks up the allow for the main function, because it gets included for main somewhere. I added a allow(dead_code) into the original code and the expanded output now contains two allow(dead_code) for the main function.
#![feature(prelude_import)]
#![no_std]
#![feature(plugin)]
#![plugin(clippy)]
#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate std as std;
#[allow(dead_code)]
#[allow(dead_code)]
fn main() { "hmm" }
<snip>The most interesting part is, is that one of the allow(dead_code) attributes has a span of 1:1 and the other has the correct span.
I think with snippet_opt I should be able to work around this, as the span of attributes that have been inserted by expansion always seems to be 1:1.
Additionally, I can use snippet_opt with the 1:1 span and check what it contains.
|
Starting with this piece of code: #![feature(plugin)]
#![plugin(clippy)]
fn main() {
"hmm"
}I managed to get the expanded macro with #![feature(prelude_import)]
#![no_std]
#![feature(plugin)]
#![plugin(clippy)]
#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate std as std;
#[allow(dead_code)]
fn main() { "hmm" }
<snip>So, when iterating over the items, it picks up the #![feature(prelude_import)]
#![no_std]
#![feature(plugin)]
#![plugin(clippy)]
#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate std as std;
#[allow(dead_code)]
#[allow(dead_code)]
fn main() { "hmm" }
<snip>The most interesting part is, is that one of the |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
oli-obk
Jan 29, 2018
Collaborator
Additionally, I can use snippet_opt with the 1:1 span and check what it contains.
sgtm
sgtm |
phansch
added some commits
Jan 8, 2018
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
phansch
Jan 29, 2018
Collaborator
I added an is_empty check for the attribute spans tests/cc_seme.rs will show a warning.
|
I added an |
oli-obk
merged commit 39d1d60
into
rust-lang-nursery:master
Jan 30, 2018
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
Great! Thanks |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
Thank you! |
phansch
deleted the
phansch:newline_after_attributes
branch
Jan 30, 2018
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
TheIronBorn
Jan 31, 2018
Seeing what looks like a false positive on this:
/// A mapping from coordinates in the source sequence to coordinates in the sequence after
/// the delta is applied.
// TODO: this doesn't need the new strings, so it should either be based on a new structure
// like Delta but missing the strings, or perhaps the two subsets it's synthesized from.
pub struct Transformer<'a, N: NodeInfo + 'a> {
// warning: src/delta.rs:447: Found an empty line after an outer attribute. Perhaps you forgot to add a '!' to make // it an inner attribute?
// note: src/delta.rs:447: #[warn(empty_line_after_outer_attr)] on by default
// help: src/delta.rs:447: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.184/index.html#empty_line_after_outer_attr
// warning: src/delta.rs:448: Found an empty line after an outer attribute. Perhaps you forgot to add a '!' to make it an inner attribute?
// help: src/delta.rs:448: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.184/index.html#empty_line_after_outer_attr
TheIronBorn
commented
Jan 31, 2018
|
Seeing what looks like a false positive on this: /// A mapping from coordinates in the source sequence to coordinates in the sequence after
/// the delta is applied.
// TODO: this doesn't need the new strings, so it should either be based on a new structure
// like Delta but missing the strings, or perhaps the two subsets it's synthesized from.
pub struct Transformer<'a, N: NodeInfo + 'a> {
// warning: src/delta.rs:447: Found an empty line after an outer attribute. Perhaps you forgot to add a '!' to make // it an inner attribute?
// note: src/delta.rs:447: #[warn(empty_line_after_outer_attr)] on by default
// help: src/delta.rs:447: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.184/index.html#empty_line_after_outer_attr
// warning: src/delta.rs:448: Found an empty line after an outer attribute. Perhaps you forgot to add a '!' to make it an inner attribute?
// help: src/delta.rs:448: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.184/index.html#empty_line_after_outer_attr |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
This should special case doc comments. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
I will have a look |
phansch
referenced this pull request
Feb 1, 2018
Merged
Fix false positive in empty_line_after_outer_attr #2419
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ozkriff
Feb 1, 2018
btw, example on https://rust-lang-nursery.github.io/rust-clippy/v0.0.184/index.html#empty_line_after_outer_attr is broken - there're no empty lines:
ozkriff
commented
Feb 1, 2018
|
btw, example on https://rust-lang-nursery.github.io/rust-clippy/v0.0.184/index.html#empty_line_after_outer_attr is broken - there're no empty lines: |

phansch commentedJan 8, 2018
•
edited
Edited 1 time
-
phansch
edited Jan 8, 2018 (most recent)
This adds a new lint to warn on empty lines after outer attributes.
Still fairly new to Rust, so I'm not sure if the empty line detection could be shortened or if the tests cover all edge cases, but it seems to work so far👍 .
Note that rustc already handles attributes with a missing item: libsyntax/parse/parser.rb#L3938
Closes #1165