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

E0716: clarify that equivalent code example is erroneous #86477

Merged
merged 1 commit into from
Jul 5, 2021

Conversation

tlyu
Copy link
Contributor

@tlyu tlyu commented Jun 19, 2021

In E0716, there is a code block that is equivalent to the erroneous
code example. Especially when viewed with rustc --explain, it's
not obvious that it is also erroneous, and some users have been
confused when they try to change their code to match the erroneous
equivalent.

@rustbot label +A-diagnostics +D-newcomer-roadblock +T-compiler

@rustbot rustbot added A-diagnostics Area: Messages for errors, warnings, and lints D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 19, 2021
@rust-highfive
Copy link
Collaborator

r? @matthewjasper

(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 Jun 19, 2021
Comment on lines 16 to 19
can be borrowed. You could imagine that `let p = bar(&foo());` is equivalent to
this:

(equivalent erroneous code)
Copy link
Member

Choose a reason for hiding this comment

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

This (equivalent to.. vs. equivalent erroneous code) sounds slightly redundant, maybe we could improve the above wording instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks! I think there needs to be a very clear indication that the example is erroneous, preferably on a line by itself. I know it seems redundant, but somehow the erroneous nature of the example to be clearly communicated when the explanation is displayed in plain text in a terminal. I think it's very easy for someone quickly scanning the --explain output in a terminal to assume that the second code block is an example of how to fix their code. (I think I've heard one or two examples in Discord of someone copy and pasting such an example, maybe even this one, and being upset when it didn't work.)

Right now the rustc --explain E0716 begins with

A temporary value is being dropped while a borrow is still in active use.

Erroneous code example:

```
fn foo() -> i32 { 22 }
fn bar(x: &i32) -> &i32 { x }
let p = bar(&foo());
         // ------ creates a temporary
let q = *p;
```

Here, the expression `&foo()` is borrowing the expression `foo()`. As `foo()` is
a call to a function, and not the name of a variable, this creates a
**temporary** -- that temporary stores the return value from `foo()` so that it
can be borrowed. You could imagine that `let p = bar(&foo());` is equivalent to
this:

```
let p = {
  let tmp = foo(); // the temporary
  bar(&tmp)
}; // <-- tmp is freed as we exit this block
let q = p;
```

Note there is nothing obviously highlighting the second code block as erroneous, not even the minimal highlighting that compile_fail examples get in the error index web page. Even the compile_fail annotation that's in the .md file gets stripped from the code fence. I guess we could repeat the wording before the first code block and say

Erroneous code example:

on a line by itself? Maybe also change the comment to something like this?

}; // <-- ERROR: tmp is freed as we exit this block

Copy link
Member

@JohnTitor JohnTitor Jun 21, 2021

Choose a reason for hiding this comment

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

Hm, I think "You could imagine that let p = bar(&foo()); is equivalent to this:" should mean it's also erroneous. If it's unclear, it's better to reword that instead of just saying it's equivalent again otherwise it'll be repeating the same wording with the same meaning. I'd reword something like "You could imagine that let p = bar(&foo()); is equivalent to this which also fails".
And note that "tmp is freed as we exit this block" is not the error itself, it explains why the error happened.

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 do you feel about putting another

Erroneous code example:

line in front of the second erroneous code block? I think making it any more verbose, or trying to have the explanatory paragraph serve the purpose of highlighting the erroneous nature, will make the code block more likely to be misinterpreted as a fix.

Also, the existing error output (from the playground) is very close to what the existing comment in the example says.

error[E0597]: `tmp` does not live long enough
 --> src/main.rs:7:7
  |
5 | let p = {
  |     - borrow later stored here
6 |   let tmp = foo(); // the temporary
7 |   bar(&tmp)
  |       ^^^^ borrowed value does not live long enough
8 | }; // <-- tmp is freed as we exit this block
  | - `tmp` dropped here while still borrowed

RFC 1567 says to put a comment on the erroneous line, which I guess is line 7 here? Either way, it seems to recommend explicitly putting // error: in a comment.

Copy link
Member

Choose a reason for hiding this comment

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

How do you feel about putting another [..] line in front of the second erroneous code block? I think making it any more verbose, or trying to have the explanatory paragraph serve the purpose of highlighting the erroneous nature, will make the code block more likely to be misinterpreted as a fix.

I'm not sure what you mean, how my suggestion causes misunderstanding? It's just saying the following also fails. And note that even though you add any wording before the snippet, you should reword "You could imagine.." part to avoid being verbose.

Also, the existing error output (from the playground) is very close to what the existing comment in the example says.

You can see the error happens on line 7, which means using a temporary value was used and line 8 just dropped tmp so "ERROR: tmp is freed as we exit this block" is totally incorrect. I'm not saying that adding ERROR: is bad but line 8 isn't the error itself.

@tlyu
Copy link
Contributor Author

tlyu commented Jun 22, 2021

I'm not sure what you mean, how my suggestion causes misunderstanding? It's just saying the following also fails. And note that even though you add any wording before the snippet, you should reword "You could imagine.." part to avoid being verbose.

I'm saying that I think we still need some brief text on a line by itself in front of the erroneous code example that clearly says that it's erroneous, otherwise users will misinterpret it as an example of how to fix the code. I think this is regardless of what wording changes we make in the "You could imagine" paragraph. I think that paragraph is long enough that users might skip over it without reading it, especially if they see something that looks like an example of a fix.

Anyway, I pushed an update; please let me know what you think?

@JohnTitor
Copy link
Member

I'm not sure if the current is the best but it seems fine, could you squash commits into one?

@JohnTitor JohnTitor 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 Jul 4, 2021
In E0716, there is a code block that is equivalent to the erroneous
code example. Especially when viewed with `rustc --explain`, it's
not obvious that it is also erroneous, and some users have been
confused when they try to change their code to match the erroneous
equivalent.
@tlyu
Copy link
Contributor Author

tlyu commented Jul 4, 2021

I'm not sure if the current is the best but it seems fine, could you squash commits into one?

Done. Thanks!

@rustbot label -S-waiting-on-author +S-waiting-on-review

@rustbot rustbot 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 Jul 4, 2021
@JohnTitor
Copy link
Member

Thanks!
r? @JohnTitor @bors r+ rollup

@bors
Copy link
Contributor

bors commented Jul 4, 2021

📌 Commit 92197a5 has been approved by JohnTitor

@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 Jul 4, 2021
bors added a commit to rust-lang-ci/rust that referenced this pull request Jul 4, 2021
Rollup of 8 pull requests

Successful merges:

 - rust-lang#86477 (E0716: clarify that equivalent code example is erroneous)
 - rust-lang#86623 (Add check to ensure error code explanations are not removed anymore even if not emitted)
 - rust-lang#86856 (Make x.py less verbose on failures)
 - rust-lang#86858 (Stabilize `string_drain_as_str`)
 - rust-lang#86859 (Add a regression test for issue-69323)
 - rust-lang#86862 (re-export SwitchIntEdgeEffects)
 - rust-lang#86864 (Add missing code example for Write::write_vectored)
 - rust-lang#86874 (Bump deps)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 5d555bf into rust-lang:master Jul 5, 2021
@rustbot rustbot added this to the 1.55.0 milestone Jul 5, 2021
@tlyu tlyu deleted the e0716-clarification branch July 13, 2021 04:33
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 D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants