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

Missing help message when forgetting to use the let keyword #132483

Closed
shubham-93 opened this issue Nov 2, 2024 · 2 comments · Fixed by #132498
Closed

Missing help message when forgetting to use the let keyword #132483

shubham-93 opened this issue Nov 2, 2024 · 2 comments · Fixed by #132498
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@shubham-93
Copy link

shubham-93 commented Nov 2, 2024

Code

fn main() {
    let n = 1;
    n1 = 2;
}

Current output

error[E0425]: cannot find value `n1` in this scope
 --> src/main.rs:3:5
  |
3 |     n1 = 2;
  |     ^^ help: a local variable with a similar name exists: `n`

For more information about this error, try `rustc --explain E0425`.

Desired output

error[E0425]: cannot find value `n1` in this scope
 --> src/main.rs:3:5
  |
3 |     n1 = 2;
  |     ^^ help: a local variable with a similar name exists: `n`
  |
help: you might have meant to introduce a new binding
  |
3 |     let n1 = 2;
  |     +++

For more information about this error, try `rustc --explain E0425`.

Rationale and extra context

Coming from a Python background, I sometimes forget to use the let keyword in Rust when binding a value to a new variable. In such cases, it would be useful to get a help message from the compiler that asks the programmer to do so (help: you might have meant to introduce a new binding). I noticed that sometimes the compiler does give such a message, but sometimes not. Suppose I want to define two variables and I forget to use the let statement for the second variable. After some experimentation, it seems like the desired help message appears after a pattern common to both variable names is matched and the non-matched part has a length that crosses a certain threshold. I will give some examples below. Assume that the first variable's name is never changed, and we tweak the second variable's name slightly to see when the message help: you might have meant to introduce a new binding is triggered. Note that the other help message help: a local variable with a similar name exists is always triggered, which is not always helpful/relevant, and is therefore one of the reasons why I raised this issue.

  1. The matched pattern is 'n' and the differing characters between the two variable names are '11', and I do get the desired help message from the compiler. The difference here is in 2 characters, but this is not always the minimum number required to trigger the help message as shown in example 3. below.
let n = 1;
n11 = 2;
  1. The desired help message in the following case is triggered when the number of differing characters is at least 2 (e.g. abc = 2 does not trigger the message).
let ab = 1;
abcd = 2;
  1. The desired help message in the following case is triggered when the number of differing characters is at least 4 (e.g. abcdefghi = 2 does not trigger the message).
let abcdef = 1;
abcdefghij = 2;
  1. Now let's flip the first 2 characters of the 2 variables. So suppose I have the following:
let abcdef = 1;
ba = 2;

where the first 2 characters of the 2 variables are flipped (ab versus ba). Then, I will start adding one new (and different) character (in alphabetical order) at a time to the second variable's name and compile to see when the help message appears. We see the message in the following cases: ba, bac, bacd, bacde. Then the message disappears in the following cases: bacdef, bacdefg. And then reappears in the case bacdefgh, etc.

  1. As a last example, suppose a user is interested in doing some data analysis and names a variable data_attribute. Then they name another variable with a similar name but with an underscore '_' followed by a numerical suffix. They will not get the desired help message unless they append at least 7 digits. So this means that
let data_attribute = 1;
data_attribute_1234567 = 2;

is the first time the help message appears. The message does not appear when the second variable's name is one of the following: data_attribute_1, data_attribute_12, data_attribute_123, data_attribute_1234, data_attribute_12345, data_attribute_123456.

These are just some random cases I quickly thought of, but perhaps there are more rules to when a message is triggered. The variable names in the examples above (except the last one) are not the best, but I used them to show which events trigger the message. But from especially the last example, one would think that data_attribute is completely different from e.g. data_attribute_71 for many use cases, and so the desired help message would be quite useful.

Can we not have the message triggered every time a let statement is forgotten?

Other cases

No response

Rust Version

rustc 1.82.0 (f6e511e 2024-10-15)
binary: rustc
commit-hash: f6e511e
commit-date: 2024-10-15
host: aarch64-apple-darwin
release: 1.82.0
LLVM version: 19.1.1

Anything else?

No response

@shubham-93 shubham-93 added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 2, 2024
@shubham-93 shubham-93 changed the title Missing help message when forgetting to use the let keyword Missing help message when forgetting to use the let keyword Nov 2, 2024
@uellenberg
Copy link
Contributor

This is the relevant code:

if !self.r.add_typo_suggestion(err, suggestion, ident_span) {
fallback = !self.let_binding_suggestion(err, ident_span);
}
and
if !self.r.add_typo_suggestion(err, typo_sugg, ident_span) {

Making typo and let binding suggestions mutually exclusive seems to be an intentional decision, so I'm not sure whether it's something to be fixed. Reworking the logic yields the following error:

error[E0425]: cannot find value `n1` in this scope
 --> src/main.rs:3:5
  |
3 |     n1 = 2;
  |     ^^
  |
help: a local variable with a similar name exists
  |
3 |     n = 2;
  |     ~
help: you might have meant to introduce a new binding
  |
3 |     let n1 = 2;
  |     +++

For more information about this error, try `rustc --explain E0425`.
error: could not compile `rust-lang-test` (bin "rust-lang-test") due to 1 previous error

@uellenberg
Copy link
Contributor

@rustbot claim

uellenberg added a commit to uellenberg/rust that referenced this issue Nov 2, 2024
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Nov 5, 2024
…s, r=estebank

Suggest fixing typos and let bindings at the same time

Fixes rust-lang#132483

Currently, a suggestion for adding a let binding won't be shown if we suggest fixing a typo. This changes that behavior to always show both, if possible. Essentially, this turns the suggestion from
```rust
error[E0425]: cannot find value `x2` in this scope
 --> src/main.rs:4:5
  |
4 |     x2 = 2;
  |     ^^ help: a local variable with a similar name exists: `x1`

For more information about this error, try `rustc --explain E0425`.
```

to
```rust
error[E0425]: cannot find value `x2` in this scope
 --> src/main.rs:4:5
  |
4 |     x2 = 2;
  |     ^^
  |
help: a local variable with a similar name exists
  |
4 |     x1 = 2;
  |     ~~
help: you might have meant to introduce a new binding
  |
4 |     let x2 = 2;
  |     +++

For more information about this error, try `rustc --explain E0425`.
```

for the following code:
```rust
fn main() {
    let x1 = 1;
    x2 = 2;
}
```

The original behavior only shows the suggestion for a let binding if a typo suggestion wasn't already displayed. However, this falls apart in the cases like the one above where we have multiple similar variables. I don't think it makes sense to hide this suggestion if there's a similar variable, since that defeats the purpose of this suggestion in that case (it's meant to help those coming from languages like Python).
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Nov 5, 2024
…s, r=estebank

Suggest fixing typos and let bindings at the same time

Fixes rust-lang#132483

Currently, a suggestion for adding a let binding won't be shown if we suggest fixing a typo. This changes that behavior to always show both, if possible. Essentially, this turns the suggestion from
```rust
error[E0425]: cannot find value `x2` in this scope
 --> src/main.rs:4:5
  |
4 |     x2 = 2;
  |     ^^ help: a local variable with a similar name exists: `x1`

For more information about this error, try `rustc --explain E0425`.
```

to
```rust
error[E0425]: cannot find value `x2` in this scope
 --> src/main.rs:4:5
  |
4 |     x2 = 2;
  |     ^^
  |
help: a local variable with a similar name exists
  |
4 |     x1 = 2;
  |     ~~
help: you might have meant to introduce a new binding
  |
4 |     let x2 = 2;
  |     +++

For more information about this error, try `rustc --explain E0425`.
```

for the following code:
```rust
fn main() {
    let x1 = 1;
    x2 = 2;
}
```

The original behavior only shows the suggestion for a let binding if a typo suggestion wasn't already displayed. However, this falls apart in the cases like the one above where we have multiple similar variables. I don't think it makes sense to hide this suggestion if there's a similar variable, since that defeats the purpose of this suggestion in that case (it's meant to help those coming from languages like Python).
@bors bors closed this as completed in 67a8592 Nov 6, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Nov 6, 2024
Rollup merge of rust-lang#132498 - uellenberg:typo-and-let-suggestions, r=estebank

Suggest fixing typos and let bindings at the same time

Fixes rust-lang#132483

Currently, a suggestion for adding a let binding won't be shown if we suggest fixing a typo. This changes that behavior to always show both, if possible. Essentially, this turns the suggestion from
```rust
error[E0425]: cannot find value `x2` in this scope
 --> src/main.rs:4:5
  |
4 |     x2 = 2;
  |     ^^ help: a local variable with a similar name exists: `x1`

For more information about this error, try `rustc --explain E0425`.
```

to
```rust
error[E0425]: cannot find value `x2` in this scope
 --> src/main.rs:4:5
  |
4 |     x2 = 2;
  |     ^^
  |
help: a local variable with a similar name exists
  |
4 |     x1 = 2;
  |     ~~
help: you might have meant to introduce a new binding
  |
4 |     let x2 = 2;
  |     +++

For more information about this error, try `rustc --explain E0425`.
```

for the following code:
```rust
fn main() {
    let x1 = 1;
    x2 = 2;
}
```

The original behavior only shows the suggestion for a let binding if a typo suggestion wasn't already displayed. However, this falls apart in the cases like the one above where we have multiple similar variables. I don't think it makes sense to hide this suggestion if there's a similar variable, since that defeats the purpose of this suggestion in that case (it's meant to help those coming from languages like Python).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants