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 small underscore scope lint #3953

Conversation

JamesHinshelwood
Copy link
Contributor

This lint checks for bindings that look like:
let (_, _) = foo; or let Bar(_) = foo; and suggests making the scope of the _ bigger.

@flip1995 flip1995 added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Apr 13, 2019
impl EarlyLintPass for Pass {
fn check_stmt(&mut self, cx: &EarlyContext<'_>, stmt: &Stmt) {
if_chain! {
if let StmtKind::Local(ref local) = stmt.node;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this should apply to all patterns (e.g. in matches, too). You should be able to implement the check_pat method instead of the check_stmt method

let sugg = if let Some(ref expr) = local.init {
format!("let _ = {};", snippet(cx, expr.span, ".."))
} else {
"let _;".to_string()
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this situation can happen. You can just use local.init.expect("let (_, _) should have failed in rustc")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=99a6a44ab8bb5bd47fc80f8232c50c8d
This seems to be valid Rust syntax, though I never realised terms like let x; were valid Rust at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Though admittedly its entirely pointless to declare a variable _, as there is no way to later initialise it. Perhaps there should be a seperate lint against let _;?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Matching on all patterns with check_pat means this doesn't matter anyway

Copy link
Contributor

Choose a reason for hiding this comment

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

It only works if you specify the types. So let _; is not writable. You're right though, we should lint the situations that can actually occur as you showed in the playground

fn check_stmt(&mut self, cx: &EarlyContext<'_>, stmt: &Stmt) {
if_chain! {
if let StmtKind::Local(ref local) = stmt.node;
if let PatKind::TupleStruct(_, ref pats, _) | PatKind::Tuple(ref pats, _) = local.pat.node;
Copy link
Contributor

Choose a reason for hiding this comment

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

The same reasoning would apply to let Foo { .. }, let Foo { a: _, b: _ }, [_], [_, _] and similar.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense for the struct ones, but I'm unsure about linting the slice patterns. The pattern [_, _] has a different meaning to _, as it will only match on a slice with exactly 2 elements. Admittedly this is a really ugly way of checking the length of a slice, but we wouldn't be able to do a MachineApplicable suggestion, since it might change semantics.

span_lint_and_sugg(
cx,
SMALL_UNDERSCORE_SCOPE,
local.span,
Copy link
Contributor

Choose a reason for hiding this comment

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

Only lint local.pat.span (or pat.span if you move to check_pat), that way the suggestion simply becomes _ unconditionally

@bors
Copy link
Contributor

bors commented Apr 18, 2019

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

@JamesHinshelwood
Copy link
Contributor Author

I'll switch to using the new macros now they are merged

let (_x, (_, _)) = t2;

let f = Foo { x: 3, y: 7 };
let Foo { .. } = f;
Copy link
Member

@phansch phansch Apr 21, 2019

Choose a reason for hiding this comment

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

Could you add a test for println!("foo");? It currently triggers on macro calls like here.

You'll probably need to add an in_external_macro check and return early in your lint code.

///
/// **Example:**
///
/// ```rust,ignore
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this has to be ignore, it should work as a doctest already.

@phansch phansch added S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Apr 21, 2019
@JamesHinshelwood
Copy link
Contributor Author

It will be a few days till I'm able to work on this again. Apologies for the delay

@JamesHinshelwood
Copy link
Contributor Author

Unfortunately, I think I won't have time to work on this for at least a month, due to other work. If needed, you can close the PR and I will reopen it again when I have time to work on it. Sorry.

@flip1995
Copy link
Member

No problem, thanks for the information! I will close this to keep the PR list clean. Feel free to reopen this PR when you're ready to continue working on this.

@flip1995 flip1995 closed this Apr 29, 2019
@flip1995 flip1995 added S-inactive-closed Status: Closed due to inactivity and removed S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) labels Apr 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-inactive-closed Status: Closed due to inactivity
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants