Skip to content

Commit 56bcbb0

Browse files
authored
Forbid unsafe in most crates in the engine (#12684)
# Objective Resolves #3824. `unsafe` code should be the exception, not the norm in Rust. It's obviously needed for various use cases as it's interfacing with platforms and essentially running the borrow checker at runtime in the ECS, but the touted benefits of Bevy is that we are able to heavily leverage Rust's safety, and we should be holding ourselves accountable to that by minimizing our unsafe footprint. ## Solution Deny `unsafe_code` workspace wide. Add explicit exceptions for the following crates, and forbid it in almost all of the others. * bevy_ecs - Obvious given how much unsafe is needed to achieve performant results * bevy_ptr - Works with raw pointers, even more low level than bevy_ecs. * bevy_render - due to needing to integrate with wgpu * bevy_window - due to needing to integrate with raw_window_handle * bevy_utils - Several unsafe utilities used by bevy_ecs. Ideally moved into bevy_ecs instead of made publicly usable. * bevy_reflect - Required for the unsafe type casting it's doing. * bevy_transform - for the parallel transform propagation * bevy_gizmos - For the SystemParam impls it has. * bevy_assets - To support reflection. Might not be required, not 100% sure yet. * bevy_mikktspace - due to being a conversion from a C library. Pending safe rewrite. * bevy_dynamic_plugin - Inherently unsafe due to the dynamic loading nature. Several uses of unsafe were rewritten, as they did not need to be using them: * bevy_text - a case of `Option::unchecked` could be rewritten as a normal for loop and match instead of an iterator. * bevy_color - the Pod/Zeroable implementations were replaceable with bytemuck's derive macros.
1 parent 025e8e6 commit 56bcbb0

File tree

44 files changed

+69
-50
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+69
-50
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ ptr_cast_constness = "warn"
4747
[workspace.lints.rust]
4848
unsafe_op_in_unsafe_fn = "warn"
4949
missing_docs = "warn"
50+
unsafe_code = "deny"
5051

5152
[lints]
5253
workspace = true

crates/bevy_animation/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2+
#![forbid(unsafe_code)]
23
#![doc(
34
html_logo_url = "https://bevyengine.org/assets/icon.png",
45
html_favicon_url = "https://bevyengine.org/assets/icon.png"

crates/bevy_app/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2+
#![forbid(unsafe_code)]
23
#![doc(
34
html_logo_url = "https://bevyengine.org/assets/icon.png",
45
html_favicon_url = "https://bevyengine.org/assets/icon.png"

crates/bevy_asset/src/reflect.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ impl ReflectAsset {
4646
}
4747

4848
/// Equivalent of [`Assets::get_mut`]
49+
#[allow(unsafe_code)]
4950
pub fn get_mut<'w>(
5051
&self,
5152
world: &'w mut World,
@@ -82,6 +83,7 @@ impl ReflectAsset {
8283
/// violating Rust's aliasing rules. To avoid this:
8384
/// * Only call this method if you know that the [`UnsafeWorldCell`] may be used to access the corresponding `Assets<T>`
8485
/// * Don't call this method more than once in the same scope.
86+
#[allow(unsafe_code)]
8587
pub unsafe fn get_unchecked_mut<'w>(
8688
&self,
8789
world: UnsafeWorldCell<'w>,
@@ -135,6 +137,7 @@ impl<A: Asset + FromReflect> FromType<A> for ReflectAsset {
135137
get_unchecked_mut: |world, handle| {
136138
// SAFETY: `get_unchecked_mut` must be called with `UnsafeWorldCell` having access to `Assets<A>`,
137139
// and must ensure to only have at most one reference to it live at all times.
140+
#[allow(unsafe_code)]
138141
let assets = unsafe { world.get_resource_mut::<Assets<A>>().unwrap().into_inner() };
139142
let asset = assets.get_mut(&handle.typed_debug_checked());
140143
asset.map(|asset| asset as &mut dyn Reflect)

crates/bevy_color/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2+
#![forbid(unsafe_code)]
23
#![doc(
34
html_logo_url = "https://bevyengine.org/assets/icon.png",
45
html_favicon_url = "https://bevyengine.org/assets/icon.png"

crates/bevy_color/src/linear_rgba.rs

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use bytemuck::{Pod, Zeroable};
1111
/// <div>
1212
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
1313
/// </div>
14-
#[derive(Debug, Clone, Copy, PartialEq, Reflect)]
14+
#[derive(Debug, Clone, Copy, PartialEq, Reflect, Pod, Zeroable)]
1515
#[reflect(PartialEq, Default)]
1616
#[cfg_attr(
1717
feature = "serialize",
@@ -373,33 +373,6 @@ impl encase::private::CreateFrom for LinearRgba {
373373
}
374374
}
375375

376-
/// A [`Zeroable`] type is one whose bytes can be filled with zeroes while remaining valid.
377-
///
378-
/// SAFETY: [`LinearRgba`] is inhabited
379-
/// SAFETY: [`LinearRgba`]'s all-zero bit pattern is a valid value
380-
unsafe impl Zeroable for LinearRgba {
381-
fn zeroed() -> Self {
382-
LinearRgba {
383-
red: 0.0,
384-
green: 0.0,
385-
blue: 0.0,
386-
alpha: 0.0,
387-
}
388-
}
389-
}
390-
391-
/// The [`Pod`] trait is [`bytemuck`]'s marker for types that can be safely transmuted from a byte array.
392-
///
393-
/// It is intended to only be implemented for types which are "Plain Old Data".
394-
///
395-
/// SAFETY: [`LinearRgba`] is inhabited.
396-
/// SAFETY: [`LinearRgba`] permits any bit value.
397-
/// SAFETY: [`LinearRgba`] does not have padding bytes.
398-
/// SAFETY: all of the fields of [`LinearRgba`] are [`Pod`], as f32 is [`Pod`].
399-
/// SAFETY: [`LinearRgba`] is `repr(C)`
400-
/// SAFETY: [`LinearRgba`] does not permit interior mutability.
401-
unsafe impl Pod for LinearRgba {}
402-
403376
impl encase::ShaderSize for LinearRgba {}
404377

405378
#[cfg(test)]

crates/bevy_core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2+
#![forbid(unsafe_code)]
23
#![doc(
34
html_logo_url = "https://bevyengine.org/assets/icon.png",
45
html_favicon_url = "https://bevyengine.org/assets/icon.png"

crates/bevy_core_pipeline/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// FIXME(3492): remove once docs are ready
22
#![allow(missing_docs)]
3+
#![forbid(unsafe_code)]
34
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
45
#![doc(
56
html_logo_url = "https://bevyengine.org/assets/icon.png",

crates/bevy_derive/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// FIXME(3492): remove once docs are ready
22
#![allow(missing_docs)]
3+
#![forbid(unsafe_code)]
34
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
45
#![doc(
56
html_logo_url = "https://bevyengine.org/assets/icon.png",

crates/bevy_dev_tools/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2+
#![forbid(unsafe_code)]
23
#![doc(
34
html_logo_url = "https://bevyengine.org/assets/icon.png",
45
html_favicon_url = "https://bevyengine.org/assets/icon.png"

crates/bevy_diagnostic/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// FIXME(3492): remove once docs are ready
22
#![allow(missing_docs)]
33
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
4+
#![forbid(unsafe_code)]
45
#![doc(
56
html_logo_url = "https://bevyengine.org/assets/icon.png",
67
html_favicon_url = "https://bevyengine.org/assets/icon.png"

crates/bevy_dynamic_plugin/src/loader.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![allow(unsafe_code)]
2+
13
use libloading::{Library, Symbol};
24
use std::ffi::OsStr;
35
use thiserror::Error;

crates/bevy_ecs/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#![allow(unsafe_op_in_unsafe_fn)]
33
#![doc = include_str!("../README.md")]
44
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
5+
#![allow(unsafe_code)]
56
#![doc(
67
html_logo_url = "https://bevyengine.org/assets/icon.png",
78
html_favicon_url = "https://bevyengine.org/assets/icon.png"

crates/bevy_encase_derive/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// FIXME(3492): remove once docs are ready
22
#![allow(missing_docs)]
3+
#![forbid(unsafe_code)]
34
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
45
#![doc(
56
html_logo_url = "https://bevyengine.org/assets/icon.png",

crates/bevy_gilrs/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2+
#![forbid(unsafe_code)]
23
#![doc(
34
html_logo_url = "https://bevyengine.org/assets/icon.png",
45
html_favicon_url = "https://bevyengine.org/assets/icon.png"

crates/bevy_gizmos/src/gizmos.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ type GizmosState<T> = (
4949
pub struct GizmosFetchState<T: GizmoConfigGroup> {
5050
state: <GizmosState<T> as SystemParam>::State,
5151
}
52+
53+
#[allow(unsafe_code)]
5254
// SAFETY: All methods are delegated to existing `SystemParam` implementations
5355
unsafe impl<T: GizmoConfigGroup> SystemParam for Gizmos<'_, '_, T> {
5456
type State = GizmosFetchState<T>;
@@ -90,6 +92,8 @@ unsafe impl<T: GizmoConfigGroup> SystemParam for Gizmos<'_, '_, T> {
9092
}
9193
}
9294
}
95+
96+
#[allow(unsafe_code)]
9397
// Safety: Each field is `ReadOnlySystemParam`, and Gizmos SystemParam does not mutate world
9498
unsafe impl<'w, 's, T: GizmoConfigGroup> ReadOnlySystemParam for Gizmos<'w, 's, T>
9599
where

crates/bevy_gltf/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2+
#![forbid(unsafe_code)]
23
#![doc(
34
html_logo_url = "https://bevyengine.org/assets/icon.png",
45
html_favicon_url = "https://bevyengine.org/assets/icon.png"

crates/bevy_hierarchy/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2+
#![forbid(unsafe_code)]
23
#![doc(
34
html_logo_url = "https://bevyengine.org/assets/icon.png",
45
html_favicon_url = "https://bevyengine.org/assets/icon.png"

crates/bevy_input/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2+
#![forbid(unsafe_code)]
23
#![doc(
34
html_logo_url = "https://bevyengine.org/assets/icon.png",
45
html_favicon_url = "https://bevyengine.org/assets/icon.png"

crates/bevy_internal/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2+
#![forbid(unsafe_code)]
23
#![doc(
34
html_logo_url = "https://bevyengine.org/assets/icon.png",
45
html_favicon_url = "https://bevyengine.org/assets/icon.png"

crates/bevy_log/src/android_tracing.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ impl<S: Subscriber + for<'a> LookupSpan<'a>> Layer<S> for AndroidLayer {
7373
}
7474
}
7575

76+
#[allow(unsafe_code)]
7677
fn on_event(&self, event: &Event<'_>, _ctx: Context<'_, S>) {
7778
let mut recorder = StringRecorder::new();
7879
event.record(&mut recorder);

crates/bevy_macro_utils/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![deny(unsafe_code)]
1+
#![forbid(unsafe_code)]
22
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
33
#![doc(
44
html_logo_url = "https://bevyengine.org/assets/icon.png",

crates/bevy_math/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2+
#![forbid(unsafe_code)]
23
#![doc(
34
html_logo_url = "https://bevyengine.org/assets/icon.png",
45
html_favicon_url = "https://bevyengine.org/assets/icon.png"

crates/bevy_mikktspace/src/generated.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@
4141
non_upper_case_globals,
4242
unused_mut,
4343
unused_assignments,
44-
unused_variables
44+
unused_variables,
45+
unsafe_code
4546
)]
4647

4748
use std::ptr::null_mut;

crates/bevy_mikktspace/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ pub trait Geometry {
6767
///
6868
/// Returns `false` if the geometry is unsuitable for tangent generation including,
6969
/// but not limited to, lack of vertices.
70+
#[allow(unsafe_code)]
7071
pub fn generate_tangents<I: Geometry>(geometry: &mut I) -> bool {
7172
unsafe { generated::genTangSpace(geometry, 180.0) }
7273
}

crates/bevy_pbr/src/meshlet/persistent_buffer.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![allow(unsafe_code)]
2+
13
use bevy_render::{
24
render_resource::{
35
BindingResource, Buffer, BufferAddress, BufferDescriptor, BufferUsages,

crates/bevy_pbr/src/meshlet/persistent_buffer_impls.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![allow(unsafe_code)]
12
#![allow(clippy::undocumented_unsafe_blocks)]
23

34
use super::{persistent_buffer::PersistentGpuBufferable, Meshlet, MeshletBoundingSphere};

crates/bevy_ptr/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![doc = include_str!("../README.md")]
22
#![no_std]
33
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
4+
#![allow(unsafe_code)]
45
#![doc(
56
html_logo_url = "https://bevyengine.org/assets/icon.png",
67
html_favicon_url = "https://bevyengine.org/assets/icon.png"

crates/bevy_reflect/src/path/parse.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ impl<'a> PathParser<'a> {
6565
// the last byte before an ASCII utf-8 character (ie: it is a char
6666
// boundary).
6767
// - The slice always starts after a symbol ie: an ASCII character's boundary.
68+
#[allow(unsafe_code)]
6869
let ident = unsafe { from_utf8_unchecked(ident) };
6970

7071
self.remaining = remaining;

crates/bevy_reflect/src/type_registry.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,7 @@ pub struct ReflectFromPtr {
663663
from_ptr_mut: unsafe fn(PtrMut) -> &mut dyn Reflect,
664664
}
665665

666+
#[allow(unsafe_code)]
666667
impl ReflectFromPtr {
667668
/// Returns the [`TypeId`] that the [`ReflectFromPtr`] was constructed for.
668669
pub fn type_id(&self) -> TypeId {
@@ -714,6 +715,7 @@ impl ReflectFromPtr {
714715
}
715716
}
716717

718+
#[allow(unsafe_code)]
717719
impl<T: Reflect> FromType<T> for ReflectFromPtr {
718720
fn from_type() -> Self {
719721
ReflectFromPtr {
@@ -733,6 +735,7 @@ impl<T: Reflect> FromType<T> for ReflectFromPtr {
733735
}
734736

735737
#[cfg(test)]
738+
#[allow(unsafe_code)]
736739
mod test {
737740
use crate::{GetTypeRegistration, ReflectFromPtr};
738741
use bevy_ptr::{Ptr, PtrMut};

crates/bevy_render/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// FIXME(3492): remove once docs are ready
22
#![allow(missing_docs)]
3+
#![allow(unsafe_code)]
34
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
45
#![doc(
56
html_logo_url = "https://bevyengine.org/assets/icon.png",

crates/bevy_scene/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2+
#![forbid(unsafe_code)]
23
#![doc(
34
html_logo_url = "https://bevyengine.org/assets/icon.png",
45
html_favicon_url = "https://bevyengine.org/assets/icon.png"

crates/bevy_sprite/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// FIXME(3492): remove once docs are ready
22
#![allow(missing_docs)]
33
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
4+
#![forbid(unsafe_code)]
45
#![doc(
56
html_logo_url = "https://bevyengine.org/assets/icon.png",
67
html_favicon_url = "https://bevyengine.org/assets/icon.png"

crates/bevy_tasks/src/single_threaded_task_pool.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ impl TaskPool {
9494
/// to spawn tasks. This function will await the completion of all tasks before returning.
9595
///
9696
/// This is similar to `rayon::scope` and `crossbeam::scope`
97+
#[allow(unsafe_code)]
9798
pub fn scope_with_executor<'env, F, T>(
9899
&self,
99100
_tick_task_pool_executor: bool,

crates/bevy_tasks/src/task_pool.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ impl TaskPool {
334334
})
335335
}
336336

337+
#[allow(unsafe_code)]
337338
fn scope_with_executor_inner<'env, F, T>(
338339
&self,
339340
tick_task_pool_executor: bool,

crates/bevy_text/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// FIXME(3492): remove once docs are ready
22
#![allow(missing_docs)]
33
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
4+
#![forbid(unsafe_code)]
45
#![doc(
56
html_logo_url = "https://bevyengine.org/assets/icon.png",
67
html_favicon_url = "https://bevyengine.org/assets/icon.png"

crates/bevy_text/src/pipeline.rs

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -129,32 +129,25 @@ impl TextMeasureInfo {
129129
scale_factor: f32,
130130
) -> Result<TextMeasureInfo, TextError> {
131131
let sections = &text.sections;
132-
for section in sections {
133-
if !fonts.contains(&section.style.font) {
134-
return Err(TextError::NoSuchFont);
135-
}
136-
}
137-
let (auto_fonts, sections) = sections
138-
.iter()
139-
.enumerate()
140-
.map(|(i, section)| {
141-
// SAFETY: we exited early earlier in this function if
142-
// one of the fonts was missing.
143-
let font = unsafe { fonts.get(&section.style.font).unwrap_unchecked() };
144-
(
145-
font.font.clone(),
146-
TextMeasureSection {
132+
let mut auto_fonts = Vec::with_capacity(sections.len());
133+
let mut out_sections = Vec::with_capacity(sections.len());
134+
for (i, section) in sections.iter().enumerate() {
135+
match fonts.get(&section.style.font) {
136+
Some(font) => {
137+
auto_fonts.push(font.font.clone());
138+
out_sections.push(TextMeasureSection {
147139
font_id: FontId(i),
148140
scale: scale_value(section.style.font_size, scale_factor),
149141
text: section.value.clone().into_boxed_str(),
150-
},
151-
)
152-
})
153-
.unzip();
142+
});
143+
}
144+
None => return Err(TextError::NoSuchFont),
145+
}
146+
}
154147

155148
Ok(Self::new(
156149
auto_fonts,
157-
sections,
150+
out_sections,
158151
text.justify,
159152
text.linebreak_behavior.into(),
160153
))

crates/bevy_time/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![doc = include_str!("../README.md")]
22
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
3+
#![forbid(unsafe_code)]
34
#![doc(
45
html_logo_url = "https://bevyengine.org/assets/icon.png",
56
html_favicon_url = "https://bevyengine.org/assets/icon.png"

crates/bevy_transform/src/systems.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ pub fn propagate_transforms(
7979
// - Since each root entity is unique and the hierarchy is consistent and forest-like,
8080
// other root entities' `propagate_recursive` calls will not conflict with this one.
8181
// - Since this is the only place where `transform_query` gets used, there will be no conflicting fetches elsewhere.
82+
#[allow(unsafe_code)]
8283
unsafe {
8384
propagate_recursive(
8485
&global_transform,
@@ -106,6 +107,7 @@ pub fn propagate_transforms(
106107
/// nor any of its descendants.
107108
/// - The caller must ensure that the hierarchy leading to `entity`
108109
/// is well-formed and must remain as a tree or a forest. Each entity must have at most one parent.
110+
#[allow(unsafe_code)]
109111
unsafe fn propagate_recursive(
110112
parent: &GlobalTransform,
111113
transform_query: &Query<

0 commit comments

Comments
 (0)