diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs
index 6a2e493a2..553ed76d3 100644
--- a/embassy-executor/src/lib.rs
+++ b/embassy-executor/src/lib.rs
@@ -1,4 +1,5 @@
 #![cfg_attr(not(any(feature = "arch-std", feature = "arch-wasm")), no_std)]
+#![cfg_attr(feature = "nightly", feature(waker_getters))]
 #![allow(clippy::new_without_default)]
 #![doc = include_str!("../README.md")]
 #![warn(missing_docs)]
diff --git a/embassy-executor/src/raw/waker.rs b/embassy-executor/src/raw/waker.rs
index 522853e34..75641c257 100644
--- a/embassy-executor/src/raw/waker.rs
+++ b/embassy-executor/src/raw/waker.rs
@@ -1,4 +1,3 @@
-use core::mem;
 use core::task::{RawWaker, RawWakerVTable, Waker};
 
 use super::{wake_task, TaskHeader, TaskRef};
@@ -33,20 +32,35 @@ pub(crate) unsafe fn from_task(p: TaskRef) -> Waker {
 ///
 /// Panics if the waker is not created by the Embassy executor.
 pub fn task_from_waker(waker: &Waker) -> TaskRef {
-    // safety: OK because WakerHack has the same layout as Waker.
-    // This is not really guaranteed because the structs are `repr(Rust)`, it is
-    // indeed the case in the current implementation.
-    // TODO use waker_getters when stable. https://github.com/rust-lang/rust/issues/96992
-    let hack: &WakerHack = unsafe { mem::transmute(waker) };
-    if hack.vtable != &VTABLE {
-        panic!("Found waker not created by the Embassy executor. `embassy_time::Timer` only works with the Embassy executor.")
+    #[cfg(not(feature = "nightly"))]
+    {
+        struct WakerHack {
+            data: *const (),
+            vtable: &'static RawWakerVTable,
+        }
+
+        // safety: OK because WakerHack has the same layout as Waker.
+        // This is not really guaranteed because the structs are `repr(Rust)`, it is
+        // indeed the case in the current implementation.
+        // TODO use waker_getters when stable. https://github.com/rust-lang/rust/issues/96992
+        let hack: &WakerHack = unsafe { core::mem::transmute(waker) };
+        if hack.vtable != &VTABLE {
+            panic!("Found waker not created by the Embassy executor. `embassy_time::Timer` only works with the Embassy executor.")
+        }
+
+        // safety: our wakers are always created with `TaskRef::as_ptr`
+        unsafe { TaskRef::from_ptr(hack.data as *const TaskHeader) }
     }
 
-    // safety: our wakers are always created with `TaskRef::as_ptr`
-    unsafe { TaskRef::from_ptr(hack.data as *const TaskHeader) }
-}
+    #[cfg(feature = "nightly")]
+    {
+        let raw_waker = waker.as_raw();
 
-struct WakerHack {
-    data: *const (),
-    vtable: &'static RawWakerVTable,
+        if raw_waker.vtable() != &VTABLE {
+            panic!("Found waker not created by the Embassy executor. `embassy_time::Timer` only works with the Embassy executor.")
+        }
+
+        // safety: our wakers are always created with `TaskRef::as_ptr`
+        unsafe { TaskRef::from_ptr(raw_waker.data() as *const TaskHeader) }
+    }
 }