Skip to content

Commit b0b7c9a

Browse files
committed
[wip] Introduce Ptr::project_map
Enables piecewise initialization. gherrit-pr-id: Gc3e9ee9afa6945e10c35be84d30c970894395c96
1 parent 7bc17a9 commit b0b7c9a

File tree

4 files changed

+62
-7
lines changed

4 files changed

+62
-7
lines changed

src/impls.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,16 +1080,24 @@ mod tuples {
10801080
// The types and indices at and after the current index.
10811081
[$CurrT:ident $CurrV:ident $CurrI:tt $($AfterT:ident $AfterV:ident $AfterI:tt)*]
10821082
) => {
1083+
impl<Replacement, $($AllT),+> crate::invariant::Map<Replacement, crate::Idx<{ $CurrI }>> for ($($AllT,)+)
1084+
where
1085+
Replacement: crate::invariant::Validity,
1086+
$($AllT: crate::invariant::Validity,)*
1087+
{
1088+
type Result = ($($BeforeT,)* Replacement, $($AfterT,)*);
1089+
}
1090+
10831091
// SAFETY:
10841092
// - `Self` is a struct (albeit anonymous), so `VARIANT_ID` is
10851093
// `STRUCT_VARIANT_ID`.
10861094
// - `$CurrI` is the field at index `$CurrI`, so `FIELD_ID` is
10871095
// `zerocopy::ident_id!($CurrI)`
1088-
// - `()` has the same visibility as the `.$CurrI` field (ie, `.0`,
1089-
// `.1`, etc)
1096+
// - `crate::Idx` has the same visibility as the `.$CurrI` field
1097+
// (ie, `.0`, `.1`, etc)
10901098
// - `Type` has the same type as `$CurrI`; i.e., `$CurrT`.
10911099
unsafe impl<$($AllT),+> crate::HasField<
1092-
(),
1100+
crate::Idx<{ $CurrI }>,
10931101
{ crate::STRUCT_VARIANT_ID },
10941102
{ crate::ident_id!($CurrI)}
10951103
> for ($($AllT,)+) {
@@ -1115,7 +1123,7 @@ mod tuples {
11151123

11161124
// SAFETY: See comments on items.
11171125
unsafe impl<Aliasing, Alignment, $($AllT),+> crate::ProjectField<
1118-
(),
1126+
crate::Idx<{ $CurrI }>,
11191127
(Aliasing, Alignment, crate::invariant::Uninit),
11201128
{ crate::STRUCT_VARIANT_ID },
11211129
{ crate::ident_id!($CurrI)}
@@ -1141,7 +1149,7 @@ mod tuples {
11411149

11421150
// SAFETY: See comments on items.
11431151
unsafe impl<Aliasing, Alignment, $($AllT),+> crate::ProjectField<
1144-
(),
1152+
crate::Idx<{ $CurrI }>,
11451153
(Aliasing, Alignment, crate::invariant::Initialized),
11461154
{ crate::STRUCT_VARIANT_ID },
11471155
{ crate::ident_id!($CurrI)}
@@ -1167,7 +1175,7 @@ mod tuples {
11671175

11681176
// SAFETY: See comments on items.
11691177
unsafe impl<Aliasing, Alignment, $($AllT),+> crate::ProjectField<
1170-
(),
1178+
crate::Idx<{ $CurrI }>,
11711179
(Aliasing, Alignment, crate::invariant::Valid),
11721180
{ crate::STRUCT_VARIANT_ID },
11731181
{ crate::ident_id!($CurrI)}
@@ -1193,7 +1201,7 @@ mod tuples {
11931201

11941202
// SAFETY: See comments on items.
11951203
unsafe impl<Aliasing, Alignment, $($AllT,)+ $($AllV),+> crate::ProjectField<
1196-
(),
1204+
crate::Idx<{ $CurrI }>,
11971205
(Aliasing, Alignment, ($($AllV,)+)),
11981206
{ crate::STRUCT_VARIANT_ID },
11991207
{ crate::ident_id!($CurrI)}

src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,6 +1123,11 @@ pub const UNION_VARIANT_ID: i128 = -2;
11231123
#[doc(hidden)]
11241124
pub const REPR_C_UNION_VARIANT_ID: i128 = -3;
11251125

1126+
/// A field visibility token for public tuple fields.
1127+
#[allow(missing_copy_implementations, missing_debug_implementations)]
1128+
#[doc(hidden)]
1129+
pub struct Idx<const INDEX: u16>;
1130+
11261131
/// # Safety
11271132
///
11281133
/// `Self::ProjectToTag` must satisfy its safety invariant.

src/pointer/invariant.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,16 @@ pub enum BecauseExclusive {}
277277
#[doc(hidden)]
278278
pub enum BecauseImmutable {}
279279

280+
/// Replaces a validity component.
281+
///
282+
/// The [`Self::Result`] is a validity identical `Self` except that the
283+
/// component corresponding to `Field` component has been replaced with
284+
/// `Replacement`.
285+
#[doc(hidden)]
286+
pub trait Map<Replacement: Validity, Field> {
287+
type Result: Validity;
288+
}
289+
280290
use sealed::Sealed;
281291
pub(crate) mod sealed {
282292
use super::*;

src/pointer/ptr.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,38 @@ mod _casts {
914914
tag.unify_invariants()
915915
}
916916

917+
#[inline(always)]
918+
pub fn project_map<F, V, const VARIANT_ID: i128, const FIELD_ID: i128>(
919+
mut self,
920+
map: impl for<'b> FnOnce(
921+
Ptr<'b, T::Type, T::Invariants>,
922+
) -> Ptr<
923+
'b,
924+
T::Type,
925+
(
926+
<T::Invariants as Invariants>::Aliasing,
927+
<T::Invariants as Invariants>::Alignment,
928+
V,
929+
),
930+
>,
931+
) -> Result<
932+
Ptr<'a, T, (I::Aliasing, I::Alignment, <I::Validity as Map<V, F>>::Result)>,
933+
T::Error,
934+
>
935+
where
936+
T: ProjectField<F, I, VARIANT_ID, FIELD_ID>,
937+
I::Aliasing: Reference,
938+
I::Validity: Map<V, F>,
939+
V: Validity,
940+
{
941+
let _mapped = match self.reborrow().project() {
942+
Ok(field) => map(field),
943+
Err(err) => return Err(err),
944+
};
945+
// SAFETY: TODO
946+
Ok(unsafe { self.assume_validity() })
947+
}
948+
917949
/// Attempts to transform the pointer, restoring the original on
918950
/// failure.
919951
///

0 commit comments

Comments
 (0)