Skip to content

Commit 37556ed

Browse files
committed
Change implementation to use safe upcasting polyfill
1 parent f884eab commit 37556ed

File tree

2 files changed

+21
-10
lines changed

2 files changed

+21
-10
lines changed

core/lib/src/fairing/mod.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,22 @@ pub use self::info_kind::{Info, Kind};
6464
/// A type alias for the return `Result` type of [`Fairing::on_ignite()`].
6565
pub type Result<T = Rocket<Build>, E = Rocket<Build>> = std::result::Result<T, E>;
6666

67+
pub trait AsAny: Any {
68+
fn as_any(&self) -> &dyn Any;
69+
fn as_any_mut(&mut self) -> &mut dyn Any;
70+
}
71+
72+
impl<T: Any> AsAny for T {
73+
fn as_any(&self) -> &dyn Any {
74+
self
75+
}
76+
77+
fn as_any_mut(&mut self) -> &mut dyn Any {
78+
self
79+
}
80+
}
81+
82+
6783
// We might imagine that a request fairing returns an `Outcome`. If it returns
6884
// `Success`, we don't do any routing and use that response directly. Same if it
6985
// returns `Error`. We only route if it returns `Forward`. I've chosen not to
@@ -425,7 +441,7 @@ pub type Result<T = Rocket<Build>, E = Rocket<Build>> = std::result::Result<T, E
425441
///
426442
/// [request-local state]: https://rocket.rs/master/guide/state/#request-local-state
427443
#[crate::async_trait]
428-
pub trait Fairing: Send + Sync + Any + 'static {
444+
pub trait Fairing: Send + Sync + AsAny + 'static {
429445
/// Returns an [`Info`] structure containing the `name` and [`Kind`] of this
430446
/// fairing. The `name` can be any arbitrary string. `Kind` must be an `or`d
431447
/// set of `Kind` variants.

core/lib/src/rocket.rs

+4-9
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ impl Rocket<Build> {
514514
/// If multiple instances of the same type of Fairing have been attached, the modify function
515515
/// will be run on each instance.
516516
#[must_use]
517-
pub fn modify_fairings<F: Fairing, E: fmt::Debug>(mut self, modifier: impl Fn(&mut F) -> Result<(), E>) -> Result<Self, Self> {
517+
pub fn modify_fairings<F: Fairing, E: fmt::Debug>(mut self, mut modifier: impl FnMut(&mut F) -> Result<(), E>) -> Result<Self, Self> {
518518
#[derive(Debug, PartialEq, Eq)]
519519
enum State {
520520
None,
@@ -523,16 +523,11 @@ impl Rocket<Build> {
523523
}
524524
let mut state = State::None;
525525
for f in self.fairings.iter_mut() {
526-
let f = f.as_mut();
527-
if f.type_id() == TypeId::of::<F>() {
528-
// SAFTEY: `f` is a valid pointer since it was obtained from a Box, and it points
529-
// at an `F` since it has the same TypeId. Converting from dyn type to a concrete
530-
// type is handled automatically by the compilier
531-
let f = unsafe { &mut *((f as *mut dyn Fairing) as *mut F) };
526+
if let Some(f) = f.as_any_mut().downcast_mut() {
532527
match modifier(f) {
533528
Ok(()) => if state == State::None { state = State::Success },
534-
Err(e) => {
535-
error_!("Failed to modify fairing: {:?}", e);
529+
Err(error) => {
530+
error!(?error, "Failed to modify fairing");
536531
state = State::Failure;
537532
}
538533
}

0 commit comments

Comments
 (0)