Can bypass #[repr(packed)] checking since rust 1.57
Since rust 1.57 it is possible to put proc macro attributes after derive (see https://github.com/rust-lang/rust/issues/81119) so given proc macro crate like that:
use proc_macro::TokenStream;
use syn::{parse_macro_input, parse_quote, ItemStruct};
use quote::quote;
#[proc_macro_attribute]
pub fn add_repr(_:TokenStream, item: TokenStream) -> TokenStream {
let mut item = parse_macro_input!(item as ItemStruct);
item.attrs.push(parse_quote!{#[add_repr_hidden]});
quote!{#item}.into()
}
#[proc_macro_attribute]
pub fn add_repr_hidden(_:TokenStream, item: TokenStream) -> TokenStream {
let mut item = parse_macro_input!(item as ItemStruct);
item.attrs.push(parse_quote!{#[repr(packed)]});
quote!{#item}.into()
}
and following usage :
#[pin_project]
#[add_repr]
pub struct Test {
x: i32
}
__PinProjectInternalDerive won't notice that at the end of the expansion there is #[repr(packed)] on struct
Of course, --cap-lints=warn is still required to actually compile it
I'm not sure how probable it is to trigger this problem in real code base..
As well as https://github.com/taiki-e/pin-project-lite/issues/26, it should eventually be fixed by unaligned_references becoming a hard error.
unaligned_references is now a hard error 🎉: https://github.com/rust-lang/rust/pull/102513