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 explanations and suggestions to irrefutable_let_patterns lint #79747

Merged
merged 1 commit into from
Feb 19, 2021

Conversation

camelid
Copy link
Member

@camelid camelid commented Dec 5, 2020

Fixes #79716.

@rust-highfive
Copy link
Collaborator

r? @varkor

(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 Dec 5, 2020
@camelid camelid added the A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. label Dec 5, 2020
@camelid
Copy link
Member Author

camelid commented Dec 5, 2020

Ugh, x.py is rebuilding LLVM for some reason 😩

@ehuss
Copy link
Contributor

ehuss commented Dec 5, 2020

My preference would be to not add one-off links like this. Ideally, every warning should (automatically) have some way to get more information. The issue is that it is not clear exactly what that should look like. Some options that were considered:

  • Add an HTTP link similar to this PR. This has several drawbacks:
    • Links are release-specific. It could always link to nightly, but that would cause problems with renamed lints.
    • Doesn't work offline.
    • Is very long and wordy, adding quite a bit of characters to the error message.
  • Add it to the --explain flag. This has several concerns:
    • It's not really clear if anyone is actually using --explain.
    • Explain has historically been only for Exxxx codes, would it be confusing if it was also for warnings?
    • Not really clear how --explain will work in relation with -Zteach in the future.

There is some history in #48041 and #48337 about trying to reduce the verbosity with --explain. I'm not sure how that would work with warnings, it would need some rewording. In some situations, there can be a lot of warnings, and I'd be concerned that it would spew out way too much text.

@camelid
Copy link
Member Author

camelid commented Dec 5, 2020

I based this off of errors like:

error: unexpected `(` after qualified path
  --> $DIR/vec-macro-in-pattern.rs:5:14
   |
LL |         Some(vec![_x]) => (),
   |              ^^^^^^^^
   |              |
   |              unexpected `(` after qualified path
   |              the qualified path
   |              in this macro invocation
   |              help: use a slice pattern here instead: `[_x]`
   |
   = help: for more information, see https://doc.rust-lang.org/edition-guide/rust-2018/slice-patterns.html
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error

but if we want to wait for a unified approach before adding more, I'm okay with that.

And I have another Con to add to using HTTP links: we currently don't check links produced in error messages, so they're prone to link rot.

@camelid
Copy link
Member Author

camelid commented Dec 5, 2020

Another example:

error: getting the inner pointer of a temporary `CString`
  --> $DIR/lint-temporary-cstring-as-param.rs:9:45
   |
LL |     some_function(CString::new("").unwrap().as_ptr());
   |                   ------------------------- ^^^^^^ this pointer will be invalid
   |                   |
   |                   this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
   |
note: the lint level is defined here
  --> $DIR/lint-temporary-cstring-as-param.rs:1:9
   |
LL | #![deny(temporary_cstring_as_ptr)]
   |         ^^^^^^^^^^^^^^^^^^^^^^^^
   = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
   = help: for more information, see https://doc.rust-lang.org/reference/destructors.html

@varkor
Copy link
Member

varkor commented Dec 8, 2020

I think we ought to link to the stable version of the documentation (or, even better, to the relevant version). But that aside, it seems like a link to the documentation is not the best fix for this issue. We should be suggesting the user change the while let into a loop. Can we do that instead?

@varkor varkor added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 14, 2020
@JohnCSimon JohnCSimon added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 11, 2021
@camelid
Copy link
Member Author

camelid commented Jan 12, 2021

Starting with a rebase.

@rust-log-analyzer

This comment has been minimized.

@camelid camelid added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 12, 2021
@camelid
Copy link
Member Author

camelid commented Jan 12, 2021

@varkor How does this look:

warning: irrefutable while-let pattern
  --> $DIR/while-let.rs:27:5
   |
LL | /     while let _a = 1 {
LL | |         println!("irrefutable pattern");
LL | |         break;
LL | |     }
   | |_____^
   |
   = note: this pattern will always match, so the loop will never exit
   = help: consider using a `loop { ... }` and adding a `let` inside it

? I added similar notes and suggestions to if-let and if-let guard as well.

Ideally they would be structured suggestions, but I think it would be tricky to recover the span information. Also, these aren't mechanical fixes which makes them more difficult to automate and not as useful to users.

@camelid
Copy link
Member Author

camelid commented Jan 12, 2021

Note that the current output uses help: for both; I'm in the middle of changing the first one to use note: instead.

@camelid camelid changed the title Add 'for more info' link to 'irrefutable *-let pattern' warning Add explanations and suggestions to irrefutable_let_patterns lint Jan 12, 2021
@rust-log-analyzer

This comment has been minimized.

@varkor
Copy link
Member

varkor commented Jan 16, 2021

Ideally they would be structured suggestions, but I think it would be tricky to recover the span information. Also, these aren't mechanical fixes which makes them more difficult to automate and not as useful to users.

Yes, that's true. This is definitely an improvement as-is.

@camelid
Copy link
Member Author

camelid commented Jan 16, 2021

(I think I need to bless tests from the error message change.)

@rust-log-analyzer

This comment has been minimized.

@varkor varkor added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 17, 2021
@camelid
Copy link
Member Author

camelid commented Jan 17, 2021

I can squash before you r+, but I figure it's easier to review as separate commits.

hir::MatchSource::IfLetDesugar { .. } => {
let mut diag = lint.build("irrefutable if-let pattern");
diag.note("this pattern will always match, so the if-let is useless");
diag.help("consider replacing the if-let with a let");
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
diag.help("consider replacing the if-let with a let");
diag.help("consider replacing the if-let with a `let`");

I wonder whether it would be more readable to write

Suggested change
diag.help("consider replacing the if-let with a let");
diag.help("consider replacing the `if let` with a `let`");

as well.

Copy link
Member Author

Choose a reason for hiding this comment

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

I intentionally removed the backticks on let to be consistent with if-let. I thought of doing the second option you suggest, but didn't because then it would be inconsistent with the error message. I'm still open to it, I just want to make sure we don't confuse people. What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

I'd be tempted to replace if-let with `if let` in general (including in the main error message). To me, it's slightly easier to read, and feels more consistent with other uses of code fragments in error messages.

Copy link
Member Author

Choose a reason for hiding this comment

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

I like the look of if-let, though I do think it's probably clearer as `if let`. However, it seems like if-let and the like are used a lot, not just in the compiler but also in documentation. So can we do that as a separate change so this one doesn't wallow too long?

Copy link
Member

Choose a reason for hiding this comment

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

That works (as long as we don't overlook that let needs to be enclosed in backticks in the message above as well).

@varkor varkor added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 7, 2021
@camelid camelid added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 17, 2021
@varkor
Copy link
Member

varkor commented Feb 17, 2021

r=me after squashing.

@camelid
Copy link
Member Author

camelid commented Feb 17, 2021

Also: blocked on #82215 (not adding S-blocked since that PR will merge very soon).

@camelid camelid added the S-blocked Status: Marked as blocked ❌ on something else such as an RFC or other implementation work. label Feb 18, 2021
@camelid
Copy link
Member Author

camelid commented Feb 18, 2021

Starting with a squash to make the rebase easier (and since I need to anyway).

@camelid camelid removed the S-blocked Status: Marked as blocked ❌ on something else such as an RFC or other implementation work. label Feb 18, 2021
@camelid
Copy link
Member Author

camelid commented Feb 18, 2021

Rebased. Ready for review!

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@varkor
Copy link
Member

varkor commented Feb 19, 2021

Thanks, looks good!

@bors r+

@bors
Copy link
Contributor

bors commented Feb 19, 2021

📌 Commit 5d2a2a1 has been approved by varkor

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 19, 2021
bors added a commit to rust-lang-ci/rust that referenced this pull request Feb 19, 2021
Rollup of 10 pull requests

Successful merges:

 - rust-lang#79747 (Add explanations and suggestions to `irrefutable_let_patterns` lint)
 - rust-lang#81496 (name async generators something more human friendly in type error diagnostic)
 - rust-lang#81873 (Add Mutex::unlock)
 - rust-lang#82093 (Add tests for Atomic*::fetch_{min,max})
 - rust-lang#82238 (ast: Keep expansion status for out-of-line module items)
 - rust-lang#82245 (Do not ICE when evaluating locals' types of invalid `yield`)
 - rust-lang#82259 (Fix popping singleton paths in when generating E0433)
 - rust-lang#82261 (rustdoc: Support argument files)
 - rust-lang#82274 (libtest: Fix unwrap panic on duplicate TestDesc)
 - rust-lang#82275 (Update cargo)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 94ab407 into rust-lang:master Feb 19, 2021
@rustbot rustbot added this to the 1.52.0 milestone Feb 19, 2021
@camelid camelid deleted the irrefut-lint-link branch February 19, 2021 20:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

more descriptive warning for irrefutable while-let pattern
9 participants