From cd9604f9740a592fe19196098decdf9b35f0dc15 Mon Sep 17 00:00:00 2001 From: Josh Liebow-Feeser Date: Wed, 14 Oct 2026 23:21:47 -0400 Subject: [PATCH] Express Alignment::read's pointer guarantees as a tuple Alignment::read quantifies over an Invariants implementation whose Alignment is Self. This creates a recursive declaration dependency which the pinned Aeneas cannot lower when a trait carries a validator signature. Accept Ptr<_, (A, Self, Safe)> with A: Reference directly. Normalize the existing caller through unify_invariants, which retains its aliasing, alignment and validity guarantees. Both read implementations keep their existing bodies. Validation: pinned MSRV and stable checks, all 170 nightly library tests, and nightly workspace Clippy. gherrit-pr-id: Gebc324cpvia63syt5uspvh2a7nz3uajp Agent-authored-by: AI agent acting on joshlf's behalf --- zerocopy/src/pointer/invariant.rs | 28 ++++++++++++++++------------ zerocopy/src/pointer/ptr.rs | 2 +- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/zerocopy/src/pointer/invariant.rs b/zerocopy/src/pointer/invariant.rs index e798feb4f1..ca07f01cbc 100644 --- a/zerocopy/src/pointer/invariant.rs +++ b/zerocopy/src/pointer/invariant.rs @@ -42,13 +42,17 @@ pub trait Aliasing: Sealed { /// The alignment invariant of a [`Ptr`][super::Ptr]. pub trait Alignment: Sealed { + // Name the aliasing parameter directly rather than quantifying over an + // Invariants implementation whose Alignment is Self. Both forms require + // the same pointer guarantees; the tuple avoids a recursive dependency + // between the Alignment and Invariants trait declarations during extraction. #[doc(hidden)] #[must_use] - fn read(ptr: crate::Ptr<'_, T, I>) -> T + fn read(ptr: crate::Ptr<'_, T, (A, Self, Safe)>) -> T where - T: Copy + Read, - I: Invariants, - I::Aliasing: Reference; + Self: Sized, + T: Copy + Read, + A: Reference; } /// The validity invariant of a [`Ptr`][super::Ptr]. @@ -148,11 +152,11 @@ pub enum Unaligned {} impl Alignment for Unaligned { #[inline(always)] - fn read(ptr: crate::Ptr<'_, T, I>) -> T + fn read(ptr: crate::Ptr<'_, T, (A, Self, Safe)>) -> T where - T: Copy + Read, - I: Invariants, - I::Aliasing: Reference, + Self: Sized, + T: Copy + Read, + A: Reference, { (*ptr.into_unalign().as_ref()).into_inner() } @@ -163,11 +167,11 @@ impl Alignment for Unaligned { pub enum Aligned {} impl Alignment for Aligned { #[inline(always)] - fn read(ptr: crate::Ptr<'_, T, I>) -> T + fn read(ptr: crate::Ptr<'_, T, (A, Self, Safe)>) -> T where - T: Copy + Read, - I: Invariants, - I::Aliasing: Reference, + Self: Sized, + T: Copy + Read, + A: Reference, { *ptr.as_ref() } diff --git a/zerocopy/src/pointer/ptr.rs b/zerocopy/src/pointer/ptr.rs index 2a492171d6..8b7f0628d0 100644 --- a/zerocopy/src/pointer/ptr.rs +++ b/zerocopy/src/pointer/ptr.rs @@ -613,7 +613,7 @@ mod _conversions { T: Copy, T: Read, { - ::read(self) + ::read(self.unify_invariants()) } /// Views the value as an aligned reference.