diff --git a/internal/src/pin_data.rs b/internal/src/pin_data.rs index 7d871236..18018b5d 100644 --- a/internal/src/pin_data.rs +++ b/internal/src/pin_data.rs @@ -79,9 +79,13 @@ pub(crate) fn pin_data( .map(|field| { let len = field.attrs.len(); field.attrs.retain(|a| !a.path().is_ident("pin")); - (len != field.attrs.len(), &*field) + let diff = len - field.attrs.len(); + if diff > 1 { + return Err(dcx.error(field, "#[pin] attribute specified more than once")); + } + Ok((diff > 0, &*field)) }) - .collect(); + .collect::>()?; for (pinned, field) in &fields { if !pinned && is_phantom_pinned(&field.ty) { diff --git a/tests/ui/compile-fail/pin_data/twice_pin.rs b/tests/ui/compile-fail/pin_data/twice_pin.rs new file mode 100644 index 00000000..c28dedd2 --- /dev/null +++ b/tests/ui/compile-fail/pin_data/twice_pin.rs @@ -0,0 +1,10 @@ +use pin_init::*; + +#[pin_data] +struct Foo { + #[pin] + #[pin] + a: usize, +} + +fn main() {} diff --git a/tests/ui/compile-fail/pin_data/twice_pin.stderr b/tests/ui/compile-fail/pin_data/twice_pin.stderr new file mode 100644 index 00000000..2a7ba524 --- /dev/null +++ b/tests/ui/compile-fail/pin_data/twice_pin.stderr @@ -0,0 +1,5 @@ +error: #[pin] attribute specified more than once + --> tests/ui/compile-fail/pin_data/twice_pin.rs:7:5 + | +7 | a: usize, + | ^^^^^^^^