Closed
Description
Code generated in a proc-macro in the 2021 edition may fail to compile when used in a 2024 crate due to changes in impl trait capturing. This will leave the author of the 2024 crate without any ability to fix the issue.
Example:
// lib.rs
#[pm::pm]
pub struct S;
// proc-macro `pm`
use proc_macro::TokenStream;
#[proc_macro_attribute]
pub fn pm(_attr: TokenStream, _item: TokenStream) -> TokenStream {
"
pub struct X<'a>(::std::marker::PhantomData<&'a str>);
pub trait Tr<'a> {
fn foo(self, x: &mut X<'a>) where Self: Sized {}
}
pub struct Y<'a>(::std::marker::PhantomData<&'a str>);
impl<'a> Tr<'a> for Y<'a> {
}
pub fn f<'a>(x: &mut X<'a>) -> impl Tr<'a> {
Y(::std::marker::PhantomData)
}
pub fn g<'a>(x: &mut X<'a>) {
f(x).foo(x)
}
"
.parse()
.unwrap()
}
When the library is migrated with cargo fix --edition
, there is a warning that the proc-macro has an issue, but with no detail on what's going on (since all the code is hidden):
warning: `impl Tr<'a>` will capture more lifetimes than possibly intended in edition 2024
--> src/lib.rs:3:1
|
3 | #[pm::pm]
| ^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
--> src/lib.rs:3:1
|
3 | #[pm::pm]
| ^
= note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024
= note: `--force-warn impl-trait-overcaptures` implied by `--force-warn rust-2024-compatibility`
= note: this warning originates in the attribute macro `pm::pm` (in Nightly builds, run with -Z macro-backtrace for more info)
After migrating to 2024, it fails to compile:
error[E0499]: cannot borrow `*x` as mutable more than once at a time
--> src/lib.rs:3:1
|
3 | #[pm::pm]
| ^^^^^^^^^
| |
| `*x` was mutably borrowed here in the previous iteration of the loop
| first borrow later used by call
|
note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
--> src/lib.rs:3:1
|
3 | #[pm::pm]
| ^^^^^^^^^
= note: this error originates in the attribute macro `pm::pm` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add a precise capturing bound to avoid overcapturing
|
3 | #[pm::pm] + use<'a>
| +++++++++
Additionally, the suggestion provided there is incorrect, since it is not valid syntax.
I would expect the functions generated by the proc-macro to use the capturing rules from 2021. This is an issue because editions are supposed to be independent of the crate.
Meta
rustc --version --verbose
:
rustc 1.84.0-nightly (59cec72a5 2024-11-08)
binary: rustc
commit-hash: 59cec72a57af178767a7b8e7f624b06cc50f1087
commit-date: 2024-11-08
host: aarch64-apple-darwin
release: 1.84.0-nightly
LLVM version: 19.1.3