diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index 22a176621..6011d8663 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -57,6 +57,9 @@ avr-device = { version = "0.5.3", optional = true } critical-section = { version = "1.1", features = ["std"] } trybuild = "1.0" +[build-dependencies] +rustc_version = "0.4.1" + [features] ## Enable nightly-only features diff --git a/embassy-executor/build.rs b/embassy-executor/build.rs index 8a41d7503..c4c86e1e2 100644 --- a/embassy-executor/build.rs +++ b/embassy-executor/build.rs @@ -96,4 +96,15 @@ fn main() { let mut rustc_cfgs = common::CfgSet::new(); common::set_target_cfgs(&mut rustc_cfgs); + + // Waker API changed on 2024-09-06 + rustc_cfgs.declare("at_least_2024_09_06"); + let Some(compiler) = common::compiler_info() else { + return; + }; + if compiler.channel == rustc_version::Channel::Nightly + && compiler.commit_date.map(|d| d >= "2024-09-06").unwrap_or(false) + { + rustc_cfgs.enable("at_least_2024_09_06"); + } } diff --git a/embassy-executor/build_common.rs b/embassy-executor/build_common.rs index 4f24e6d37..af6bb0618 100644 --- a/embassy-executor/build_common.rs +++ b/embassy-executor/build_common.rs @@ -92,3 +92,54 @@ pub fn set_target_cfgs(cfgs: &mut CfgSet) { cfgs.set("has_fpu", target.ends_with("-eabihf")); } + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub struct CompilerDate { + year: u16, + month: u8, + day: u8, +} + +impl CompilerDate { + fn parse(date: &str) -> Option { + let mut parts = date.split('-'); + let year = parts.next()?.parse().ok()?; + let month = parts.next()?.parse().ok()?; + let day = parts.next()?.parse().ok()?; + Some(Self { year, month, day }) + } +} + +impl PartialEq<&str> for CompilerDate { + fn eq(&self, other: &&str) -> bool { + let Some(other) = Self::parse(other) else { + return false; + }; + self.eq(&other) + } +} + +impl PartialOrd<&str> for CompilerDate { + fn partial_cmp(&self, other: &&str) -> Option { + Self::parse(other).map(|other| self.cmp(&other)) + } +} + +pub struct CompilerInfo { + #[allow(unused)] + pub version: rustc_version::Version, + pub channel: rustc_version::Channel, + pub commit_date: Option, +} + +pub fn compiler_info() -> Option { + let Ok(meta) = rustc_version::version_meta() else { + return None; + }; + + Some(CompilerInfo { + version: meta.semver, + channel: meta.channel, + commit_date: meta.commit_date.as_deref().and_then(CompilerDate::parse), + }) +} diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs index d816539ac..8e07a8b18 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(all(feature = "nightly", not(at_least_2024_09_06)), 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 8bb2cfd05..30b8cdd4c 100644 --- a/embassy-executor/src/raw/waker.rs +++ b/embassy-executor/src/raw/waker.rs @@ -50,7 +50,16 @@ pub fn task_from_waker(waker: &Waker) -> TaskRef { #[cfg(feature = "nightly")] { - (waker.vtable(), waker.data()) + #[cfg(not(at_least_2024_09_06))] + { + let raw_waker = waker.as_raw(); + (raw_waker.vtable(), raw_waker.data()) + } + + #[cfg(at_least_2024_09_06)] + { + (waker.vtable(), waker.data()) + } } };