Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add semicolon-outside/inside-block lints #9826

Merged
merged 8 commits into from Dec 9, 2022
Merged

Conversation

Veykril
Copy link
Member

@Veykril Veykril commented Nov 10, 2022

changelog: Add semicolon_outside_block and semicolon_inside_block lints

Fixes #7322

An earlier attempt at this can be found here #7564. This PR still implements two separate lints but I am open to merging them into a single one that's configurable.

@rust-highfive
Copy link

r? @Alexendoo

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Nov 10, 2022
@Veykril Veykril force-pushed the semi-blocks branch 2 times, most recently from f1a5d8e to d0a8c69 Compare November 10, 2022 12:34
Copy link
Member

@Alexendoo Alexendoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👋

clippy_lints/src/semicolon_block.rs Outdated Show resolved Hide resolved
clippy_lints/src/semicolon_block.rs Outdated Show resolved Hide resolved
clippy_lints/src/semicolon_block.rs Outdated Show resolved Hide resolved
clippy_lints/src/semicolon_block.rs Outdated Show resolved Hide resolved
clippy_lints/src/semicolon_block.rs Outdated Show resolved Hide resolved
@bors
Copy link
Collaborator

bors commented Nov 22, 2022

☔ The latest upstream changes (presumably #9924) made this pull request unmergeable. Please resolve the merge conflicts.

@Veykril
Copy link
Member Author

Veykril commented Nov 24, 2022

Needed to rebase, changes are in 16b016e

declare_clippy_lint! {
/// ### What it does
///
/// For () returning expressions, check that the semicolon is inside the block.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I think this is the last thing:

I believe this lint would apply to expressions returning any type rather than just ()

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I forgot to change that good catch. Unsure what wording to take here though, let me know if this works.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's tricky, maybe something like "Suggests moving the semicolon from a block's final expression outside of the block" and the opposite, to me the current reading suggests it wouldn't work on things like { a; b; }

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can rebase on master also to fix the remark CI issue

declare_clippy_lint! {
/// ### What it does
///
/// Suggests moving the semicolon from a block inside of the block to its kast expression.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Suggests moving the semicolon from a block inside of the block to its kast expression.
/// Suggests moving the semicolon after a block to the inside of the block, after its last expression.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I was a bit hasty on that commit I think, fixed it

@oxalica
Copy link
Contributor

oxalica commented Dec 4, 2022

If I read correctly, this lint doesn't trigger if both semicolons are used, yes?
unsafe { foo(); }; from #3305

@Veykril
Copy link
Member Author

Veykril commented Dec 5, 2022

It does not trigger in that case no (I added it as to the tests though, thanks for bringing that up)

@Alexendoo
Copy link
Member

Great, thanks @Veykril

@bors r+

@bors
Copy link
Collaborator

bors commented Dec 7, 2022

📌 Commit f62eab4 has been approved by Alexendoo

It is now in the queue for this repository.

@flip1995
Copy link
Member

flip1995 commented Dec 9, 2022

@bors r=Alexendoo

@bors
Copy link
Collaborator

bors commented Dec 9, 2022

📌 Commit 20ec2ce has been approved by Alexendoo

It is now in the queue for this repository.

@bors
Copy link
Collaborator

bors commented Dec 9, 2022

⌛ Testing commit 20ec2ce with merge d4cd91c...

@bors
Copy link
Collaborator

bors commented Dec 9, 2022

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: Alexendoo
Pushing d4cd91c to master...

@bors bors merged commit d4cd91c into rust-lang:master Dec 9, 2022
@oxalica
Copy link
Contributor

oxalica commented Dec 9, 2022

@Veykril

It does not trigger in that case no (I added it as to the tests though, thanks for bringing that up)

I think the double semicolon case perfectly fits the lint name semicolon_outside_block, and it's surprising that it fires only when there's no semi inside.

Also I'd expect the following cases to be warn-by-default.

unsafe { foo(); }; // Double semicolon.
match foo() { _ => foo() }; // The arm returns `()`.
match foo() { _ => foo(), _ => { foo() } }; // All arms return `()`.
for _ in [()] { unit_fn_block()/*semi or no semi*/ }; // Always `()`.
if foo() { unit_fn_block()/*semi or no semi*/ }; // Always `()`.
loop { }; // `!`

If we want to warn these cases, while still make it configurable for unsafe { f() }; v.s. unsafe { f(); }. Should we create a separated lint for the these warning cases? I cannot come up with another name besides semicolon_outside_block.

@oxalica
Copy link
Contributor

oxalica commented Dec 10, 2022

🤔 If the current semicolon-outside/inside-block behaviors rely purely on the syntax, and unsafe { foo() }; is semantically always the same as unsafe { foo(); }, could we move these into rustfmt instead?

@Jarcho
Copy link
Contributor

Jarcho commented Dec 11, 2022

Changing { foo() }; to { foo(); } is only sementically equivalent when there aren't any bindings inside the block. rustfmt also has the restriction of working with an untyped ast, so it's very limited on what transformations it could do with semicolon placement.

@oxalica
Copy link
Contributor

oxalica commented Dec 14, 2022

Changing { foo() }; to { foo(); } is only sementically equivalent when there aren't any bindings inside the block.

Oh, I forget the drop order stuff. ;-outside-the-block will delay the drop of the last Expr. So yeah it's more complicated than rustfmt typically does.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Normalize semicolon inside/outside blocks for () returning expressions
7 participants