Skip to content

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

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

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.
# for free to join this conversation on GitHub. Already have an account? # 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