This bisects to #156676, which was designed to solve #156475. The original issue involves code that is not macro-generated. I believe heuristics may need to be adjusted for the case of macro-generated code. It is common that macros use diagnostic attributes and assorted tricks to place custom error messages at some intentional location within the macro's input.
The following is minimized from https://github.com/dtolnay/cxx. It is designed to produce an error if and only if Unpin is not implemented for some type, in this case Arg.
# Cargo.toml
[package]
name = "repro"
edition = "2024"
publish = false
[lib]
proc-macro = true
[dependencies]
proc-macro2 = "1"
quote = "1"
// src/main.rs
pub struct Arg(std::marker::PhantomPinned);
#[repro::repro]
fn f(arg: &mut Arg);
fn main() {}
// src/lib.rs
use proc_macro::{TokenStream, TokenTree};
#[proc_macro_attribute]
pub fn repro(_args: TokenStream, input: TokenStream) -> TokenStream {
// Parse input that looks like `fn f(arg: &mut Arg);`
let mut input = input.into_iter();
assert_eq!(input.next().unwrap().to_string(), "fn");
assert_eq!(input.next().unwrap().to_string(), "f");
let TokenTree::Group(group) = input.next().unwrap() else {
unreachable!()
};
let mut input = group.stream().into_iter();
assert_eq!(input.next().unwrap().to_string(), "arg");
assert_eq!(input.next().unwrap().to_string(), ":");
let arg: TokenStream = input.collect();
let arg: proc_macro2::TokenStream = arg.into();
// Emit output:
TokenStream::from(quote::quote! {
const _: fn() = {
#[diagnostic::on_unimplemented(
message = "mutable reference to C++ type requires a pin -- use Pin<&mut Arg>",
label = "use `Pin<&mut Arg>`"
)]
trait ReferenceToUnpin_Arg {
fn check_unpin() {}
}
#[diagnostic::do_not_recommend]
impl<
'a,
T: ?::core::marker::Sized + ::core::marker::Unpin,
> ReferenceToUnpin_Arg for &'a mut T {}
<#arg as ReferenceToUnpin_Arg>::check_unpin
};
})
}
Before #156676:
error[E0277]: mutable reference to C++ type requires a pin -- use Pin<&mut Arg>
--> src/main.rs:6:11
|
6 | fn f(arg: &mut Arg);
| ^^^^^^^^ use `Pin<&mut Arg>`
|
= help: the trait `ReferenceToUnpin_Arg` is not implemented for `&mut Arg`
After #156676:
error[E0277]: mutable reference to C++ type requires a pin -- use Pin<&mut Arg>
--> src/main.rs:5:1
|
5 | #[repro::repro]
| ^^^^^^^^^^^^^^^ use `Pin<&mut Arg>`
|
= help: the trait `ReferenceToUnpin_Arg` is not implemented for `&mut Arg`
= note: this error originates in the attribute macro `repro::repro` (in Nightly builds, run with -Z macro-backtrace for more info)
@qaijuang @chenyukang
This bisects to #156676, which was designed to solve #156475. The original issue involves code that is not macro-generated. I believe heuristics may need to be adjusted for the case of macro-generated code. It is common that macros use
diagnosticattributes and assorted tricks to place custom error messages at some intentional location within the macro's input.The following is minimized from https://github.com/dtolnay/cxx. It is designed to produce an error if and only if
Unpinis not implemented for some type, in this caseArg.Before #156676:
After #156676:
@qaijuang @chenyukang