Fix no_std CI Warnings and WASM Compatibility (#17049)
				
					
				
			# Objective - Resolve several warnings encountered when compiling for `no_std` around `dead_code` - Fix compatibility with `wasm32-unknown-unknown` when using `no_std` (identified by Sachymetsu on [Discord](https://discord.com/channels/691052431525675048/692572690833473578/1323365426901549097)) ## Solution - Removed some unused imports - Added `allow(dead_code)` for certain private items when compiling on `no_std` - Fixed `bevy_app` and `bevy_tasks` compatibility with WASM when compiling without `std` by appropriately importing `Box` and feature gating panic unwinding ## Testing - CI
This commit is contained in:
		
							parent
							
								
									b78efd339d
								
							
						
					
					
						commit
						5f42c9ab6d
					
				| @ -10,7 +10,7 @@ use bevy_utils::Instant; | ||||
| 
 | ||||
| #[cfg(target_arch = "wasm32")] | ||||
| use { | ||||
|     alloc::rc::Rc, | ||||
|     alloc::{boxed::Box, rc::Rc}, | ||||
|     core::cell::RefCell, | ||||
|     wasm_bindgen::{prelude::*, JsCast}, | ||||
| }; | ||||
|  | ||||
| @ -1,12 +1,17 @@ | ||||
| #[cfg(feature = "alloc")] | ||||
| use alloc::{collections::BTreeMap, vec::Vec}; | ||||
| use { | ||||
|     super::{Measured2d, Triangle2d}, | ||||
|     alloc::{collections::BTreeMap, vec::Vec}, | ||||
| }; | ||||
| 
 | ||||
| use core::cmp::Ordering; | ||||
| 
 | ||||
| use crate::Vec2; | ||||
| 
 | ||||
| use super::{Measured2d, Triangle2d}; | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|     not(feature = "alloc"), | ||||
|     expect(dead_code, reason = "this type is only used with the alloc feature") | ||||
| )] | ||||
| #[derive(Debug, Clone, Copy)] | ||||
| enum Endpoint { | ||||
|     Left, | ||||
| @ -20,12 +25,20 @@ enum Endpoint { | ||||
| ///
 | ||||
| /// This is the order expected by the [`SweepLine`].
 | ||||
| #[derive(Debug, Clone, Copy)] | ||||
| #[cfg_attr(
 | ||||
|     not(feature = "alloc"), | ||||
|     allow(dead_code, reason = "this type is only used with the alloc feature") | ||||
| )] | ||||
| struct SweepLineEvent { | ||||
|     segment: Segment, | ||||
|     /// Type of the vertex (left or right)
 | ||||
|     endpoint: Endpoint, | ||||
| } | ||||
| impl SweepLineEvent { | ||||
|     #[cfg_attr(
 | ||||
|         not(feature = "alloc"), | ||||
|         allow(dead_code, reason = "this type is only used with the alloc feature") | ||||
|     )] | ||||
|     fn position(&self) -> Vec2 { | ||||
|         match self.endpoint { | ||||
|             Endpoint::Left => self.segment.left, | ||||
| @ -51,6 +64,10 @@ impl Ord for SweepLineEvent { | ||||
| } | ||||
| 
 | ||||
| /// Orders 2D points according to the order expected by the sweep line and event queue from -X to +X and then -Y to Y.
 | ||||
| #[cfg_attr(
 | ||||
|     not(feature = "alloc"), | ||||
|     allow(dead_code, reason = "this type is only used with the alloc feature") | ||||
| )] | ||||
| fn xy_order(a: Vec2, b: Vec2) -> Ordering { | ||||
|     a.x.total_cmp(&b.x).then_with(|| a.y.total_cmp(&b.y)) | ||||
| } | ||||
| @ -134,6 +151,10 @@ impl Ord for Segment { | ||||
| } | ||||
| 
 | ||||
| /// Holds information about which segment is above and which is below a given [`Segment`]
 | ||||
| #[cfg_attr(
 | ||||
|     not(feature = "alloc"), | ||||
|     expect(dead_code, reason = "this type is only used with the alloc feature") | ||||
| )] | ||||
| #[derive(Debug, Clone, Copy)] | ||||
| struct SegmentOrder { | ||||
|     above: Option<usize>, | ||||
| @ -241,6 +262,13 @@ impl<'a> SweepLine<'a> { | ||||
| /// Test what side of the line through `p1` and `p2` `q` is.
 | ||||
| ///
 | ||||
| /// The result will be `0` if the `q` is on the segment, negative for one side and positive for the other.
 | ||||
| #[cfg_attr(
 | ||||
|     not(feature = "alloc"), | ||||
|     expect( | ||||
|         dead_code, | ||||
|         reason = "this function is only used with the alloc feature" | ||||
|     ) | ||||
| )] | ||||
| #[inline(always)] | ||||
| fn point_side(p1: Vec2, p2: Vec2, q: Vec2) -> f32 { | ||||
|     (p2.x - p1.x) * (q.y - p1.y) - (q.x - p1.x) * (p2.y - p1.y) | ||||
|  | ||||
| @ -4,9 +4,6 @@ use assert_type_match::assert_type_match; | ||||
| use bevy_reflect_derive::{impl_reflect, impl_reflect_opaque}; | ||||
| use glam::*; | ||||
| 
 | ||||
| #[cfg(not(feature = "std"))] | ||||
| use alloc::format; | ||||
| 
 | ||||
| /// Reflects the given foreign type as an enum and asserts that the variants/fields match up.
 | ||||
| macro_rules! reflect_enum { | ||||
|     ($(#[$meta:meta])* enum $ident:ident { $($ty:tt)* } ) => { | ||||
| @ -381,6 +378,7 @@ impl_reflect_opaque!(::glam::BVec4A(Debug, Default, Deserialize, Serialize)); | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use alloc::format; | ||||
|     use ron::{ | ||||
|         ser::{to_string_pretty, PrettyConfig}, | ||||
|         Deserializer, | ||||
|  | ||||
| @ -1,11 +1,8 @@ | ||||
| use alloc::boxed::Box; | ||||
| use alloc::{boxed::Box, vec::Vec}; | ||||
| use bevy_reflect_derive::impl_type_path; | ||||
| use core::any::Any; | ||||
| use smallvec::{Array as SmallArray, SmallVec}; | ||||
| 
 | ||||
| #[cfg(not(feature = "std"))] | ||||
| use alloc::{format, vec, vec::Vec}; | ||||
| 
 | ||||
| use crate::{ | ||||
|     self as bevy_reflect, utility::GenericTypeInfoCell, ApplyError, FromReflect, FromType, | ||||
|     Generics, GetTypeRegistration, List, ListInfo, ListIter, MaybeTyped, PartialReflect, Reflect, | ||||
|  | ||||
| @ -8,7 +8,6 @@ | ||||
| //! [`async-executor`]: https://crates.io/crates/async-executor
 | ||||
| //! [`edge-executor`]: https://crates.io/crates/edge-executor
 | ||||
| 
 | ||||
| pub use async_task::Task; | ||||
| use core::{ | ||||
|     fmt, | ||||
|     panic::{RefUnwindSafe, UnwindSafe}, | ||||
|  | ||||
| @ -198,7 +198,7 @@ impl TaskPool { | ||||
|     where | ||||
|         T: 'static + MaybeSend + MaybeSync, | ||||
|     { | ||||
|         #[cfg(all(target_arch = "wasm32", feature = "std"))] | ||||
|         #[cfg(target_arch = "wasm32")] | ||||
|         return Task::wrap_future(future); | ||||
| 
 | ||||
|         #[cfg(all(not(target_arch = "wasm32"), feature = "std"))] | ||||
| @ -210,7 +210,7 @@ impl TaskPool { | ||||
|             Task::new(task) | ||||
|         }); | ||||
| 
 | ||||
|         #[cfg(not(feature = "std"))] | ||||
|         #[cfg(all(not(target_arch = "wasm32"), not(feature = "std")))] | ||||
|         return { | ||||
|             let task = LOCAL_EXECUTOR.spawn(future); | ||||
|             // Loop until all tasks are done
 | ||||
|  | ||||
| @ -14,11 +14,11 @@ use core::{ | ||||
| /// Tasks that panic get immediately canceled. Awaiting a canceled task also causes a panic.
 | ||||
| #[derive(Debug)] | ||||
| #[must_use = "Tasks are canceled when dropped, use `.detach()` to run them in the background."] | ||||
| pub struct Task<T>(crate::executor::Task<T>); | ||||
| pub struct Task<T>(async_task::Task<T>); | ||||
| 
 | ||||
| impl<T> Task<T> { | ||||
|     /// Creates a new task from a given `async_executor::Task`
 | ||||
|     pub fn new(task: crate::executor::Task<T>) -> Self { | ||||
|     pub fn new(task: async_task::Task<T>) -> Self { | ||||
|         Self(task) | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -1,7 +1,8 @@ | ||||
| use core::marker::PhantomData; | ||||
| use std::thread::{self, ThreadId}; | ||||
| 
 | ||||
| use crate::executor::{Executor, Task}; | ||||
| use crate::executor::Executor; | ||||
| use async_task::Task; | ||||
| use futures_lite::Future; | ||||
| 
 | ||||
| /// An executor that can only be ticked on the thread it was instantiated on. But
 | ||||
|  | ||||
| @ -1,3 +1,4 @@ | ||||
| use alloc::boxed::Box; | ||||
| use core::{ | ||||
|     any::Any, | ||||
|     future::{Future, IntoFuture}, | ||||
| @ -59,7 +60,12 @@ impl<T> Future for Task<T> { | ||||
|             // NOTE: Propagating the panic here sorta has parity with the async_executor behavior.
 | ||||
|             // For those tasks, polling them after a panic returns a `None` which gets `unwrap`ed, so
 | ||||
|             // using `resume_unwind` here is essentially keeping the same behavior while adding more information.
 | ||||
|             #[cfg(feature = "std")] | ||||
|             Poll::Ready(Ok(Err(panic))) => std::panic::resume_unwind(panic), | ||||
|             #[cfg(not(feature = "std"))] | ||||
|             Poll::Ready(Ok(Err(_panic))) => { | ||||
|                 unreachable!("catching a panic is only possible with std") | ||||
|             } | ||||
|             Poll::Ready(Err(_)) => panic!("Polled a task after it was cancelled"), | ||||
|             Poll::Pending => Poll::Pending, | ||||
|         } | ||||
| @ -74,6 +80,14 @@ struct CatchUnwind<F: UnwindSafe>(#[pin] F); | ||||
| impl<F: Future + UnwindSafe> Future for CatchUnwind<F> { | ||||
|     type Output = Result<F::Output, Panic>; | ||||
|     fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> { | ||||
|         std::panic::catch_unwind(AssertUnwindSafe(|| self.project().0.poll(cx)))?.map(Ok) | ||||
|         let f = AssertUnwindSafe(|| self.project().0.poll(cx)); | ||||
| 
 | ||||
|         #[cfg(feature = "std")] | ||||
|         let result = std::panic::catch_unwind(f)?; | ||||
| 
 | ||||
|         #[cfg(not(feature = "std"))] | ||||
|         let result = f(); | ||||
| 
 | ||||
|         result.map(Ok) | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Zachary Harrold
						Zachary Harrold