@@ -1139,6 +1139,17 @@ pub unsafe trait HasField<Field, const VARIANT_ID: i128, const FIELD_ID: i128> {
11391139 /// The type of the field.
11401140 type Type : ?Sized ;
11411141
1142+ /// The type's enum tag, or `()` for non-enum types.
1143+ type Tag : Immutable ;
1144+
1145+ /// A pointer projection from `Self` to its tag.
1146+ ///
1147+ /// # Safety
1148+ ///
1149+ /// It must be the case that, for all `slf: Ptr<'_, Self, I>`, it is sound
1150+ /// to project from `slf` to `Ptr<'_, Self::Tag, I>` using this projection.
1151+ type ProjectToTag : pointer:: cast:: Project < Self , Self :: Tag > ;
1152+
11421153 /// Projects from `slf` to the field.
11431154 ///
11441155 /// Users should generally not call `project` directly, and instead should
@@ -1185,6 +1196,18 @@ where
11851196 /// otherwise [`core::convert::Infallible`].
11861197 type Error ;
11871198
1199+ #[ must_use]
1200+ #[ inline( always) ]
1201+ fn project_tag < ' a > ( ptr : Ptr < ' a , Self , I > ) -> Ptr < ' a , Self :: Tag , I > {
1202+ // SAFETY: By invariant on `Self::ProjectToTag`, this is a sound
1203+ // projection.
1204+ let tag = unsafe { ptr. project_transmute_unchecked :: < _ , _ , Self :: ProjectToTag > ( ) } ;
1205+ // SAFETY: By invariant on `Self::ProjectToTag`, the projected pointer
1206+ // has the same alignment as `ptr`.
1207+ let tag = unsafe { tag. assume_alignment ( ) } ;
1208+ tag. unify_invariants ( )
1209+ }
1210+
11881211 /// Is the given field projectable from `ptr`?
11891212 ///
11901213 /// If a field with [`Self::Invariants`] is projectable from the referent,
@@ -1194,7 +1217,7 @@ where
11941217 /// This method must be overriden if the field's projectability depends on
11951218 /// the value of the bytes in `ptr`.
11961219 #[ inline( always) ]
1197- fn is_projectable < ' a > ( ptr : Ptr < ' a , Self , I > ) -> Result < Ptr < ' a , Self , I > , Self :: Error > {
1220+ fn is_projectable < ' a > ( _ptr : Ptr < ' a , Self :: Tag , I > ) -> Result < ( ) , Self :: Error > {
11981221 trait IsInfallible {
11991222 const IS_INFALLIBLE : bool ;
12001223 }
@@ -1248,7 +1271,7 @@ where
12481271 <Projection <Self , Field , I , VARIANT_ID , FIELD_ID > as IsInfallible >:: IS_INFALLIBLE
12491272 ) ;
12501273
1251- Ok ( ptr )
1274+ Ok ( ( ) )
12521275 }
12531276}
12541277
0 commit comments