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

Compiler can suggest #[derive(move Trait)] #55146

Open
jonas-schievink opened this issue Oct 17, 2018 · 3 comments
Open

Compiler can suggest #[derive(move Trait)] #55146

jonas-schievink opened this issue Oct 17, 2018 · 3 comments
Labels
A-attributes Area: Attributes (`#[…]`, `#![…]`) A-diagnostics Area: Messages for errors, warnings, and lints A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) C-bug Category: This is a bug. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jonas-schievink
Copy link
Contributor

When a custom derive generates a closure, and that closure causes a compiler error because it borrows its environment instead of correctly moving it, rustc suggests to put the move keyword into the #[derive] attribute:

Actual error message I just got:

error[E0373]: closure may outlive the current function, but it borrows `route_kind`, which is owned by the current function                                         
  --> modules/debug/src/lib.rs:19:10                                                                                                                                
   |                                                                                                                                                                
19 | #[derive(FromRequest)]                                                                                                                                         
   |          ^^^^^^^^^^^                                                                                                                                           
   |          |                                                                                                                                                     
   |          `route_kind` is borrowed here                                                                                                                         
   |          may outlive borrowed value `route_kind`                                                                                                               
help: to force the closure to take ownership of `route_kind` (and any other referenced variables), use the `move` keyword                                           
   |                                                                                                                                                                
19 | #[derive(move FromRequest)]                                                                                                                                    
   |          ^^^^^^^^^^^^^^^^                                                                                                                                      
                                                                                                                                                                    
error: aborting due to previous error                                                                                                                               

(this is happening in a rather convoluted production codebase, so unfortunately I don't have a test case yet)

If I'm not mistaken, this can only happen when the custom derive macro outputs incorrect code, so the impact is pretty limited.

@Havvy Havvy added A-attributes Area: Attributes (`#[…]`, `#![…]`) A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. labels Oct 17, 2018
@XAMPPRocky XAMPPRocky added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Jan 11, 2019
@estebank estebank added E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) labels Dec 20, 2019
@CobaltCause
Copy link

CobaltCause commented Sep 15, 2021

I ran into what I think is a similar problem on stable rust 1.55, MCVE here: https://or.computer.surgery/charles/rust_55146

@Bryysen
Copy link
Contributor

Bryysen commented Sep 15, 2021

Hey, I've also recently ran into something similar to the above while implementing a macro to generate boilerplate for error types

Weird suggestion
   Compiling util_proc v0.1.0 ( .. util_proc)
   Compiling util v0.1.0 ( .. util)
error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> src/lib.rs:817:18
    |
817 |         #[derive(EnumError, Debug)]
    |                  ^^^^^^^^^
    |                  |
    |                  this data with an anonymous lifetime `'_`...
    |                  ...is captured and required to live as long as `'static` here
    |
    = note: this error originates in the derive macro `EnumError` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `self`
    |
817 |         #[derive('_, Debug)]
    |                  ~~
help: alternatively, add an explicit `'static` bound to this reference
    |
817 |         #[derive(&'static MyError, Debug)]
    |                  ~~~~~~~~~~~~~~~~

Unfortunately I've since fixed the issue, error messages without any span are rarely useful so i wasn't paying much attention at the time.

Here is another
   Compiling util v0.1.0 ( .. util)
error: expected one of `!`, `,`, `.`, `::`, `?`, `{`, `}`, or an operator, found reserved identifier `_`
   --> src/lib.rs:817:18
    |
817 |         #[derive(EnumError, Debug)]
    |                  ^^^^^^^^^
    |                  |
    |                  expected one of 8 possible tokens
    |                  while parsing the `match` arm starting here
    |
    = note: this error originates in the derive macro `EnumError` (in Nightly builds, run with -Z macro-backtrace for more info)

error: proc-macro derive produced unparseable tokens
   --> src/lib.rs:817:18
    |
817 |         #[derive(EnumError, Debug)]
    |                  ^^^^^^^^^

error: expected `,`, found `;`
   --> src/lib.rs:817:18
    |
817 |         #[derive(EnumError, Debug)]
    |                  ^^^^^^^^^ expected `,`
    |
    = note: this error originates in the derive macro `EnumError` (in Nightly builds, run with -Z macro-backtrace for more info)

error: format argument must be a string literal
   --> src/lib.rs:817:18
    |
817 |         #[derive(EnumError, Debug)]
    |                  ^^^^^^^^^
    |
    = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might be missing a string literal to format with
    |
817 |         #[derive("{}", EnumError, Debug)]
    |                  +++++
Note the
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)

Edit: Didn't see that a MCVE was posted above. Just in case it's of any help I encountered these on beta

binary: rustc
commit-hash: e784c962ea252f0874a4305168077e7048cb39e9
commit-date: 2021-09-07
host: x86_64-unknown-linux-gnu
release: 1.56.0-beta.1
LLVM version: 13.0.0

@estebank
Copy link
Contributor

I have a repro case. The output is even worse now:

error[E0373]: closure may outlive the current function, but it borrows `books`, which is owned by the current function
  --> $DIR/issue-55146.rs:8:10
   |
LL | #[derive(Foo)]
   |          ^^^
   |          |
   |          `books` is borrowed here
   |          may outlive borrowed value `books`
   |
note: closure is returned here
  --> $DIR/issue-55146.rs:8:10
   |
LL |   #[derive(Foo)]
   |            ^--
   |            |
   |  __________in this derive macro expansion
   | |
LL | | struct Bar;
LL | |
LL | | fn main() {}
...  |
   = note: this error originates in the derive macro `Foo` (in Nightly builds, run with -Z macro-backtrace for more info)
help: to force the closure to take ownership of `books` (and any other referenced variables), use the `move` keyword
   |
LL | #[derive(move Foo)]
   |          ++++

The suggestion will no longer appear after #109082, but the "closure returned here" note still has an improper span:

error[E0373]: closure may outlive the current function, but it borrows `books`, which is owned by the current function
  --> $DIR/issue-55146.rs:8:10
   |
LL | #[derive(Foo)]
   |          ^^^
   |          |
   |          `books` is borrowed here
   |          may outlive borrowed value `books`
   |
note: closure is returned here
  --> $DIR/issue-55146.rs:8:10
   |
LL |   #[derive(Foo)]
   |            ^--
   |            |
   |  __________in this derive macro expansion
   | |
LL | | struct Bar;
LL | |
LL | | fn main() {}
...  |
   = note: this error originates in the derive macro `Foo` (in Nightly builds, run with -Z macro-backtrace for more info)

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Mar 16, 2023
Do not provide suggestions when the spans come from expanded code that doesn't point at user code

Hide invalid proc-macro suggestions and track spans
coming from proc-macros pointing at attribute.

Effectively, unless the proc-macro keeps user spans,
suggestions will not be produced for the code they
produce.

r? `@ghost`

Fix rust-lang#107113, fix rust-lang#107976, fix rust-lang#107977, fix rust-lang#108748, fix rust-lang#106720, fix rust-lang#90557.

Could potentially address rust-lang#50141, rust-lang#67373, rust-lang#55146, rust-lang#78862, rust-lang#74043, rust-lang#88514, rust-lang#83320, rust-lang#91520, rust-lang#104071. CC rust-lang#50122, rust-lang#76360.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Mar 17, 2023
Do not provide suggestions when the spans come from expanded code that doesn't point at user code

Hide invalid proc-macro suggestions and track spans
coming from proc-macros pointing at attribute.

Effectively, unless the proc-macro keeps user spans,
suggestions will not be produced for the code they
produce.

r? ``@ghost``

Fix rust-lang#107113, fix rust-lang#107976, fix rust-lang#107977, fix rust-lang#108748, fix rust-lang#106720, fix rust-lang#90557.

Could potentially address rust-lang#50141, rust-lang#67373, rust-lang#55146, rust-lang#78862, rust-lang#74043, rust-lang#88514, rust-lang#83320, rust-lang#91520, rust-lang#104071. CC rust-lang#50122, rust-lang#76360.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-attributes Area: Attributes (`#[…]`, `#![…]`) A-diagnostics Area: Messages for errors, warnings, and lints A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) C-bug Category: This is a bug. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants