From 31b392fe3a6961596a0bd4e1bb24c0da2a9b7b42 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 6 Nov 2019 19:05:37 -0500 Subject: [PATCH 1/4] CI: replace compiletest-rs with trybuild We use compiletest to run compile-fail tests but compiletest depends on compiler internals so it breaks every now and then and requires nightly. With trybuild we can also run compile-fail tests but it works on stable and it already has reached version 1.0 --- .cargo/config | 5 +---- .travis.yml | 3 +-- Cargo.toml | 2 +- ci/script.sh | 6 +++--- tests/single.rs | 18 +++--------------- ui/single/exception-invalid.stderr | 3 --- ui/single/exception-systick-used.stderr | 3 --- ui/single/extern-interrupt-not-enough.stderr | 3 --- ui/single/extern-interrupt-used.stderr | 3 --- ui/single/locals-cfg.stderr | 8 ++++++-- ui/single/resources-cfg.stderr | 4 ---- ui/single/task-priority-too-high.stderr | 12 ++++++++---- 12 files changed, 23 insertions(+), 47 deletions(-) diff --git a/.cargo/config b/.cargo/config index 2683610de4..d095766400 100644 --- a/.cargo/config +++ b/.cargo/config @@ -7,7 +7,4 @@ runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semiho [target.'cfg(all(target_arch = "arm", target_os = "none"))'] rustflags = [ "-C", "link-arg=-Tlink.x", -] - -[build] -target = "thumbv7m-none-eabi" \ No newline at end of file +] \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index fa4f46aab4..ac5a7b8ab7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,8 +18,7 @@ matrix: # compile-fail tests - env: TARGET=x86_64-unknown-linux-gnu - # FIXME revert this -- compiletest-rs v0.3.25 is broken with recent nightly - rust: nightly-2019-10-31 + rust: nightly if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master) # heterogeneous multi-core support diff --git a/Cargo.toml b/Cargo.toml index 69d17fea61..6a2dbd9d47 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,7 +67,7 @@ features = ["exit"] version = "0.5.2" [target.x86_64-unknown-linux-gnu.dev-dependencies] -compiletest_rs = "0.3.22" +trybuild = "1" [features] heterogeneous = ["cortex-m-rtfm-macros/heterogeneous", "microamp"] diff --git a/ci/script.sh b/ci/script.sh index 9cb03fcea9..5c898a8668 100644 --- a/ci/script.sh +++ b/ci/script.sh @@ -37,10 +37,10 @@ main() { mkdir -p ci/builds if [ $T = x86_64-unknown-linux-gnu ]; then - if [ $TRAVIS_RUST_VERSION = nightly ]; then - # compile-fail tests - cargo test --test single --target $T + # compile-fail tests + cargo test --test single --target $T + if [ $TRAVIS_RUST_VERSION = nightly ]; then # multi-core compile-pass tests pushd heterogeneous local exs=( diff --git a/tests/single.rs b/tests/single.rs index 01b80312cb..b5d480c7ae 100644 --- a/tests/single.rs +++ b/tests/single.rs @@ -1,19 +1,7 @@ -use std::path::PathBuf; - -use compiletest_rs::{common::Mode, Config}; +use trybuild::TestCases; #[test] fn ui() { - let mut config = Config::default(); - - config.mode = Mode::Ui; - config.src_base = PathBuf::from("ui/single"); - config.target_rustcflags = Some( - "--edition=2018 -L target/debug/deps -Z unstable-options --extern rtfm --extern lm3s6965" - .to_owned(), - ); - config.link_deps(); - config.clean_rmeta(); - - compiletest_rs::run_tests(&config); + let t = TestCases::new(); + t.compile_fail("ui/single/*.rs"); } diff --git a/ui/single/exception-invalid.stderr b/ui/single/exception-invalid.stderr index 306074b095..9021376826 100644 --- a/ui/single/exception-invalid.stderr +++ b/ui/single/exception-invalid.stderr @@ -3,6 +3,3 @@ error: only exceptions with configurable priority can be used as hardware tasks | 6 | fn nmi(_: nmi::Context) {} | ^^^ - -error: aborting due to previous error - diff --git a/ui/single/exception-systick-used.stderr b/ui/single/exception-systick-used.stderr index e2ccbd3b88..23b6dc4a10 100644 --- a/ui/single/exception-systick-used.stderr +++ b/ui/single/exception-systick-used.stderr @@ -3,6 +3,3 @@ error: this exception can't be used because it's being used by the runtime | 6 | fn sys_tick(_: sys_tick::Context) {} | ^^^^^^^^ - -error: aborting due to previous error - diff --git a/ui/single/extern-interrupt-not-enough.stderr b/ui/single/extern-interrupt-not-enough.stderr index 43249c4954..73ce7ad008 100644 --- a/ui/single/extern-interrupt-not-enough.stderr +++ b/ui/single/extern-interrupt-not-enough.stderr @@ -3,6 +3,3 @@ error: not enough `extern` interrupts to dispatch all software tasks (need: 1; g | 6 | fn a(_: a::Context) {} | ^ - -error: aborting due to previous error - diff --git a/ui/single/extern-interrupt-used.stderr b/ui/single/extern-interrupt-used.stderr index 2e084caf1e..fb0ff5bc7c 100644 --- a/ui/single/extern-interrupt-used.stderr +++ b/ui/single/extern-interrupt-used.stderr @@ -3,6 +3,3 @@ error: `extern` interrupts can't be used as hardware tasks | 5 | #[task(binds = UART0)] | ^^^^^ - -error: aborting due to previous error - diff --git a/ui/single/locals-cfg.stderr b/ui/single/locals-cfg.stderr index fc324f139a..bb558fa60e 100644 --- a/ui/single/locals-cfg.stderr +++ b/ui/single/locals-cfg.stderr @@ -28,6 +28,10 @@ error[E0425]: cannot find value `FOO` in this scope 44 | FOO; | ^^^ not found in this scope -error: aborting due to 5 previous errors +error: duplicate lang item in crate `panic_halt`: `panic_impl`. + | + = note: first defined in crate `std`. -For more information about this error, try `rustc --explain E0425`. +error: duplicate lang item in crate `panic_semihosting`: `panic_impl`. + | + = note: first defined in crate `panic_halt`. diff --git a/ui/single/resources-cfg.stderr b/ui/single/resources-cfg.stderr index a745e6e223..c47b95d4b9 100644 --- a/ui/single/resources-cfg.stderr +++ b/ui/single/resources-cfg.stderr @@ -117,7 +117,3 @@ error[E0609]: no field `o5` on type `uart1Resources<'_>` | ^^ unknown field | = note: available fields are: `__marker__` - -error: aborting due to 15 previous errors - -For more information about this error, try `rustc --explain E0609`. diff --git a/ui/single/task-priority-too-high.stderr b/ui/single/task-priority-too-high.stderr index b402a95ca4..0e0b1cb26e 100644 --- a/ui/single/task-priority-too-high.stderr +++ b/ui/single/task-priority-too-high.stderr @@ -1,9 +1,13 @@ +warning: unused import: `rtfm::app` + --> $DIR/task-priority-too-high.rs:3:5 + | +3 | use rtfm::app; + | ^^^^^^^^^ + | + = note: `#[warn(unused_imports)]` on by default + error[E0080]: evaluation of constant value failed --> $DIR/task-priority-too-high.rs:5:1 | 5 | #[rtfm::app(device = lm3s6965)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0080`. From da9c6a714eaa9420694dc6377c6e0167fe08f5d4 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 6 Nov 2019 19:39:57 -0500 Subject: [PATCH 2/4] run cfail tests only when rustc --version == $MSRV this version is more or less fixed so new releases of Rust (stable or nightly channel) are unlikely to break to build due to changes in diagnostic messages --- ci/script.sh | 7 +++++-- ui/single/task-priority-too-high.stderr | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ci/script.sh b/ci/script.sh index 5c898a8668..e87e50a8db 100644 --- a/ci/script.sh +++ b/ci/script.sh @@ -37,8 +37,11 @@ main() { mkdir -p ci/builds if [ $T = x86_64-unknown-linux-gnu ]; then - # compile-fail tests - cargo test --test single --target $T + if [ $TRAVIS_RUST_VERSION == 1.*.* ]; then + # test on a fixed version (MSRV) to avoid problems with changes in rustc diagnostics + # compile-fail tests + cargo test --test single --target $T + fi if [ $TRAVIS_RUST_VERSION = nightly ]; then # multi-core compile-pass tests diff --git a/ui/single/task-priority-too-high.stderr b/ui/single/task-priority-too-high.stderr index 0e0b1cb26e..98b5d657c9 100644 --- a/ui/single/task-priority-too-high.stderr +++ b/ui/single/task-priority-too-high.stderr @@ -4,7 +4,7 @@ warning: unused import: `rtfm::app` 3 | use rtfm::app; | ^^^^^^^^^ | - = note: `#[warn(unused_imports)]` on by default + = note: #[warn(unused_imports)] on by default error[E0080]: evaluation of constant value failed --> $DIR/task-priority-too-high.rs:5:1 From e9a83947bc919487d8566ec0f7348bbe0d9ae8af Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 6 Nov 2019 19:48:02 -0500 Subject: [PATCH 3/4] fix bash comparison --- ci/script.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/script.sh b/ci/script.sh index e87e50a8db..78341e1bba 100644 --- a/ci/script.sh +++ b/ci/script.sh @@ -37,7 +37,7 @@ main() { mkdir -p ci/builds if [ $T = x86_64-unknown-linux-gnu ]; then - if [ $TRAVIS_RUST_VERSION == 1.*.* ]; then + if [[ $TRAVIS_RUST_VERSION == 1.*.* ]]; then # test on a fixed version (MSRV) to avoid problems with changes in rustc diagnostics # compile-fail tests cargo test --test single --target $T From 76e234599f6da0b7ee21b98da80201a3984ee323 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Thu, 7 Nov 2019 14:12:16 +0100 Subject: [PATCH 4/4] Added struct de-structure-ing example in tips & tricks --- book/en/src/by-example/tips.md | 9 +++++++ examples/destructure.rs | 47 ++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 examples/destructure.rs diff --git a/book/en/src/by-example/tips.md b/book/en/src/by-example/tips.md index a0082060a9..b923ed0850 100644 --- a/book/en/src/by-example/tips.md +++ b/book/en/src/by-example/tips.md @@ -165,3 +165,12 @@ crate and print the output to the console. $ # produces the same output as before $ cargo expand --example smallest | tail ``` + +## Resource de-structure-ing + +When having a task taking multiple resources it can help in readability to split +up the resource struct. Here're two examples on how this can be done: + +``` rust +{{#include ../../../../examples/destructure.rs}} +``` diff --git a/examples/destructure.rs b/examples/destructure.rs new file mode 100644 index 0000000000..0cc3c1f1c2 --- /dev/null +++ b/examples/destructure.rs @@ -0,0 +1,47 @@ +//! examples/destructure.rs + +#![deny(unsafe_code)] +#![deny(warnings)] +#![no_main] +#![no_std] + +use cortex_m_semihosting::hprintln; +use lm3s6965::Interrupt; +use panic_semihosting as _; + +#[rtfm::app(device = lm3s6965)] +const APP: () = { + struct Resources { + // Some resources to work with + #[init(0)] + a: u32, + #[init(0)] + b: u32, + #[init(0)] + c: u32, + } + + #[init] + fn init(_: init::Context) { + rtfm::pend(Interrupt::UART0); + rtfm::pend(Interrupt::UART1); + } + + // Direct destructure + #[task(binds = UART0, resources = [a, b, c])] + fn uart0(cx: uart0::Context) { + let a = cx.resources.a; + let b = cx.resources.b; + let c = cx.resources.c; + + hprintln!("UART0: a = {}, b = {}, c = {}", a, b, c).unwrap(); + } + + // De-structure-ing syntax + #[task(binds = UART1, resources = [a, b, c])] + fn uart1(cx: uart1::Context) { + let uart1::Resources { a, b, c } = cx.resources; + + hprintln!("UART0: a = {}, b = {}, c = {}", a, b, c).unwrap(); + } +};