From 9c70db7cc4eb37d186ea955354589504e257f5fb Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Fri, 6 Jan 2023 13:59:00 -0500 Subject: [PATCH 01/10] add `MutUntyped::with_type` --- crates/bevy_ecs/src/change_detection.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/crates/bevy_ecs/src/change_detection.rs b/crates/bevy_ecs/src/change_detection.rs index 10bd2b5da3c9f..82cf12acc2872 100644 --- a/crates/bevy_ecs/src/change_detection.rs +++ b/crates/bevy_ecs/src/change_detection.rs @@ -444,6 +444,18 @@ impl<'a> MutUntyped<'a> { pub fn as_ref(&self) -> Ptr<'_> { self.value.as_ref() } + + /// Transforms this [`MutUntyped`] into a [`Mut`] with the same lifetime. + /// + /// # Safety + /// + /// Must point to a valid `T`. + pub unsafe fn with_type(self) -> Mut<'a, T> { + Mut { + value: self.value.deref_mut(), + ticks: self.ticks, + } + } } impl<'a> DetectChanges for MutUntyped<'a> { From 55bd1ba6ff0af1b1534edf53a87f25766d66046d Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Fri, 6 Jan 2023 20:47:59 -0500 Subject: [PATCH 02/10] be more specific about safety invariants --- crates/bevy_ecs/src/change_detection.rs | 2 +- crates/bevy_ptr/src/lib.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/bevy_ecs/src/change_detection.rs b/crates/bevy_ecs/src/change_detection.rs index 82cf12acc2872..689a29ee67d65 100644 --- a/crates/bevy_ecs/src/change_detection.rs +++ b/crates/bevy_ecs/src/change_detection.rs @@ -449,7 +449,7 @@ impl<'a> MutUntyped<'a> { /// /// # Safety /// - /// Must point to a valid `T`. + /// Must point to an aligned and fully-initialized `T` that is valid for writes. pub unsafe fn with_type(self) -> Mut<'a, T> { Mut { value: self.value.deref_mut(), diff --git a/crates/bevy_ptr/src/lib.rs b/crates/bevy_ptr/src/lib.rs index bf38fd5ff1d9f..b71de58bc564f 100644 --- a/crates/bevy_ptr/src/lib.rs +++ b/crates/bevy_ptr/src/lib.rs @@ -122,7 +122,7 @@ impl<'a> Ptr<'a> { /// Transforms this [`Ptr`] into a `&T` with the same lifetime /// /// # Safety - /// Must point to a valid `T` + /// Must point to an aligned and fully-initialized `T` that is valid for reads. #[inline] pub unsafe fn deref(self) -> &'a T { &*self.as_ptr().cast() @@ -161,7 +161,7 @@ impl<'a> PtrMut<'a> { /// Transforms this [`PtrMut`] into a `&mut T` with the same lifetime /// /// # Safety - /// Must point to a valid `T` + /// Must point to an aligned and fully-initialized `T` that is valid for writes. #[inline] pub unsafe fn deref_mut(self) -> &'a mut T { &mut *self.as_ptr().cast() @@ -214,7 +214,7 @@ impl<'a> OwningPtr<'a> { /// Consumes the [`OwningPtr`] to obtain ownership of the underlying data of type `T`. /// /// # Safety - /// Must point to a valid `T`. + /// Must point to an aligned and fully-initialized `T` that is valid for reads. #[inline] pub unsafe fn read(self) -> T { self.as_ptr().cast::().read() From 4fe76a03031fb82a52d347f8f97a028e3a5d8e6b Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Fri, 6 Jan 2023 21:59:07 -0500 Subject: [PATCH 03/10] make safety comments more precise --- crates/bevy_ecs/src/change_detection.rs | 4 ++-- crates/bevy_ptr/src/lib.rs | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/crates/bevy_ecs/src/change_detection.rs b/crates/bevy_ecs/src/change_detection.rs index 689a29ee67d65..1a82c4fbe7951 100644 --- a/crates/bevy_ecs/src/change_detection.rs +++ b/crates/bevy_ecs/src/change_detection.rs @@ -448,8 +448,8 @@ impl<'a> MutUntyped<'a> { /// Transforms this [`MutUntyped`] into a [`Mut`] with the same lifetime. /// /// # Safety - /// - /// Must point to an aligned and fully-initialized `T` that is valid for writes. + /// * Must be valid for writes and aligned for `T`. + /// * Must point to an initialized value of `T`. pub unsafe fn with_type(self) -> Mut<'a, T> { Mut { value: self.value.deref_mut(), diff --git a/crates/bevy_ptr/src/lib.rs b/crates/bevy_ptr/src/lib.rs index b71de58bc564f..8521f5df7ad15 100644 --- a/crates/bevy_ptr/src/lib.rs +++ b/crates/bevy_ptr/src/lib.rs @@ -161,7 +161,8 @@ impl<'a> PtrMut<'a> { /// Transforms this [`PtrMut`] into a `&mut T` with the same lifetime /// /// # Safety - /// Must point to an aligned and fully-initialized `T` that is valid for writes. + /// * Must be valid for writes and aligned for `T`. + /// * Must point to an initialized value of `T`. #[inline] pub unsafe fn deref_mut(self) -> &'a mut T { &mut *self.as_ptr().cast() @@ -214,7 +215,8 @@ impl<'a> OwningPtr<'a> { /// Consumes the [`OwningPtr`] to obtain ownership of the underlying data of type `T`. /// /// # Safety - /// Must point to an aligned and fully-initialized `T` that is valid for reads. + /// * Must be valid for reads and aligned for `T`. + /// * Must point to an initialized value of `T`. #[inline] pub unsafe fn read(self) -> T { self.as_ptr().cast::().read() @@ -223,7 +225,8 @@ impl<'a> OwningPtr<'a> { /// Consumes the [`OwningPtr`] to drop the underlying data of type `T`. /// /// # Safety - /// Must point to a valid `T`. + /// * Must be valid for writes and aligned for `T`. + /// * Must point to an initialized value of `T`. #[inline] pub unsafe fn drop_as(self) { self.as_ptr().cast::().drop_in_place(); From 139f5bf80596c39976f7213969b872b589aad4da Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Fri, 6 Jan 2023 22:00:32 -0500 Subject: [PATCH 04/10] update a function i forgot --- crates/bevy_ptr/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/bevy_ptr/src/lib.rs b/crates/bevy_ptr/src/lib.rs index 8521f5df7ad15..4e26e693bb21e 100644 --- a/crates/bevy_ptr/src/lib.rs +++ b/crates/bevy_ptr/src/lib.rs @@ -122,7 +122,8 @@ impl<'a> Ptr<'a> { /// Transforms this [`Ptr`] into a `&T` with the same lifetime /// /// # Safety - /// Must point to an aligned and fully-initialized `T` that is valid for reads. + /// * Must be valid for reads and aligned for `T`. + /// * Must point to an initialized value of `T`. #[inline] pub unsafe fn deref(self) -> &'a T { &*self.as_ptr().cast() From 8df064259af2307e8a15bfc7871d18b8727903e5 Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Sat, 7 Jan 2023 14:12:38 -0500 Subject: [PATCH 05/10] relax requirements on `OwningPtr` methods --- crates/bevy_ptr/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_ptr/src/lib.rs b/crates/bevy_ptr/src/lib.rs index 4e26e693bb21e..21a501aedb789 100644 --- a/crates/bevy_ptr/src/lib.rs +++ b/crates/bevy_ptr/src/lib.rs @@ -216,7 +216,7 @@ impl<'a> OwningPtr<'a> { /// Consumes the [`OwningPtr`] to obtain ownership of the underlying data of type `T`. /// /// # Safety - /// * Must be valid for reads and aligned for `T`. + /// * Must be aligned for `T`. /// * Must point to an initialized value of `T`. #[inline] pub unsafe fn read(self) -> T { @@ -226,7 +226,7 @@ impl<'a> OwningPtr<'a> { /// Consumes the [`OwningPtr`] to drop the underlying data of type `T`. /// /// # Safety - /// * Must be valid for writes and aligned for `T`. + /// * Must be aligned for `T`. /// * Must point to an initialized value of `T`. #[inline] pub unsafe fn drop_as(self) { From b5bee3de80b7036054233d3b9cb2575f18337b3e Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Sat, 7 Jan 2023 14:15:12 -0500 Subject: [PATCH 06/10] relax more requirements --- crates/bevy_ptr/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_ptr/src/lib.rs b/crates/bevy_ptr/src/lib.rs index 21a501aedb789..132a7b4ff58dd 100644 --- a/crates/bevy_ptr/src/lib.rs +++ b/crates/bevy_ptr/src/lib.rs @@ -122,7 +122,7 @@ impl<'a> Ptr<'a> { /// Transforms this [`Ptr`] into a `&T` with the same lifetime /// /// # Safety - /// * Must be valid for reads and aligned for `T`. + /// * Must be aligned for `T`. /// * Must point to an initialized value of `T`. #[inline] pub unsafe fn deref(self) -> &'a T { @@ -162,7 +162,7 @@ impl<'a> PtrMut<'a> { /// Transforms this [`PtrMut`] into a `&mut T` with the same lifetime /// /// # Safety - /// * Must be valid for writes and aligned for `T`. + /// * Must be aligned for `T`. /// * Must point to an initialized value of `T`. #[inline] pub unsafe fn deref_mut(self) -> &'a mut T { From 383b8343651a17c03c49453dcec3d09764fae934 Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Sat, 7 Jan 2023 14:18:40 -0500 Subject: [PATCH 07/10] last round of simplification --- crates/bevy_ptr/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/bevy_ptr/src/lib.rs b/crates/bevy_ptr/src/lib.rs index 132a7b4ff58dd..e824a472ffbb9 100644 --- a/crates/bevy_ptr/src/lib.rs +++ b/crates/bevy_ptr/src/lib.rs @@ -123,7 +123,7 @@ impl<'a> Ptr<'a> { /// /// # Safety /// * Must be aligned for `T`. - /// * Must point to an initialized value of `T`. + /// * Must point to a value of type `T`. #[inline] pub unsafe fn deref(self) -> &'a T { &*self.as_ptr().cast() @@ -163,7 +163,7 @@ impl<'a> PtrMut<'a> { /// /// # Safety /// * Must be aligned for `T`. - /// * Must point to an initialized value of `T`. + /// * Must point to a value of type `T`. #[inline] pub unsafe fn deref_mut(self) -> &'a mut T { &mut *self.as_ptr().cast() @@ -217,7 +217,7 @@ impl<'a> OwningPtr<'a> { /// /// # Safety /// * Must be aligned for `T`. - /// * Must point to an initialized value of `T`. + /// * Must point to a value of type `T`. #[inline] pub unsafe fn read(self) -> T { self.as_ptr().cast::().read() @@ -227,7 +227,7 @@ impl<'a> OwningPtr<'a> { /// /// # Safety /// * Must be aligned for `T`. - /// * Must point to an initialized value of `T`. + /// * Must point to a value of type `T`. #[inline] pub unsafe fn drop_as(self) { self.as_ptr().cast::().drop_in_place(); From 337af1d2612fc72725604aff03cb3302d37e1822 Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Mon, 9 Jan 2023 16:10:28 -0500 Subject: [PATCH 08/10] revert docs --- crates/bevy_ecs/src/change_detection.rs | 3 +-- crates/bevy_ptr/src/lib.rs | 12 ++++-------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/crates/bevy_ecs/src/change_detection.rs b/crates/bevy_ecs/src/change_detection.rs index 1a82c4fbe7951..4679da39a354f 100644 --- a/crates/bevy_ecs/src/change_detection.rs +++ b/crates/bevy_ecs/src/change_detection.rs @@ -448,8 +448,7 @@ impl<'a> MutUntyped<'a> { /// Transforms this [`MutUntyped`] into a [`Mut`] with the same lifetime. /// /// # Safety - /// * Must be valid for writes and aligned for `T`. - /// * Must point to an initialized value of `T`. + /// Must point to a valid `T` pub unsafe fn with_type(self) -> Mut<'a, T> { Mut { value: self.value.deref_mut(), diff --git a/crates/bevy_ptr/src/lib.rs b/crates/bevy_ptr/src/lib.rs index e824a472ffbb9..bfadeca3d1035 100644 --- a/crates/bevy_ptr/src/lib.rs +++ b/crates/bevy_ptr/src/lib.rs @@ -122,8 +122,7 @@ impl<'a> Ptr<'a> { /// Transforms this [`Ptr`] into a `&T` with the same lifetime /// /// # Safety - /// * Must be aligned for `T`. - /// * Must point to a value of type `T`. + /// Must point to a valid `T` #[inline] pub unsafe fn deref(self) -> &'a T { &*self.as_ptr().cast() @@ -162,8 +161,7 @@ impl<'a> PtrMut<'a> { /// Transforms this [`PtrMut`] into a `&mut T` with the same lifetime /// /// # Safety - /// * Must be aligned for `T`. - /// * Must point to a value of type `T`. + /// Must point to a valid `T` #[inline] pub unsafe fn deref_mut(self) -> &'a mut T { &mut *self.as_ptr().cast() @@ -216,8 +214,7 @@ impl<'a> OwningPtr<'a> { /// Consumes the [`OwningPtr`] to obtain ownership of the underlying data of type `T`. /// /// # Safety - /// * Must be aligned for `T`. - /// * Must point to a value of type `T`. + /// Must point to a valid `T` #[inline] pub unsafe fn read(self) -> T { self.as_ptr().cast::().read() @@ -226,8 +223,7 @@ impl<'a> OwningPtr<'a> { /// Consumes the [`OwningPtr`] to drop the underlying data of type `T`. /// /// # Safety - /// * Must be aligned for `T`. - /// * Must point to a value of type `T`. + /// Must point to a valid `T` #[inline] pub unsafe fn drop_as(self) { self.as_ptr().cast::().drop_in_place(); From 8da0ac4fc23a48897b89a089c7f70de70a62a2b8 Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Mon, 9 Jan 2023 16:11:18 -0500 Subject: [PATCH 09/10] typo --- crates/bevy_ecs/src/change_detection.rs | 2 +- crates/bevy_ptr/src/lib.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/bevy_ecs/src/change_detection.rs b/crates/bevy_ecs/src/change_detection.rs index 4679da39a354f..f079d980a2632 100644 --- a/crates/bevy_ecs/src/change_detection.rs +++ b/crates/bevy_ecs/src/change_detection.rs @@ -448,7 +448,7 @@ impl<'a> MutUntyped<'a> { /// Transforms this [`MutUntyped`] into a [`Mut`] with the same lifetime. /// /// # Safety - /// Must point to a valid `T` + /// Must point to a valid `T`. pub unsafe fn with_type(self) -> Mut<'a, T> { Mut { value: self.value.deref_mut(), diff --git a/crates/bevy_ptr/src/lib.rs b/crates/bevy_ptr/src/lib.rs index bfadeca3d1035..f28e7c7b880a0 100644 --- a/crates/bevy_ptr/src/lib.rs +++ b/crates/bevy_ptr/src/lib.rs @@ -122,7 +122,7 @@ impl<'a> Ptr<'a> { /// Transforms this [`Ptr`] into a `&T` with the same lifetime /// /// # Safety - /// Must point to a valid `T` + /// Must point to a valid `T`. #[inline] pub unsafe fn deref(self) -> &'a T { &*self.as_ptr().cast() @@ -161,7 +161,7 @@ impl<'a> PtrMut<'a> { /// Transforms this [`PtrMut`] into a `&mut T` with the same lifetime /// /// # Safety - /// Must point to a valid `T` + /// Must point to a valid `T`. #[inline] pub unsafe fn deref_mut(self) -> &'a mut T { &mut *self.as_ptr().cast() @@ -214,7 +214,7 @@ impl<'a> OwningPtr<'a> { /// Consumes the [`OwningPtr`] to obtain ownership of the underlying data of type `T`. /// /// # Safety - /// Must point to a valid `T` + /// Must point to a valid `T`. #[inline] pub unsafe fn read(self) -> T { self.as_ptr().cast::().read() @@ -223,7 +223,7 @@ impl<'a> OwningPtr<'a> { /// Consumes the [`OwningPtr`] to drop the underlying data of type `T`. /// /// # Safety - /// Must point to a valid `T` + /// Must point to a valid `T`. #[inline] pub unsafe fn drop_as(self) { self.as_ptr().cast::().drop_in_place(); From 7c72089c2389e7bc63bf71747f0600dc764d610c Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Wed, 11 Jan 2023 12:32:59 -0500 Subject: [PATCH 10/10] update docs for `with_type` --- crates/bevy_ecs/src/change_detection.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/change_detection.rs b/crates/bevy_ecs/src/change_detection.rs index fe29307649b07..516a007e61f64 100644 --- a/crates/bevy_ecs/src/change_detection.rs +++ b/crates/bevy_ecs/src/change_detection.rs @@ -482,7 +482,7 @@ impl<'a> MutUntyped<'a> { /// Transforms this [`MutUntyped`] into a [`Mut`] with the same lifetime. /// /// # Safety - /// Must point to a valid `T`. + /// - `T` must be the erased pointee type for this [`MutUntyped`]. pub unsafe fn with_type(self) -> Mut<'a, T> { Mut { value: self.value.deref_mut(),