Skip to content

Conversation

ada4a
Copy link
Contributor

@ada4a ada4a commented Aug 11, 2025

This kind of supersedes #15386 -- by making the lint early-pass, we get access to TyKind::Parens that surround the type ascription. And with that, we can return to the simpler calculation of span_to_remove.

The biggest hurdle was is_from_proc_macro -- calling that function required me to impl WithSearchPat for rustc_ast::Ty, i.e. ast_ty_search_pat, which I based on ty_search_pat. Since that's a larger change, I could extract it into a PR of its own.

changelog: none

@rustbot
Copy link
Collaborator

rustbot commented Aug 11, 2025

r? @samueltardieu

rustbot has assigned @samueltardieu.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Aug 11, 2025
@ada4a ada4a force-pushed the let-unit-with-type-underscore branch from 43b866d to b506c33 Compare August 11, 2025 14:51
@samueltardieu
Copy link
Member

I won't be able to properly review this PR in the next two weeks, I'll reroll the dice.
r? clippy

@rustbot rustbot assigned Jarcho and unassigned samueltardieu Aug 11, 2025
@ada4a ada4a force-pushed the let-unit-with-type-underscore branch from b506c33 to b40274c Compare August 12, 2025 14:09
span_lint_and_then(
cx,
LET_WITH_TYPE_UNDERSCORE,
local.span,
"variable declared with type underscore",
|diag| {
diag.span_suggestion_verbose(
span_to_remove,
ty.span.with_lo(local.pat.span.hi()),
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't work the local and type are in different contexts. The old one is the correct way to do this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a bit unfortunate, because removing span_to_remove was kind of the whole purpose of this PR.. I'm the one who added it in #15386

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This doesn't work [if] the local and type are in different contexts

Actually, we don't even lint if that's the case:

&& local.span.eq_ctxt(ty.span)

So I think this is fine after all?

Or do you think we can instead remove that check now? I tried doing that, then I needed to modfify span_to_remove to be ty.span.with_lo(local.pat.span.source_callsite().hi()), but then all of the following test cases passed at least:

macro_rules! foo {
    () => {
        (a)
    };
};
macro_rules! bar {
    () => {
        _
    };
};

let (a): bar!() = 0;
//~^ let_with_type_underscore
let foo!(): _ = 0;
//~^ let_with_type_underscore
let foo!(): bar!() = 0;
//~^ let_with_type_underscore

gives:

error: variable declared with type underscore
  --> tests/ui/let_with_type_underscore.rs:71:5
   |
LL |     let (a): bar!() = 0;
   |     ^^^^^^^^^^^^^^^^^^^^
   |
help: remove the explicit type `_` declaration
   |
LL -     let (a): bar!() = 0;
LL +     let (a) = 0;
   |

error: variable declared with type underscore
  --> tests/ui/let_with_type_underscore.rs:73:5
   |
LL |     let foo!(): _ = 0;
   |     ^^^^^^^^^^^^^^^^^^
   |
help: remove the explicit type `_` declaration
   |
LL -     let foo!(): _ = 0;
LL +     let foo!() = 0;
   |

error: variable declared with type underscore
  --> tests/ui/let_with_type_underscore.rs:75:5
   |
LL |     let foo!(): bar!() = 0;
   |     ^^^^^^^^^^^^^^^^^^^^^^^
   |
help: remove the explicit type `_` declaration
   |
LL -     let foo!(): bar!() = 0;
LL +     let foo!() = 0;
   |

But:

  • the error message mentions _ instead of bar!()
  • this could be seen as a feature addition

So I'd say leaving the eq_ctxt in and simplifying span_to_remove is good enough?

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, I meant the pattern and type. e.g. let $name: _

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Then maybe that's what the check should've been?

Some(GenericArgs::AngleBracketed(_)) => Pat::Str(">"),
Some(GenericArgs::Parenthesized(par_args)) => match &par_args.output {
// last `)` in `(A, B)`
FnRetTy::Default(_) => Pat::Str(")"),
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be the last argument, or "(" if there are none. Closing parenthesis are stripped from the end before matching.

FnRetTy::Ty(ty) => ast_ty_search_pat(ty).1,
},
// last `)` in `(..)`
Some(GenericArgs::ParenthesizedElided(_)) => Pat::Str(")"),
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be "..".

Comment on lines +480 to +493
#[allow(
clippy::collapsible_else_if,
reason = "we want to keep these cases together, since they are both impossible"
)]
Copy link
Contributor

Choose a reason for hiding this comment

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

This allow shouldn't be needed anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

how so?..

Copy link
Contributor

@Jarcho Jarcho Aug 15, 2025

Choose a reason for hiding this comment

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

I thought there was a PR that blocked the lint if there was a comment.

edit: I thought you had copied that from somewhere else in the file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm, I rebased onto latest master, and it still lints.. but now that I've already done the rebase, I guess I might just leave it in

(Pat::Str(""), Pat::Str(""))
}
},
TyKind::MacCall(_) => (Pat::Str(""), Pat::MultiStr(&[")", "]", "}"])), // closing parens of the invocation
Copy link
Contributor

Choose a reason for hiding this comment

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

This should match the path at the start and nothing at the end. The closing parenthesis can't be reliably detected.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I knew that parentheses get trimmed, but I thought that'd be the case only for paired ones? Turning foo!(bar, baz) into foo!(bar, baz feels.. wrong. But sure

Copy link
Contributor

Choose a reason for hiding this comment

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

They're trimmed because the HIR tree doesn't have a separate node for parenthesis making ty and (ty) appear the same. The AST does have them as a node, but since the machinery is currently shared...

I'm working on getting rid of the need for is_from_proc_macro.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh, best of luck to you then!

@rustbot rustbot 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 Aug 15, 2025
@ada4a ada4a force-pushed the let-unit-with-type-underscore branch from b40274c to c90e863 Compare August 15, 2025 19:51
@ada4a
Copy link
Contributor Author

ada4a commented Aug 15, 2025

this should address all points except #15458 (comment)

@ada4a ada4a force-pushed the let-unit-with-type-underscore branch 2 times, most recently from 2d8b1dd to 2d3dcf5 Compare August 15, 2025 20:46
@ada4a ada4a force-pushed the let-unit-with-type-underscore branch from 2d3dcf5 to 2459ad6 Compare August 22, 2025 13:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants