From c3cd739dffc94065d91499a6144d1d06971f1fa3 Mon Sep 17 00:00:00 2001 From: Avril Date: Mon, 3 Aug 2020 00:56:31 +0100 Subject: [PATCH] added build-script --- Cargo.lock | 26 +++++++++++ Cargo.toml | 6 ++- build.rs | 24 ++++++++++ src/interval.rs | 1 + src/live.rs | 4 +- src/main.rs | 6 +-- src/util.rs | 116 +++++++++++++++++++++++++++++++++++++++++------- 7 files changed, 160 insertions(+), 23 deletions(-) create mode 100644 build.rs diff --git a/Cargo.lock b/Cargo.lock index 02b6cac..2675620 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -300,12 +300,14 @@ dependencies = [ name = "lolicron" version = "0.1.0" dependencies = [ + "cfg-if", "chrono", "futures", "lazy_static", "notify", "once_cell", "recolored", + "rustc_version", "sexp", "tokio", ] @@ -504,6 +506,15 @@ version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + [[package]] name = "same-file" version = "1.0.6" @@ -513,6 +524,21 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + [[package]] name = "sexp" version = "1.1.4" diff --git a/Cargo.toml b/Cargo.toml index 054e84a..ef9aa10 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,4 +20,8 @@ sexp = "1.1" once_cell = "1.4" lazy_static = "1.4" recolored = "1.9.3" -chrono = "0.4" \ No newline at end of file +chrono = "0.4" +cfg-if = "0.1" + +[build-dependencies] +rustc_version = "0.2" \ No newline at end of file diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..6399463 --- /dev/null +++ b/build.rs @@ -0,0 +1,24 @@ + +extern crate rustc_version; +use rustc_version::{version, version_meta, Channel}; + +fn main() { + // Assert we haven't travelled back in time + assert!(version().unwrap().major >= 1); + + // Set cfg flags depending on release channel + match version_meta().unwrap().channel { + Channel::Stable => { + println!("cargo:rustc-cfg=stable"); + } + Channel::Beta => { + println!("cargo:rustc-cfg=beta"); + } + Channel::Nightly => { + println!("cargo:rustc-cfg=nightly"); + } + Channel::Dev => { + println!("cargo:rustc-cfg=dev"); + } + } +} diff --git a/src/interval.rs b/src/interval.rs index 43897c0..3f0d459 100644 --- a/src/interval.rs +++ b/src/interval.rs @@ -25,6 +25,7 @@ pub enum Unit impl Unit { /// Multiplier to get to miliseconds + #[inline] #[cfg(nightly)] const fn multiplier(&self) -> u64 { diff --git a/src/live.rs b/src/live.rs index fe2fe38..92f6fd7 100644 --- a/src/live.rs +++ b/src/live.rs @@ -118,10 +118,10 @@ impl Hook { /// Try to dispatch on one of many paths pub async fn try_dispatch_many(&self, paths: T, event: &Event) -> Result> - where T: AsRef<[P]>, + where T: IntoIterator, P: AsRef { - for path in paths.as_ref().iter() { + for path in paths.into_iter() { if self.path == path.as_ref() { self.dispatch(event.to_owned()).await?; return Ok(true); diff --git a/src/main.rs b/src/main.rs index 73b9738..845cb47 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ -#![cfg_attr(nightly, int_error_matching)] -#![cfg_attr(nightly, const_fn)] - +#![cfg_attr(nightly, feature(int_error_matching))] +#![cfg_attr(nightly, feature(const_fn))] +#![cfg_attr(nightly, feature(maybe_uninit_ref))] #![allow(dead_code)] diff --git a/src/util.rs b/src/util.rs index 0764e23..f5c6c8d 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,15 +1,29 @@ +#[allow(unused_imports)] use std::{ ops::{ Drop, Deref, DerefMut, }, - mem::replace, + mem::{ + replace, + MaybeUninit, + }, fmt, }; +use cfg_if::cfg_if; + + +#[cfg(not(debug_assertions))] +type OptFn = MaybeUninit<(T,F)>; +#[cfg(debug_assertions)] +type OptFn = Option<(T,F)>; /// Allow for running function on drop, to support moving out of a larger structure. -pub struct PhantomDrop(Option<(T,F)>) +/// +/// # Notes +/// This type has a safe ABI with runtime checks when compiled with `debug_assertions`, without them an unsafe but lower cost ABI is preferred. +pub struct PhantomDrop(OptFn) where F: FnOnce(T); @@ -27,9 +41,20 @@ impl Drop for PhantomDrop where F:FnOnce(T) { fn drop(&mut self) { - if let Some((value, func)) = replace(&mut self.0, None) - { - func(value); + cfg_if! { + if #[cfg(debug_assertions)] { + if let Some((value, func)) = replace(&mut self.0, None) + { + func(value); + } else { + panic!("Double drop?") + } + } else { + let (value, func) = unsafe { + (&mut self.0 as *mut OptFn).read().assume_init() + }; + func(value); + } } } } @@ -42,14 +67,56 @@ where F:FnOnce(T) #[cfg(nightly)] pub const fn new(value: T, func: F) -> Self { - Self(Some((value,func))) + cfg_if! { + if #[cfg(debug_assertions)] { + Self(Some((value,func))) + } else { + Self(MaybeUninit::new((value,func))) + } + } } /// Create a new `PhantomDrop` with a drop closure and a value. #[cfg(not(nightly))] pub fn new(value: T, func: F) -> Self + { + cfg_if! { + if #[cfg(debug_assertions)] { + Self(Some((value,func))) + } else { + Self(MaybeUninit::new((value,func))) + } + } + } + + #[cfg(not(debug_assertions))] + #[inline] + fn get_ref<'a>(&'a self) -> &'a (T, F) { - Self(Some((value,func))) + unsafe { + cfg_if! { + if #[cfg(nightly)] { + self.0.get_ref() + } else { + std::mem::transmute::<_,&'a T>(self.0.as_ptr()) + } + } + } + } + + #[cfg(not(debug_assertions))] + #[inline] + fn get_mut<'a>(&'a mut self) -> &'a mut (T, F) + { + unsafe { + cfg_if! { + if #[cfg(nightly)] { + self.0.get_mut() + } else { + std::mem::transmute::<_,&'a T>(self.0.as_mut_ptr()) + } + } + } } } @@ -60,11 +127,18 @@ where F:FnOnce(T) type Target = T; fn deref(&self) -> &Self::Target { - if let Some((t, _)) = &self.0 - { - t - } else { - panic!("Double drop?") + cfg_if! { + if #[cfg(debug_assertions)] { + if let Some((t, _)) = &self.0 + { + t + } else { + panic!("Double drop?") + } + } else { + let (t, _) = self.get_ref(); + t + } } } } @@ -75,11 +149,19 @@ where F:FnOnce(T) { fn deref_mut(&mut self) -> &mut ::Target { - if let Some((t, _)) = &mut self.0 - { - t - } else { - panic!("Double drop?") + cfg_if! { + if #[cfg(debug_assertions)] { + if let Some((t, _)) = &mut self.0 + { + t + } else { + panic!("Double drop?") + } + } else { + let (t, _) = self.get_mut(); + t + } } + } }