Skip to content

Suggest a borrow when using dbg!() #120327

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
gak opened this issue Jan 25, 2024 · 7 comments · Fixed by #120990
Closed

Suggest a borrow when using dbg!() #120327

gak opened this issue Jan 25, 2024 · 7 comments · Fixed by #120990
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@gak
Copy link

gak commented Jan 25, 2024

Code

fn s() -> String {
    let a = String::new();
    dbg!(a);
    return a;
}

Current output

Compiling playground v0.0.1 (/playground)
error[E0382]: use of moved value: `a`
 --> src/lib.rs:4:12
  |
2 |     let a = String::new();
  |         - move occurs because `a` has type `String`, which does not implement the `Copy` trait
3 |     dbg!(a);
  |     ------- value moved here
4 |     return a;
  |            ^ value used here after move
  |
help: borrow this binding in the pattern to avoid moving the value
 --> /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/macros.rs:364:13
  |
36|             ref tmp => {
  |             +++

For more information about this error, try `rustc --explain E0382`.
error: could not compile `playground` (lib) due to 1 previous error

Desired output

help: consider borrowing instead of transferring ownership.

dbg!(&a);

Rationale and extra context

No response

Other cases

No response

Rust Version

Example was in the playground: "Build using the Nightly version: 1.77.0-nightly (2024-01-23 5d3d3479d774754856db)"

My machine has the same message:

rustc 1.76.0-nightly (a96d57bdb 2023-12-15)
binary: rustc
commit-hash: a96d57bdb6d2bb6d233d7d5aaefc2995ab99be01
commit-date: 2023-12-15
host: aarch64-apple-darwin
release: 1.76.0-nightly
LLVM version: 17.0.6

Anything else?

No response

@gak gak 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 Jan 25, 2024
@fmease fmease added A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. D-terse Diagnostics: An error or lint that doesn't give enough information about the problem at hand. and removed D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. D-terse Diagnostics: An error or lint that doesn't give enough information about the problem at hand. labels Jan 25, 2024
@chenyukang chenyukang self-assigned this Jan 27, 2024
@detly
Copy link

detly commented Feb 27, 2024

I thought the intent with dbg!() was to use it in a passthrough style, so you can insert it into existing expressions ie. return a; becomes return dbg!(a);. In which case, maybe the lint should be for not using the value resulting from evaluating dbg!(expr).

@gak
Copy link
Author

gak commented Feb 28, 2024

Not sure about the majority of users but for me dbg!(v); is a convenience over println!(“{:#?}”, v);. I use it without using the return value almost all of the time.

@detly
Copy link

detly commented Feb 28, 2024

Probably a common thing to do, sure, but if we're talking about adding a lint, why not nudge the user in the direction of the intended and documented usage? You could at least do both: "insert dbg!() into an existing expression or pass it a borrow" etc.

@chenyukang
Copy link
Member

chenyukang commented Mar 2, 2024

The fix in #120990 will only report a hint when there is already a borrow of moved value happened.

For example this code:

fn in_expr() -> String {
    let b: String = "".to_string();
    let res = dbg!(b);
    let _l = b.len();
    return res; 
}

before this fix the error is:

error[E0382]: borrow of moved value: `b`
  --> ./t/de.rs:10:14
   |
8  |     let b: String = "".to_string();
   |         - move occurs because `b` has type `String`, which does not implement the `Copy` trait
9  |     let res = dbg!(b);
   |               ------- value moved here
10 |     let _l = b.len();
   |              ^ value borrowed here after move
   |
help: borrow this binding in the pattern to avoid moving the value
  --> /Users/yukang/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/macros.rs:364:13
   |
364|             ref tmp => {
   |             +++

error: aborting due to 1 previous error

with the fix, since there is already a value moved here error, the lint will try to find out the original macro, and suggest a borrow:

error[E0382]: borrow of moved value: `b`
  --> ./t/de.rs:10:14
   |
8  |     let b: String = "".to_string();
   |         - move occurs because `b` has type `String`, which does not implement the `Copy` trait
9  |     let res = dbg!(b);
   |               ------- value moved here
10 |     let _l = b.len();
   |              ^ value borrowed here after move
   |
help: consider borrowing instead of transferring ownership
   |
9  |     let res = dbg!(&b);
   |                    +

The suggestion is not 100% right, since if we change it to let res = dbg!(&b), we need one more extra fix now(the return type is not expecting a reference), but there is a different issue, at least we have already moved one step on.

If the original code is:

fn in_expr() -> String {
    let b: String = "".to_string();
    let res = dbg!(b);
    let _l = b.len();
    return res.to_string();
}

Then suggest a borrow is a great and correct hint.

@chenyukang
Copy link
Member

Similar in the scenario of function argument:

fn get_expr(_s: String) {}

fn test() {
    let a: String = "".to_string();
    let _res = get_expr(dbg!(a));
    let _l = a.len();
}

original error is:

error[E0382]: borrow of moved value: `a`
  --> ./t/de.rs:12:14
   |
10 |     let a: String = "".to_string();
   |         - move occurs because `a` has type `String`, which does not implement the `Copy` trait
11 |     let _res = get_expr(dbg!(a));
   |                         ------- value moved here
12 |     let _l = a.len();
   |              ^ value borrowed here after move
   |
help: borrow this binding in the pattern to avoid moving the value
  --> /Users/yukang/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/macros.rs:364:13
   |
364|             ref tmp => {
   |             +++

new errors from the fix:

error[E0382]: borrow of moved value: `a`
  --> ./t/de.rs:12:14
   |
10 |     let a: String = "".to_string();
   |         - move occurs because `a` has type `String`, which does not implement the `Copy` trait
11 |     let _res = get_expr(dbg!(a));
   |                         ------- value moved here
12 |     let _l = a.len();
   |              ^ value borrowed here after move
   |
help: consider borrowing instead of transferring ownership
   |
11 |     let _res = get_expr(dbg!(&a));
   |                              +

@detly
Copy link

detly commented Mar 5, 2024

If the original code is:

fn in_expr() -> String {
    let b: String = "".to_string();
    let res = dbg!(b);
    let _l = b.len();
    return res.to_string();
}

Then suggest a borrow is a great and correct hint.

Would let _l = dbg!(b).len(); not also be a good hint?

Similar in the scenario of function argument:

The suggestion wouldn't compile anyway right? Because get_expr() would need to change to take &str? Without dbg!() involved, the compiler does indeed suggest that:

note: consider changing this parameter type in function `get_expr` to borrow instead if owning the value isn't necessary
 --> src/lib.rs:1:17
  |
1 | fn get_expr(_s: String) {}
  |    --------     ^^^^^^ this parameter takes ownership of the value
  |    |
  |    in this function
help: consider cloning the value if the performance cost is acceptable
  |
5 |     let _res = get_expr(a.clone());
  |                          ++++++++

Once that's addressed (whichever way it's done), dbg!() once again becomes transparent, and eg. dbg!(a).clone() or dbg!(&a) works. &dbg!(a) does not, however, and I see why a "consider borrowing" hint would be good there.

However, if you make the dbg!(&a) change first and leave get_expr(_s: String) as-is, the resulting error does not include the suggestion to change get_expr(), which is unhelpful.

(I agree that the ref tmp => { message is even less helpful though, I'm not disputing that.)

@chenyukang
Copy link
Member

chenyukang commented Mar 5, 2024

Would let _l = dbg!(b).len(); not also be a good hint?

Yes, it's a good hint, but from the implementation view of a hint, it's much harder to analyze the following code from the error point and then construct a new expression. Even it seems an easy thing for humans.

You are right, the suggestion is not 100% right, we may need an extra follow-up fix after applying the hint, which is also a common thing in rustc diagnostics.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jul 15, 2024
…r=oli-obk

Suggest a borrow when using dbg

Fixes rust-lang#120327
r? `@estebank`
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jul 15, 2024
…r=oli-obk

Suggest a borrow when using dbg

Fixes rust-lang#120327
r? `@estebank`
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jul 15, 2024
…r=oli-obk

Suggest a borrow when using dbg

Fixes rust-lang#120327
r? ``@estebank``
tgross35 added a commit to tgross35/rust that referenced this issue Jul 16, 2024
…r=oli-obk

Suggest a borrow when using dbg

Fixes rust-lang#120327
r? ```@estebank```
@bors bors closed this as completed in 12fd2f9 Jul 16, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Jul 16, 2024
Rollup merge of rust-lang#120990 - chenyukang:yukang-fix-120327-dbg, r=oli-obk

Suggest a borrow when using dbg

Fixes rust-lang#120327
r? ````@estebank````
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` 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.

4 participants