diff --git a/.travis.yml b/.travis.yml index 6a08f1279..fe2effe23 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,5 @@ addons: script: - rustup target add thumbv6m-none-eabi + - cargo test --verbose --features="compiletest" - ./scripts/build-examples.sh - - cargo test --verbose - -cache: cargo diff --git a/Cargo.toml b/Cargo.toml index 12915cb8e..73090a15e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,9 @@ embedded-hal = { version = "0.2", features = ["unproven"] } lpc82x = "0.4" nb = "0.1.1" void = { version = "1", default-features = false } +# This should be in [dev-dependencies], but those can't be optional. Issue: +# https://github.com/rust-lang/cargo/issues/1596 +compiletest_rs = { version = "0.3", optional = true } [dev-dependencies] cortex-m-rt = "0.5" @@ -30,7 +33,10 @@ panic-abort = "0.2" [features] -rt = ["lpc82x/rt"] +# This is needed to make the compiletest stuff optional. It requires std, which +# means we can't build it together with the examples. +compiletest = ["compiletest_rs"] +rt = ["lpc82x/rt"] [[example]] diff --git a/src/swm.rs b/src/swm.rs index 86b99df95..56f1b5f71 100644 --- a/src/swm.rs +++ b/src/swm.rs @@ -690,7 +690,7 @@ impl UnassignFunction for Pin> where T: PinTrait, - F: FunctionTrait, + F: FunctionTrait, { type Unassigned = Pin>; diff --git a/tests/compile-fail/swm/assign-function-to-multiple-pins.rs b/tests/compile-fail/swm/assign-function-to-multiple-pins.rs new file mode 100644 index 000000000..4a10651aa --- /dev/null +++ b/tests/compile-fail/swm/assign-function-to-multiple-pins.rs @@ -0,0 +1,27 @@ +extern crate lpc82x_hal; + + +use lpc82x_hal::Peripherals; +use lpc82x_hal::swm::{ + self, + pin_state, + Pin, +}; + + +fn main() { + let mut p = Peripherals::take().unwrap(); + + let swm = p.swm.split(); + let mut syscon = p.syscon.split(); + + let pio0_0: Pin<_, pin_state::Unused> = swm.pins.pio0_0; + let pio0_1: Pin<_, pin_state::Unused> = swm.pins.pio0_1; + + let u0_rxd: swm::Function<_, swm::state::Unassigned> = + swm.movable_functions.u0_rxd; + + let (u0_rxd, _) = u0_rxd.assign(pio0_0.into_swm_pin(), &mut swm.handle); + let (u0_rxd, _) = u0_rxd.assign(pio0_1.into_swm_pin(), &mut swm.handle); + //~^ ERROR no method named `assign` found for type +} diff --git a/tests/compile-fail/swm/assign-multiple-output-functions.rs b/tests/compile-fail/swm/assign-multiple-output-functions.rs new file mode 100644 index 000000000..4591cfb6e --- /dev/null +++ b/tests/compile-fail/swm/assign-multiple-output-functions.rs @@ -0,0 +1,38 @@ +extern crate lpc82x_hal; + + +use lpc82x_hal::Peripherals; +use lpc82x_hal::swm::{ + self, + pin_state, + Pin, +}; + + +fn main() { + let mut p = Peripherals::take().unwrap(); + + let swm = p.swm.split(); + let mut syscon = p.syscon.split(); + + let pio0_0: Pin<_, pin_state::Unused> = swm.pins.pio0_0; + + let u0_rxd: swm::Function<_, swm::state::Unassigned> = + swm.movable_functions.u0_rxd; + let u0_txd: swm::Function<_, swm::state::Unassigned> = + swm.movable_functions.u0_txd; + let u1_rxd: swm::Function<_, swm::state::Unassigned> = + swm.movable_functions.u1_rxd; + let u1_txd: swm::Function<_, swm::state::Unassigned> = + swm.movable_functions.u1_txd; + + let (u0_rxd, pio0_0) = + u0_rxd.assign(pio0_0.into_swm_pin(), &mut swm.handle); + let (u1_rxd, pio0_0) = + u1_rxd.assign(pio0_0, &mut swm.handle); + let (u0_txd, pio0_0) = + u0_txd.assign(pio0_0, &mut swm.handle); + let (u1_txd, pio0_0) = + u1_txd.assign(pio0_0, &mut swm.handle); + //~^ ERROR the trait bound +} diff --git a/tests/compile-fail/swm/unassign-function-from-wrong-pin.rs b/tests/compile-fail/swm/unassign-function-from-wrong-pin.rs new file mode 100644 index 000000000..d8095c986 --- /dev/null +++ b/tests/compile-fail/swm/unassign-function-from-wrong-pin.rs @@ -0,0 +1,27 @@ +extern crate lpc82x_hal; + + +use lpc82x_hal::Peripherals; +use lpc82x_hal::swm::{ + self, + pin_state, + Pin, +}; + + +fn main() { + let mut p = Peripherals::take().unwrap(); + + let swm = p.swm.split(); + let mut syscon = p.syscon.split(); + + let pio0_0: Pin<_, pin_state::Unused> = swm.pins.pio0_0; + let pio0_1: Pin<_, pin_state::Unused> = swm.pins.pio0_1; + + let u0_rxd: swm::Function<_, swm::state::Unassigned> = + swm.movable_functions.u0_rxd; + + let (u0_rxd, _) = u0_rxd.assign(pio0_0.into_swm_pin(), &mut swm.handle); + let (u0_rxd, _) = u0_rxd.unassign(pio0_1.into_swm_pin(), &mut swm.handle); + //~^ ERROR mismatched types [E0308] +} diff --git a/tests/compile-fail/swm/unassign-unassigned-input-function.rs b/tests/compile-fail/swm/unassign-unassigned-input-function.rs new file mode 100644 index 000000000..e2d80291a --- /dev/null +++ b/tests/compile-fail/swm/unassign-unassigned-input-function.rs @@ -0,0 +1,30 @@ +extern crate lpc82x_hal; + + +use lpc82x_hal::Peripherals; +use lpc82x_hal::swm::{ + self, + pin_state, + Pin, +}; + + +fn main() { + let mut p = Peripherals::take().unwrap(); + + let swm = p.swm.split(); + let mut syscon = p.syscon.split(); + + let pio0_0: Pin<_, pin_state::Unused> = swm.pins.pio0_0; + + let u0_rxd: swm::Function<_, swm::state::Unassigned> = + swm.movable_functions.u0_rxd; + + let (u0_rxd, pio0_0) = + u0_rxd.assign(pio0_0.into_swm_pin(), &mut swm.handle); + let (u0_rxd, pio0_0) = + u0_rxd.unassign(pio0_0, &mut swm.handle); + let (u0_rxd, pio0_0) = + u0_rxd.unassign(pio0_0, &mut swm.handle); + //~^ ERROR no method named `unassign` found for type +} diff --git a/tests/compile-fail/swm/unassign-unassigned-output-function.rs b/tests/compile-fail/swm/unassign-unassigned-output-function.rs new file mode 100644 index 000000000..48f25bf44 --- /dev/null +++ b/tests/compile-fail/swm/unassign-unassigned-output-function.rs @@ -0,0 +1,30 @@ +extern crate lpc82x_hal; + + +use lpc82x_hal::Peripherals; +use lpc82x_hal::swm::{ + self, + pin_state, + Pin, +}; + + +fn main() { + let mut p = Peripherals::take().unwrap(); + + let swm = p.swm.split(); + let mut syscon = p.syscon.split(); + + let pio0_0: Pin<_, pin_state::Unused> = swm.pins.pio0_0; + + let u0_txd: swm::Function<_, swm::state::Unassigned> = + swm.movable_functions.u0_txd; + + let (u0_txd, pio0_0) = + u0_txd.assign(pio0_0.into_swm_pin(), &mut swm.handle); + let (u0_txd, pio0_0) = + u0_txd.unassign(pio0_0, &mut swm.handle); + let (u0_txd, pio0_0) = + u0_txd.unassign(pio0_0, &mut swm.handle); + //~^ ERROR no method named `unassign` found for type +} diff --git a/tests/compiletest.rs b/tests/compiletest.rs new file mode 100644 index 000000000..7dac77a21 --- /dev/null +++ b/tests/compiletest.rs @@ -0,0 +1,28 @@ +#![cfg(feature = "compiletest")] + + +extern crate compiletest_rs as compiletest; + + +use std::path::PathBuf; + + +#[test] +fn compile_test() { + run_mode("compile-fail"); +} + +fn run_mode(mode: &'static str) { + let mut config = compiletest::Config::default(); + + config.mode = mode.parse().expect("Failed to parse mode"); + config.src_base = PathBuf::from(format!("tests/{}", mode)); + + // Needed by the compiler to find other crates + config.link_deps(); + + // Fixes E0464, "multiple matching crates" + config.clean_rmeta(); + + compiletest::run_tests(&config); +}