diff --git a/macros/src/trans.rs b/macros/src/trans.rs index 4d51840f98..ef224c1921 100644 --- a/macros/src/trans.rs +++ b/macros/src/trans.rs @@ -50,8 +50,8 @@ fn idle( .iter() .all(|resource| ownerships[resource].is_owned()) { - tys.push(quote!(#krate::Threshold)); - exprs.push(quote!(unsafe { #krate::Threshold::new(0) })); + tys.push(quote!(&mut #krate::Threshold)); + exprs.push(quote!(unsafe { &mut #krate::Threshold::new(0) })); } if !app.idle.locals.is_empty() { diff --git a/src/lib.rs b/src/lib.rs index c1c7c8f74e..a4cfbec870 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -221,10 +221,10 @@ macro_rules! task { #[allow(non_snake_case)] #[no_mangle] pub unsafe extern "C" fn $NAME() { - let f: fn($crate::Threshold, ::$NAME::Resources) = $body; + let f: fn(&mut $crate::Threshold, ::$NAME::Resources) = $body; f( - $crate::Threshold::new(::$NAME::$NAME), + &mut $crate::Threshold::new(::$NAME::$NAME), ::$NAME::Resources::new(), ); } @@ -240,7 +240,7 @@ macro_rules! task { #[no_mangle] pub unsafe extern "C" fn $NAME() { let f: fn( - $crate::Threshold, + &mut $crate::Threshold, &mut $local, ::$NAME::Resources, ) = $body; @@ -250,7 +250,7 @@ macro_rules! task { }; f( - $crate::Threshold::new(::$NAME::$NAME), + &mut $crate::Threshold::new(::$NAME::$NAME), &mut LOCAL, ::$NAME::Resources::new(), ); diff --git a/tests/cfail/duplicated-handler.rs b/tests/cfail/duplicated-handler.rs index cae5d8a5e8..dc90204115 100644 --- a/tests/cfail/duplicated-handler.rs +++ b/tests/cfail/duplicated-handler.rs @@ -28,8 +28,8 @@ fn idle() -> ! { task!(EXTI0, exti0); -fn exti0(_t: Threshold, _r: EXTI0::Resources) {} +fn exti0(_t: &mut Threshold, _r: EXTI0::Resources) {} task!(EXTI0, exti1); -fn exti1(_t: Threshold, _r: EXTI0::Resources) {} +fn exti1(_t: &mut Threshold, _r: EXTI0::Resources) {} diff --git a/tests/cfail/local-token.rs b/tests/cfail/local-token.rs new file mode 100644 index 0000000000..4c98956bf0 --- /dev/null +++ b/tests/cfail/local-token.rs @@ -0,0 +1,44 @@ +#![deny(warnings)] +#![feature(const_fn)] +#![feature(proc_macro)] + +#[macro_use(task)] +extern crate cortex_m_rtfm as rtfm; +extern crate stm32f103xx; + +use rtfm::{app, Threshold}; + +app! { + device: stm32f103xx, + + tasks: { + EXTI0: { + enabled: true, + priority: 1, + }, + } +} + +fn init(_p: init::Peripherals) {} + +fn idle() -> ! { + loop {} +} + +task!(EXTI0, exti0, Old { + token: Option = None; +}); + +fn exti0(nt: &mut Threshold, old: &mut Old, _r: EXTI0::Resources) { + if let Some(ot) = old.token.take() { + let _: (Threshold, Threshold) = (*nt, ot); + //~^ error cannot move out of borrowed content + + return + } + + // ERROR can't store a threshold token in a local variable, otherwise you + // would end up with two threshold tokens in a task (see `if let` above) + old.token = Some(*nt); + //~^ error cannot move out of borrowed content +} diff --git a/tests/cfail/lock.rs b/tests/cfail/lock.rs index f93b79aa11..736027e221 100644 --- a/tests/cfail/lock.rs +++ b/tests/cfail/lock.rs @@ -45,7 +45,7 @@ fn idle() -> ! { task!(EXTI0, exti0); -fn exti0(mut t: Threshold, r: EXTI0::Resources) { +fn exti0(mut t: &mut Threshold, r: EXTI0::Resources) { // OK need to lock to access the resource if r.STATE.claim(&mut t, |state, _| **state) {} @@ -55,7 +55,7 @@ fn exti0(mut t: Threshold, r: EXTI0::Resources) { task!(EXTI1, exti1); -fn exti1(mut t: Threshold, r: EXTI1::Resources) { +fn exti1(mut t: &mut Threshold, r: EXTI1::Resources) { // ERROR no need to lock. Has direct access because priority == ceiling if r.STATE.claim(&mut t, |state, _| **state) { //~^ error no method named `claim` found for type diff --git a/tests/cfail/priority-too-high.rs b/tests/cfail/priority-too-high.rs index ac3a7043a6..c76b7a6b68 100644 --- a/tests/cfail/priority-too-high.rs +++ b/tests/cfail/priority-too-high.rs @@ -26,4 +26,4 @@ fn idle() -> ! { task!(SYS_TICK, sys_tick); -fn sys_tick(_: Threshold, _: SYS_TICK::Resources) {} +fn sys_tick(_: &mut Threshold, _: SYS_TICK::Resources) {} diff --git a/tests/cfail/priority-too-low.rs b/tests/cfail/priority-too-low.rs index 8bb080171b..1e0c8e92be 100644 --- a/tests/cfail/priority-too-low.rs +++ b/tests/cfail/priority-too-low.rs @@ -26,4 +26,4 @@ fn idle() -> ! { task!(SYS_TICK, sys_tick); -fn sys_tick(_: Threshold, _: SYS_TICK::Resources) {} +fn sys_tick(_: &mut Threshold, _: SYS_TICK::Resources) {} diff --git a/tests/cfail/token-outlive.rs b/tests/cfail/token-outlive.rs index 9bcd288260..93d1c604f9 100644 --- a/tests/cfail/token-outlive.rs +++ b/tests/cfail/token-outlive.rs @@ -38,7 +38,7 @@ fn idle() -> ! { task!(EXTI0, exti0); -fn exti0(mut t: Threshold, r: EXTI0::Resources) { +fn exti0(mut t: &mut Threshold, r: EXTI0::Resources) { // ERROR token should not outlive the critical section let t = r.STATE.claim(&mut t, |_state, t| t); //~^ error cannot infer an appropriate lifetime @@ -46,4 +46,4 @@ fn exti0(mut t: Threshold, r: EXTI0::Resources) { task!(EXTI1, exti1); -fn exti1(_t: Threshold, _r: EXTI1::Resources) {} +fn exti1(_t: &mut Threshold, _r: EXTI1::Resources) {} diff --git a/tests/cfail/token-transfer.rs b/tests/cfail/token-transfer.rs index e517a6bf49..91e74bdf38 100644 --- a/tests/cfail/token-transfer.rs +++ b/tests/cfail/token-transfer.rs @@ -32,4 +32,4 @@ fn idle() -> ! { task!(EXTI0, exti0); -fn exti0(_t: Threshold, _r: EXTI0::Resources) {} +fn exti0(_t: &mut Threshold, _r: EXTI0::Resources) {} diff --git a/tests/cfail/wrong-threshold.rs b/tests/cfail/wrong-threshold.rs index af8bb05d73..39d3a57b52 100644 --- a/tests/cfail/wrong-threshold.rs +++ b/tests/cfail/wrong-threshold.rs @@ -39,7 +39,7 @@ fn idle() -> ! { task!(EXTI0, exti0); -fn exti0(mut ot: Threshold, r: EXTI0::Resources) { +fn exti0(mut ot: &mut Threshold, r: EXTI0::Resources) { r.A.claim(&mut ot, |_a, mut _it| { //~^ error cannot borrow `ot` as mutable more than once at a time //~| error cannot borrow `ot` as mutable more than once at a time @@ -50,4 +50,4 @@ fn exti0(mut ot: Threshold, r: EXTI0::Resources) { task!(EXTI1, exti1); -fn exti1(_t: Threshold, r: EXTI1::Resources) {} +fn exti1(_t: &mut Threshold, r: EXTI1::Resources) {}