From a5c42b956ae51c00576d4915d7c9ef7204a98d12 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 11 May 2018 13:50:58 +0200 Subject: [PATCH] replace uses of ! with Void --- .travis.yml | 8 ++++++ CHANGELOG.md | 15 +++++++++- Cargo.toml | 4 +++ ci/install.sh | 4 ++- ci/script.sh | 6 +++- src/lib.rs | 78 +++++++++++++++++++++++++++------------------------ src/timer.rs | 8 ++++-- 7 files changed, 81 insertions(+), 42 deletions(-) diff --git a/.travis.yml b/.travis.yml index 201117897..2e67e9ab6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,14 @@ language: rust matrix: include: + - env: TARGET=x86_64-unknown-linux-gnu + + - env: TARGET=thumbv6m-none-eabi + rust: beta + + - env: TARGET=thumbv7m-none-eabi + rust: beta + - env: TARGET=x86_64-unknown-linux-gnu rust: nightly diff --git a/CHANGELOG.md b/CHANGELOG.md index 36d2c9743..324c55907 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +## [v0.2.0] - 2018-05-11 + +### Changed + +- [breaking-change] The signature of `CountDown.wait` changed; it now returns `nb::Result<(), + Void>`. Where [`Void`] is the stable alternative to the never type, `!`, provided by the stable + [`void`] crate. Implementations of the `CountDown` trait will have to be updated to use the new + signature. With this change this crate compiles on the stable and beta channels. + +[`Void`]: https://docs.rs/void/1.0.2/void/enum.Void.html +[`void`]: https://crates.io/crates/void + ## [v0.1.2] - 2018-02-14 ### Added @@ -23,6 +35,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). Initial release -[Unreleased]: https://github.com/japaric/embedded-hal/compare/v0.1.2...HEAD +[Unreleased]: https://github.com/japaric/embedded-hal/compare/v0.2.0...HEAD +[v0.2.0]: https://github.com/japaric/embedded-hal/compare/v0.1.2...v0.2.0 [v0.1.2]: https://github.com/japaric/embedded-hal/compare/v0.1.1...v0.1.2 [v0.1.1]: https://github.com/japaric/embedded-hal/compare/v0.1.0...v0.1.1 diff --git a/Cargo.toml b/Cargo.toml index 5b1b4bc65..225fce0c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,10 @@ readme = "README.md" repository = "https://github.com/japaric/embedded-hal" version = "0.1.2" +[dependencies.void] +default-features = false +version = "1.0.2" + [dependencies.nb] version = "0.1.1" diff --git a/ci/install.sh b/ci/install.sh index 642d79a96..3c4192119 100644 --- a/ci/install.sh +++ b/ci/install.sh @@ -1,7 +1,9 @@ set -euxo pipefail main() { - return + if [ $TARGET != x86_64-unknown-linux-gnu ]; then + rustup target add $TARGET + fi } main diff --git a/ci/script.sh b/ci/script.sh index fa48ee096..12c05e27b 100644 --- a/ci/script.sh +++ b/ci/script.sh @@ -2,7 +2,11 @@ set -euxo pipefail main() { cargo check --target $TARGET - cargo test --target $TARGET --features unproven + cargo check --target $TARGET --features unproven + + if [ $TRAVIS_RUST_VERSION = nightly ]; then + cargo test --target $TARGET --features unproven + fi } main diff --git a/src/lib.rs b/src/lib.rs index 6e36046f5..8cefbf06c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -90,19 +90,20 @@ //! [`WouldBlock`]: https://docs.rs/nb/0.1.0/nb/enum.Error.html //! //! Some traits, like the one shown below, may expose possibly blocking APIs that can't fail. In -//! those cases `nb::Result<_, !>` is used. +//! those cases `nb::Result<_, Void>` is used. //! //! ``` -//! #![feature(never_type)] -//! //! extern crate nb; +//! extern crate void; +//! +//! use void::Void; //! //! /// A count down timer //! pub trait CountDown { //! // .. //! //! /// "waits" until the count down is over -//! fn wait(&mut self) -> nb::Result<(), !>; +//! fn wait(&mut self) -> nb::Result<(), Void>; //! } //! //! # fn main() {} @@ -201,7 +202,6 @@ //! fashion: //! //! ``` -//! # #![feature(never_type)] //! extern crate embedded_hal; //! #[macro_use(block)] //! extern crate nb; @@ -223,9 +223,11 @@ //! # } //! //! # mod stm32f30x_hal { +//! # extern crate void; +//! # use self::void::Void; //! # pub struct Serial1; //! # impl Serial1 { -//! # pub fn write(&mut self, _: u8) -> ::nb::Result<(), !> { +//! # pub fn write(&mut self, _: u8) -> ::nb::Result<(), Void> { //! # Ok(()) //! # } //! # } @@ -238,11 +240,9 @@ //! second. Second task: loop back data over the serial interface. //! //! ``` -//! #![feature(conservative_impl_trait)] -//! #![feature(never_type)] -//! //! extern crate embedded_hal as hal; //! extern crate futures; +//! extern crate void; //! //! #[macro_use(try_nb)] //! extern crate nb; @@ -255,11 +255,12 @@ //! }; //! use futures::future::Loop; //! use stm32f30x_hal::{Led, Serial1, Timer6}; +//! use void::Void; //! //! /// `futures` version of `CountDown.wait` //! /// //! /// This returns a future that must be polled to completion -//! fn wait(mut timer: T) -> impl Future +//! fn wait(mut timer: T) -> impl Future //! where //! T: hal::timer::CountDown, //! { @@ -341,30 +342,32 @@ //! //! // Event loop //! loop { -//! blinky.poll().unwrap(); // NOTE(unwrap) E = ! +//! blinky.poll().unwrap(); // NOTE(unwrap) E = Void //! loopback.poll().unwrap(); //! # break; //! } //! } //! //! # mod stm32f30x_hal { +//! # extern crate void; +//! # use self::void::Void; //! # pub struct Timer6; //! # impl ::hal::timer::CountDown for Timer6 { //! # type Time = (); //! # //! # fn start(&mut self, _: T) where T: Into<()> {} -//! # fn wait(&mut self) -> ::nb::Result<(), !> { Err(::nb::Error::WouldBlock) } +//! # fn wait(&mut self) -> ::nb::Result<(), Void> { Err(::nb::Error::WouldBlock) } //! # } //! # //! # pub struct Serial1; //! # impl ::hal::serial::Read for Serial1 { -//! # type Error = !; -//! # fn read(&mut self) -> ::nb::Result { Err(::nb::Error::WouldBlock) } +//! # type Error = Void; +//! # fn read(&mut self) -> ::nb::Result { Err(::nb::Error::WouldBlock) } //! # } //! # impl ::hal::serial::Write for Serial1 { -//! # type Error = !; -//! # fn flush(&mut self) -> ::nb::Result<(), !> { Err(::nb::Error::WouldBlock) } -//! # fn write(&mut self, _: u8) -> ::nb::Result<(), !> { Err(::nb::Error::WouldBlock) } +//! # type Error = Void; +//! # fn flush(&mut self) -> ::nb::Result<(), Void> { Err(::nb::Error::WouldBlock) } +//! # fn write(&mut self, _: u8) -> ::nb::Result<(), Void> { Err(::nb::Error::WouldBlock) } //! # } //! # //! # pub struct Led; @@ -382,7 +385,6 @@ //! ``` //! #![feature(generator_trait)] //! #![feature(generators)] -//! # #![feature(never_type)] //! //! extern crate embedded_hal as hal; //! @@ -415,7 +417,7 @@ //! loop { //! // `await!` means "suspend / yield here" instead of "block until //! // completion" -//! await!(timer.wait()).unwrap(); // NOTE(unwrap) E = ! +//! await!(timer.wait()).unwrap(); // NOTE(unwrap) E = Void //! //! state = !state; //! @@ -436,21 +438,23 @@ //! //! // Event loop //! loop { -//! blinky.resume(); -//! loopback.resume(); +//! unsafe { blinky.resume(); } +//! unsafe { loopback.resume(); } //! # break; //! } //! } //! //! # mod stm32f30x_hal { +//! # extern crate void; +//! # use self::void::Void; //! # pub struct Serial1; //! # impl Serial1 { -//! # pub fn read(&mut self) -> ::nb::Result { Err(::nb::Error::WouldBlock) } -//! # pub fn write(&mut self, _: u8) -> ::nb::Result<(), !> { Err(::nb::Error::WouldBlock) } +//! # pub fn read(&mut self) -> ::nb::Result { Err(::nb::Error::WouldBlock) } +//! # pub fn write(&mut self, _: u8) -> ::nb::Result<(), Void> { Err(::nb::Error::WouldBlock) } //! # } //! # pub struct Timer6; //! # impl Timer6 { -//! # pub fn wait(&mut self) -> ::nb::Result<(), !> { Err(::nb::Error::WouldBlock) } +//! # pub fn wait(&mut self) -> ::nb::Result<(), Void> { Err(::nb::Error::WouldBlock) } //! # } //! # pub struct Led; //! # impl Led { @@ -589,15 +593,16 @@ //! - Buffered serial interface with periodic flushing in interrupt handler //! //! ``` -//! # #![feature(never_type)] //! extern crate embedded_hal as hal; //! extern crate nb; +//! extern crate void; //! //! use hal::prelude::*; +//! use void::Void; //! //! fn flush(serial: &mut S, cb: &mut CircularBuffer) //! where -//! S: hal::serial::Write, +//! S: hal::serial::Write, //! { //! loop { //! if let Some(byte) = cb.peek() { @@ -662,9 +667,9 @@ //! # } //! # struct Serial1; //! # impl ::hal::serial::Write for Serial1 { -//! # type Error = !; -//! # fn write(&mut self, _: u8) -> nb::Result<(), !> { Err(::nb::Error::WouldBlock) } -//! # fn flush(&mut self) -> nb::Result<(), !> { Err(::nb::Error::WouldBlock) } +//! # type Error = Void; +//! # fn write(&mut self, _: u8) -> nb::Result<(), Void> { Err(::nb::Error::WouldBlock) } +//! # fn flush(&mut self) -> nb::Result<(), Void> { Err(::nb::Error::WouldBlock) } //! # } //! # struct CircularBuffer; //! # impl CircularBuffer { @@ -678,11 +683,11 @@ #![deny(missing_docs)] #![deny(warnings)] -#![feature(never_type)] #![no_std] #[macro_use] extern crate nb; +extern crate void; pub mod blocking; pub mod digital; @@ -699,8 +704,6 @@ pub mod timer; /// / events /// /// ``` -/// # #![feature(never_type)] -/// /// extern crate embedded_hal as hal; /// #[macro_use(block)] /// extern crate nb; @@ -723,6 +726,8 @@ pub mod timer; /// println!("Period: {} ms", period); /// } /// +/// # extern crate void; +/// # use void::Void; /// # struct MilliSeconds(u32); /// # trait U32Ext { fn ms(self) -> MilliSeconds; } /// # impl U32Ext for u32 { fn ms(self) -> MilliSeconds { MilliSeconds(self) } } @@ -731,9 +736,9 @@ pub mod timer; /// # impl hal::Capture for Capture1 { /// # type Capture = u16; /// # type Channel = Channel; -/// # type Error = !; +/// # type Error = Void; /// # type Time = MilliSeconds; -/// # fn capture(&mut self, _: Channel) -> ::nb::Result { Ok(0) } +/// # fn capture(&mut self, _: Channel) -> ::nb::Result { Ok(0) } /// # fn disable(&mut self, _: Channel) { unimplemented!() } /// # fn enable(&mut self, _: Channel) { unimplemented!() } /// # fn get_resolution(&self) -> MilliSeconds { unimplemented!() } @@ -908,7 +913,6 @@ pub trait PwmPin { /// You can use this interface to measure the speed of a motor /// /// ``` -/// # #![feature(never_type)] /// extern crate embedded_hal as hal; /// #[macro_use(block)] /// extern crate nb; @@ -935,6 +939,8 @@ pub trait PwmPin { /// println!("Speed: {} pulses per second", speed); /// } /// +/// # extern crate void; +/// # use void::Void; /// # struct Seconds(u32); /// # trait U32Ext { fn s(self) -> Seconds; } /// # impl U32Ext for u32 { fn s(self) -> Seconds { Seconds(self) } } @@ -948,7 +954,7 @@ pub trait PwmPin { /// # impl hal::timer::CountDown for Timer6 { /// # type Time = Seconds; /// # fn start(&mut self, _: T) where T: Into {} -/// # fn wait(&mut self) -> ::nb::Result<(), !> { Ok(()) } +/// # fn wait(&mut self) -> ::nb::Result<(), Void> { Ok(()) } /// # } /// ``` #[cfg(feature = "unproven")] diff --git a/src/timer.rs b/src/timer.rs index c7a31fec6..e793751b5 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -1,6 +1,7 @@ //! Timers use nb; +use void::Void; /// A count down timer /// @@ -17,7 +18,6 @@ use nb; /// You can use this timer to create delays /// /// ``` -/// # #![feature(never_type)] /// extern crate embedded_hal as hal; /// #[macro_use(block)] /// extern crate nb; @@ -40,6 +40,8 @@ use nb; /// Led.off(); /// } /// +/// # extern crate void; +/// # use void::Void; /// # struct Seconds(u32); /// # trait U32Ext { fn s(self) -> Seconds; } /// # impl U32Ext for u32 { fn s(self) -> Seconds { Seconds(self) } } @@ -52,7 +54,7 @@ use nb; /// # impl hal::timer::CountDown for Timer6 { /// # type Time = Seconds; /// # fn start(&mut self, _: T) where T: Into {} -/// # fn wait(&mut self) -> ::nb::Result<(), !> { Ok(()) } +/// # fn wait(&mut self) -> ::nb::Result<(), Void> { Ok(()) } /// # } /// ``` pub trait CountDown { @@ -72,7 +74,7 @@ pub trait CountDown { /// finishes. /// - Otherwise the behavior of calling `wait` after the last call returned `Ok` is UNSPECIFIED. /// Implementers are suggested to panic on this scenario to signal a programmer error. - fn wait(&mut self) -> nb::Result<(), !>; + fn wait(&mut self) -> nb::Result<(), Void>; } /// Marker trait that indicates that a timer is periodic