Skip to content

Commit ae3f7e7

Browse files
committed
Mark fundamental traits as unsafe
Incorrect implementations of these could cause UB.
1 parent dfe269f commit ae3f7e7

5 files changed

Lines changed: 16 additions & 16 deletions

File tree

macros/src/bundle.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ fn gen_dynamic_bundle_impl(
3939
) -> TokenStream2 {
4040
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
4141
quote! {
42-
impl #impl_generics ::hecs::DynamicBundle for #ident #ty_generics #where_clause {
42+
unsafe impl #impl_generics ::hecs::DynamicBundle for #ident #ty_generics #where_clause {
4343
fn with_ids<__hecs__T>(&self, f: impl ::std::ops::FnOnce(&[::std::any::TypeId]) -> __hecs__T) -> __hecs__T {
4444
<Self as ::hecs::Bundle>::with_static_ids(f)
4545
}
@@ -98,7 +98,7 @@ fn gen_bundle_impl(
9898
}
9999
};
100100
quote! {
101-
impl #impl_generics ::hecs::Bundle for #ident #ty_generics #where_clause {
101+
unsafe impl #impl_generics ::hecs::Bundle for #ident #ty_generics #where_clause {
102102
#[allow(non_camel_case_types)]
103103
fn with_static_ids<__hecs__T>(f: impl ::std::ops::FnOnce(&[::std::any::TypeId]) -> __hecs__T) -> __hecs__T {
104104
#with_static_ids_body
@@ -129,7 +129,7 @@ fn gen_bundle_impl(
129129
fn gen_unit_struct_bundle_impl(ident: syn::Ident, generics: &syn::Generics) -> TokenStream2 {
130130
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
131131
quote! {
132-
impl #impl_generics ::hecs::Bundle for #ident #ty_generics #where_clause {
132+
unsafe impl #impl_generics ::hecs::Bundle for #ident #ty_generics #where_clause {
133133
#[allow(non_camel_case_types)]
134134
fn with_static_ids<__hecs__T>(f: impl ::std::ops::FnOnce(&[::std::any::TypeId]) -> __hecs__T) -> __hecs__T { f(&[]) }
135135
fn static_type_info() -> ::std::vec::Vec<::hecs::TypeInfo> { ::std::vec::Vec::new() }

macros/src/query.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ pub fn derive(input: DeriveInput) -> Result<TokenStream2> {
8989
#[doc(hidden)]
9090
#fetch
9191

92-
impl<'a> ::hecs::Fetch<'a> for #fetch_ident {
92+
unsafe impl<'a> ::hecs::Fetch<'a> for #fetch_ident {
9393
type Item = #ident<'a>;
9494

9595
fn dangling() -> Self {

src/bundle.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::archetype::TypeInfo;
2121
use crate::Component;
2222

2323
/// A dynamically typed collection of components
24-
pub trait DynamicBundle {
24+
pub unsafe trait DynamicBundle {
2525
/// Invoke a callback on the fields' type IDs, sorted by descending alignment then id
2626
#[doc(hidden)]
2727
fn with_ids<T>(&self, f: impl FnOnce(&[TypeId]) -> T) -> T;
@@ -37,7 +37,7 @@ pub trait DynamicBundle {
3737
}
3838

3939
/// A statically typed collection of components
40-
pub trait Bundle: DynamicBundle {
40+
pub unsafe trait Bundle: DynamicBundle {
4141
#[doc(hidden)]
4242
fn with_static_ids<T>(f: impl FnOnce(&[TypeId]) -> T) -> T;
4343

@@ -79,7 +79,7 @@ impl std::error::Error for MissingComponent {}
7979

8080
macro_rules! tuple_impl {
8181
($($name: ident),*) => {
82-
impl<$($name: Component),*> DynamicBundle for ($($name,)*) {
82+
unsafe impl<$($name: Component),*> DynamicBundle for ($($name,)*) {
8383
fn with_ids<T>(&self, f: impl FnOnce(&[TypeId]) -> T) -> T {
8484
Self::with_static_ids(f)
8585
}
@@ -102,7 +102,7 @@ macro_rules! tuple_impl {
102102
}
103103
}
104104

105-
impl<$($name: Component),*> Bundle for ($($name,)*) {
105+
unsafe impl<$($name: Component),*> Bundle for ($($name,)*) {
106106
fn with_static_ids<T>(f: impl FnOnce(&[TypeId]) -> T) -> T {
107107
const N: usize = count!($($name),*);
108108
let mut xs: [(usize, TypeId); N] = [$((mem::align_of::<$name>(), TypeId::of::<$name>())),*];

src/entity_builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ pub struct BuiltEntity<'a> {
180180
builder: &'a mut EntityBuilder,
181181
}
182182

183-
impl DynamicBundle for BuiltEntity<'_> {
183+
unsafe impl DynamicBundle for BuiltEntity<'_> {
184184
fn with_ids<T>(&self, f: impl FnOnce(&[TypeId]) -> T) -> T {
185185
f(&self.builder.ids)
186186
}

src/query.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub trait Query {
3131
pub type QueryItem<'a, Q> = <<Q as Query>::Fetch as Fetch<'a>>::Item;
3232

3333
/// Streaming iterators over contiguous homogeneous ranges of components
34-
pub trait Fetch<'a>: Sized {
34+
pub unsafe trait Fetch<'a>: Sized {
3535
/// Type of value to be fetched
3636
type Item;
3737

@@ -76,7 +76,7 @@ impl<'a, T: Component> Query for &'a T {
7676
#[doc(hidden)]
7777
pub struct FetchRead<T>(NonNull<T>);
7878

79-
impl<'a, T: Component> Fetch<'a> for FetchRead<T> {
79+
unsafe impl<'a, T: Component> Fetch<'a> for FetchRead<T> {
8080
type Item = &'a T;
8181

8282
fn dangling() -> Self {
@@ -113,7 +113,7 @@ impl<'a, T: Component> Query for &'a mut T {
113113
#[doc(hidden)]
114114
pub struct FetchWrite<T>(NonNull<T>);
115115

116-
impl<'a, T: Component> Fetch<'a> for FetchWrite<T> {
116+
unsafe impl<'a, T: Component> Fetch<'a> for FetchWrite<T> {
117117
type Item = &'a mut T;
118118

119119
fn dangling() -> Self {
@@ -150,7 +150,7 @@ impl<T: Query> Query for Option<T> {
150150
#[doc(hidden)]
151151
pub struct TryFetch<T>(Option<T>);
152152

153-
impl<'a, T: Fetch<'a>> Fetch<'a> for TryFetch<T> {
153+
unsafe impl<'a, T: Fetch<'a>> Fetch<'a> for TryFetch<T> {
154154
type Item = Option<T::Item>;
155155

156156
fn dangling() -> Self {
@@ -202,7 +202,7 @@ impl<T: Component, Q: Query> Query for Without<T, Q> {
202202
#[doc(hidden)]
203203
pub struct FetchWithout<T, F>(F, PhantomData<fn(T)>);
204204

205-
impl<'a, T: Component, F: Fetch<'a>> Fetch<'a> for FetchWithout<T, F> {
205+
unsafe impl<'a, T: Component, F: Fetch<'a>> Fetch<'a> for FetchWithout<T, F> {
206206
type Item = F::Item;
207207

208208
fn dangling() -> Self {
@@ -263,7 +263,7 @@ impl<T: Component, Q: Query> Query for With<T, Q> {
263263
#[doc(hidden)]
264264
pub struct FetchWith<T, F>(F, PhantomData<fn(T)>);
265265

266-
impl<'a, T: Component, F: Fetch<'a>> Fetch<'a> for FetchWith<T, F> {
266+
unsafe impl<'a, T: Component, F: Fetch<'a>> Fetch<'a> for FetchWith<T, F> {
267267
type Item = F::Item;
268268

269269
fn dangling() -> Self {
@@ -677,7 +677,7 @@ unsafe impl<'q, Q: Query> Sync for Batch<'q, Q> {}
677677

678678
macro_rules! tuple_impl {
679679
($($name: ident),*) => {
680-
impl<'a, $($name: Fetch<'a>),*> Fetch<'a> for ($($name,)*) {
680+
unsafe impl<'a, $($name: Fetch<'a>),*> Fetch<'a> for ($($name,)*) {
681681
type Item = ($($name::Item,)*);
682682

683683
fn dangling() -> Self {

0 commit comments

Comments
 (0)