Skip to content

Commit b1273d4

Browse files
authored
Enable clippy::check-private-items so that missing_safety_doc will apply to private functions as well (bevyengine#15161)
Enabled `check-private-items` in `clippy.toml` and then fixed the resulting errors. Most of these were simply misformatted and of the remaining: - ~Added `#[allow(clippy::missing_safety_doc)]` to~ Removed unsafe from a pair of functions in `bevy_utils/futures` which are only unsafe so that they can be passed to a function which requires `unsafe fn` - Removed `unsafe` from `UnsafeWorldCell::observers` as from what I can tell it is always safe like `components`, `bundles` etc. (this should be checked) - Added safety docs to: - `Bundles::get_storage_unchecked`: Based on the function that writes to `dynamic_component_storages` - `Bundles::get_storages_unchecked`: Based on the function that writes to `dynamic_bundle_storages` - `QueryIterationCursor::init_empty`: Duplicated from `init` - `QueryIterationCursor::peek_last`: Thanks Giooschi (also added internal unsafe blocks) - `tests::drop_ptr`: Moved safety comment out to the doc string This lint would also apply to `missing_errors_doc`, `missing_panics_doc` and `unnecessary_safety_doc` if we chose to enable any of those at some point, although there is an open [issue](rust-lang/rust-clippy#13074) to separate these options.
1 parent fbb9b36 commit b1273d4

File tree

11 files changed

+65
-30
lines changed

11 files changed

+65
-30
lines changed

clippy.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ doc-valid-idents = [
1111
"..",
1212
]
1313

14+
check-private-items = true
15+
1416
disallowed-methods = [
1517
{ path = "f32::powi", reason = "use bevy_math::ops::FloatPow::squared, bevy_math::ops::FloatPow::cubed, or bevy_math::ops::powf instead for libm determinism" },
1618
{ path = "f32::log", reason = "use bevy_math::ops::ln, bevy_math::ops::log2, or bevy_math::ops::log10 instead for libm determinism" },

crates/bevy_ecs/src/bundle.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,7 +1279,7 @@ impl<'w> BundleSpawner<'w> {
12791279
unsafe { &mut self.world.world_mut().entities }
12801280
}
12811281

1282-
/// # Safety:
1282+
/// # Safety
12831283
/// - `Self` must be dropped after running this function as it may invalidate internal pointers.
12841284
#[inline]
12851285
pub(crate) unsafe fn flush_commands(&mut self) {
@@ -1344,18 +1344,22 @@ impl Bundles {
13441344
}
13451345

13461346
/// # Safety
1347-
/// A `BundleInfo` with the given `BundleId` must have been initialized for this instance of `Bundles`.
1347+
/// A [`BundleInfo`] with the given [`BundleId`] must have been initialized for this instance of `Bundles`.
13481348
pub(crate) unsafe fn get_unchecked(&self, id: BundleId) -> &BundleInfo {
13491349
self.bundle_infos.get_unchecked(id.0)
13501350
}
13511351

1352+
/// # Safety
1353+
/// This [`BundleId`] must have been initialized with a single [`Component`] (via [`init_component_info`](Self::init_dynamic_info))
13521354
pub(crate) unsafe fn get_storage_unchecked(&self, id: BundleId) -> StorageType {
13531355
*self
13541356
.dynamic_component_storages
13551357
.get(&id)
13561358
.debug_checked_unwrap()
13571359
}
13581360

1361+
/// # Safety
1362+
/// This [`BundleId`] must have been initialized with multiple [`Component`]s (via [`init_dynamic_info`](Self::init_dynamic_info))
13591363
pub(crate) unsafe fn get_storages_unchecked(&mut self, id: BundleId) -> &mut Vec<StorageType> {
13601364
self.dynamic_bundle_storages
13611365
.get_mut(&id)

crates/bevy_ecs/src/component.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,7 @@ impl Debug for ComponentDescriptor {
738738
}
739739

740740
impl ComponentDescriptor {
741-
/// # SAFETY
741+
/// # Safety
742742
///
743743
/// `x` must point to a valid value of type `T`.
744744
unsafe fn drop_ptr<T>(x: OwningPtr<'_>) {

crates/bevy_ecs/src/query/iter.rs

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,7 +1290,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, I: Iterator<Item: Borrow<Entity>>>
12901290
}
12911291
}
12921292

1293-
/// Safety:
1293+
/// # Safety
12941294
/// All arguments must stem from the same valid `QueryManyIter`.
12951295
///
12961296
/// The lifetime here is not restrictive enough for Fetch with &mut access,
@@ -1578,7 +1578,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter, const K: usize> QueryCombinationIter<
15781578
}
15791579
}
15801580

1581-
/// Safety:
1581+
/// # Safety
15821582
/// The lifetime here is not restrictive enough for Fetch with &mut access,
15831583
/// as calling `fetch_next_aliased_unchecked` multiple times can produce multiple
15841584
/// references to the same component, leading to unique reference aliasing.
@@ -1733,6 +1733,9 @@ impl<D: QueryData, F: QueryFilter> Clone for QueryIterationCursor<'_, '_, D, F>
17331733
}
17341734

17351735
impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
1736+
/// # Safety
1737+
/// - `world` must have permission to access any of the components registered in `query_state`.
1738+
/// - `world` must be the same one used to initialize `query_state`.
17361739
unsafe fn init_empty(
17371740
world: UnsafeWorldCell<'w>,
17381741
query_state: &'s QueryState<D, F>,
@@ -1781,25 +1784,41 @@ impl<'w, 's, D: QueryData, F: QueryFilter> QueryIterationCursor<'w, 's, D, F> {
17811784
}
17821785
}
17831786

1784-
/// retrieve item returned from most recent `next` call again.
1787+
/// Retrieve item returned from most recent `next` call again.
1788+
///
1789+
/// # Safety
1790+
/// The result of `next` and any previous calls to `peek_last` with this row must have been
1791+
/// dropped to prevent aliasing mutable references.
17851792
#[inline]
17861793
unsafe fn peek_last(&mut self) -> Option<D::Item<'w>> {
17871794
if self.current_row > 0 {
17881795
let index = self.current_row - 1;
17891796
if self.is_dense {
1790-
let entity = self.table_entities.get_unchecked(index);
1791-
Some(D::fetch(
1792-
&mut self.fetch,
1793-
*entity,
1794-
TableRow::from_usize(index),
1795-
))
1797+
// SAFETY: This must have been called previously in `next` as `current_row > 0`
1798+
let entity = unsafe { self.table_entities.get_unchecked(index) };
1799+
// SAFETY:
1800+
// - `set_table` must have been called previously either in `next` or before it.
1801+
// - `*entity` and `index` are in the current table.
1802+
unsafe {
1803+
Some(D::fetch(
1804+
&mut self.fetch,
1805+
*entity,
1806+
TableRow::from_usize(index),
1807+
))
1808+
}
17961809
} else {
1797-
let archetype_entity = self.archetype_entities.get_unchecked(index);
1798-
Some(D::fetch(
1799-
&mut self.fetch,
1800-
archetype_entity.id(),
1801-
archetype_entity.table_row(),
1802-
))
1810+
// SAFETY: This must have been called previously in `next` as `current_row > 0`
1811+
let archetype_entity = unsafe { self.archetype_entities.get_unchecked(index) };
1812+
// SAFETY:
1813+
// - `set_archetype` must have been called previously either in `next` or before it.
1814+
// - `archetype_entity.id()` and `archetype_entity.table_row()` are in the current archetype.
1815+
unsafe {
1816+
Some(D::fetch(
1817+
&mut self.fetch,
1818+
archetype_entity.id(),
1819+
archetype_entity.table_row(),
1820+
))
1821+
}
18031822
}
18041823
} else {
18051824
None

crates/bevy_ecs/src/query/state.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
123123
///
124124
/// Consider using `as_readonly` or `as_nop` instead which are safe functions.
125125
///
126-
/// # SAFETY
126+
/// # Safety
127127
///
128128
/// `NewD` must have a subset of the access that `D` does and match the exact same archetypes/tables
129129
/// `NewF` must have a subset of the access that `F` does and match the exact same archetypes/tables

crates/bevy_ecs/src/storage/blob_vec.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,8 +507,12 @@ mod tests {
507507
use super::BlobVec;
508508
use std::{alloc::Layout, cell::RefCell, mem::align_of, rc::Rc};
509509

510+
/// # Safety
511+
///
512+
/// The pointer `x` must point to a valid value of type `T` and it must be safe to drop this value.
510513
unsafe fn drop_ptr<T>(x: OwningPtr<'_>) {
511-
// SAFETY: The pointer points to a valid value of type `T` and it is safe to drop this value.
514+
// SAFETY: It is guaranteed by the caller that `x` points to a
515+
// valid value of type `T` and it is safe to drop this value.
512516
unsafe {
513517
x.drop_as::<T>();
514518
}

crates/bevy_ecs/src/system/system_param.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1923,7 +1923,7 @@ pub struct DynSystemParam<'w, 's> {
19231923
}
19241924

19251925
impl<'w, 's> DynSystemParam<'w, 's> {
1926-
/// # SAFETY
1926+
/// # Safety
19271927
/// - `state` must be a `ParamState<T>` for some inner `T: SystemParam`.
19281928
/// - The passed [`UnsafeWorldCell`] must have access to any world data registered
19291929
/// in [`init_state`](SystemParam::init_state) for the inner system param.
@@ -1998,7 +1998,7 @@ impl<'w, 's> DynSystemParam<'w, 's> {
19981998
}
19991999
}
20002000

2001-
/// # SAFETY
2001+
/// # Safety
20022002
/// - `state` must be a `ParamState<T>` for some inner `T: SystemParam`.
20032003
/// - The passed [`UnsafeWorldCell`] must have access to any world data registered
20042004
/// in [`init_state`](SystemParam::init_state) for the inner system param.

crates/bevy_ecs/src/world/entity_ref.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,7 +1130,7 @@ impl<'w> EntityWorldMut<'w> {
11301130

11311131
/// Remove the components of `bundle` from `entity`.
11321132
///
1133-
/// SAFETY:
1133+
/// # Safety
11341134
/// - A `BundleInfo` with the corresponding `BundleId` must have been initialized.
11351135
#[allow(clippy::too_many_arguments)]
11361136
unsafe fn remove_bundle(&mut self, bundle: BundleId) -> EntityLocation {
@@ -1519,7 +1519,8 @@ impl<'w> EntityWorldMut<'w> {
15191519
}
15201520
}
15211521

1522-
/// SAFETY: all components in the archetype must exist in world
1522+
/// # Safety
1523+
/// All components in the archetype must exist in world
15231524
unsafe fn trigger_on_replace_and_on_remove_hooks_and_observers(
15241525
deferred_world: &mut DeferredWorld,
15251526
archetype: &Archetype,
@@ -2387,6 +2388,8 @@ impl<'w, B> EntityRefExcept<'w, B>
23872388
where
23882389
B: Bundle,
23892390
{
2391+
/// # Safety
2392+
/// Other users of `UnsafeEntityCell` must only have mutable access to the components in `B`.
23902393
pub(crate) unsafe fn new(entity: UnsafeEntityCell<'w>) -> Self {
23912394
Self {
23922395
entity,
@@ -2466,6 +2469,8 @@ impl<'w, B> EntityMutExcept<'w, B>
24662469
where
24672470
B: Bundle,
24682471
{
2472+
/// # Safety
2473+
/// Other users of `UnsafeEntityCell` must not have access to any components not in `B`.
24692474
pub(crate) unsafe fn new(entity: UnsafeEntityCell<'w>) -> Self {
24702475
Self {
24712476
entity,

crates/bevy_ecs/src/world/unsafe_world_cell.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ impl<'w> UnsafeWorldCell<'w> {
248248
}
249249

250250
/// Retrieves this world's [`Observers`] collection.
251-
pub(crate) unsafe fn observers(self) -> &'w Observers {
251+
pub(crate) fn observers(self) -> &'w Observers {
252252
// SAFETY:
253253
// - we only access world metadata
254254
&unsafe { self.world_metadata() }.observers
@@ -1002,7 +1002,7 @@ impl<'w> UnsafeEntityCell<'w> {
10021002

10031003
impl<'w> UnsafeWorldCell<'w> {
10041004
#[inline]
1005-
/// # Safety:
1005+
/// # Safety
10061006
/// - the returned `Table` is only used in ways that this [`UnsafeWorldCell`] has permission for.
10071007
/// - the returned `Table` is only used in ways that would not conflict with any existing borrows of world data.
10081008
unsafe fn fetch_table(self, location: EntityLocation) -> Option<&'w Table> {
@@ -1013,7 +1013,7 @@ impl<'w> UnsafeWorldCell<'w> {
10131013
}
10141014

10151015
#[inline]
1016-
/// # Safety:
1016+
/// # Safety
10171017
/// - the returned `ComponentSparseSet` is only used in ways that this [`UnsafeWorldCell`] has permission for.
10181018
/// - the returned `ComponentSparseSet` is only used in ways that would not conflict with any existing
10191019
/// borrows of world data.

crates/bevy_render/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,8 @@ fn extract(main_world: &mut World, render_world: &mut World) {
447447
main_world.insert_resource(ScratchMainWorld(scratch_world));
448448
}
449449

450-
/// SAFETY: this function must be called from the main thread.
450+
/// # Safety
451+
/// This function must be called from the main thread.
451452
unsafe fn initialize_render_app(app: &mut App) {
452453
app.init_resource::<ScratchMainWorld>();
453454

crates/bevy_utils/src/futures.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ pub fn check_ready<F: Future + Unpin>(future: &mut F) -> Option<F::Output> {
3636
}
3737
}
3838

39-
unsafe fn noop_clone(_data: *const ()) -> RawWaker {
39+
fn noop_clone(_data: *const ()) -> RawWaker {
4040
noop_raw_waker()
4141
}
42-
unsafe fn noop(_data: *const ()) {}
42+
fn noop(_data: *const ()) {}
4343

4444
const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(noop_clone, noop, noop, noop);
4545

0 commit comments

Comments
 (0)