diff --git a/CHANGELOG.md b/CHANGELOG.md index 94b745b387..53406faf45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - Re-export `rtic_core::prelude` as `rtic::mutex::prelude` to allow glob imports + Clippy +- Fix all except `must_use` lints from clippy::pedantic - Fix dated migration docs for spawn - Remove obsolete action-rs tool-cache - Force mdBook to return error codes diff --git a/build.rs b/build.rs index e46837f07e..7c518c90d4 100644 --- a/build.rs +++ b/build.rs @@ -4,18 +4,18 @@ fn main() { let target = env::var("TARGET").unwrap(); if version_check::Channel::read().unwrap().is_nightly() { - println!("cargo:rustc-cfg=rustc_is_nightly") + println!("cargo:rustc-cfg=rustc_is_nightly"); } if target.starts_with("thumbv6m") { - println!("cargo:rustc-cfg=armv6m") + println!("cargo:rustc-cfg=armv6m"); } if target.starts_with("thumbv7m") | target.starts_with("thumbv7em") | target.starts_with("thumbv8m") { - println!("cargo:rustc-cfg=armv7m") + println!("cargo:rustc-cfg=armv7m"); } println!("cargo:rerun-if-changed=build.rs"); diff --git a/macros/src/analyze.rs b/macros/src/analyze.rs index 6b26138879..d255b7f5bc 100644 --- a/macros/src/analyze.rs +++ b/macros/src/analyze.rs @@ -34,7 +34,7 @@ pub fn app(analysis: P, app: &App) -> P { // map from priorities to interrupts (holding name and attributes) let interrupts: BTreeMap = priorities .iter() - .cloned() + .copied() .rev() .zip(&app.args.extern_interrupts) .map(|(p, (id, ext))| (p, (id.clone(), ext.clone()))) diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index 100508432d..f5cae34a72 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -20,6 +20,7 @@ mod software_tasks; mod timer_queue; mod util; +#[allow(clippy::too_many_lines)] pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { let mut mod_app = vec![]; let mut mains = vec![]; @@ -142,7 +143,9 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { }) .collect(); - let monotonics = if !monotonic_parts.is_empty() { + let monotonics = if monotonic_parts.is_empty() { + quote!() + } else { quote!( pub use rtic::Monotonic as _; @@ -151,8 +154,6 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { #(#monotonic_parts)* } ) - } else { - quote!() }; let rt_err = util::rt_err_ident(); diff --git a/macros/src/codegen/local_resources_struct.rs b/macros/src/codegen/local_resources_struct.rs index 10bde5fefb..b7eae3f9d3 100644 --- a/macros/src/codegen/local_resources_struct.rs +++ b/macros/src/codegen/local_resources_struct.rs @@ -78,7 +78,7 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2, pub __marker__: core::marker::PhantomData<&'a ()> )); - values.push(quote!(__marker__: core::marker::PhantomData)) + values.push(quote!(__marker__: core::marker::PhantomData)); } } diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 8410b7d75c..fd8137fad4 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -3,6 +3,7 @@ use proc_macro2::TokenStream as TokenStream2; use quote::quote; use rtic_syntax::{ast::App, Context}; +#[allow(clippy::too_many_lines)] pub fn codegen( ctxt: Context, shared_resources_tick: bool, @@ -50,11 +51,7 @@ pub fn codegen( values.push(quote!(core)); } - Context::Idle => {} - - Context::HardwareTask(_) => {} - - Context::SoftwareTask(_) => {} + Context::Idle | Context::HardwareTask(_) | Context::SoftwareTask(_) => {} } // if ctxt.has_locals(app) { @@ -438,7 +435,9 @@ pub fn codegen( } } - if !items.is_empty() { + if items.is_empty() { + quote!() + } else { quote!( #(#items)* @@ -449,7 +448,5 @@ pub fn codegen( #(#module_items)* } ) - } else { - quote!() } } diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs index 8bd3a7ddcf..9531254caf 100644 --- a/macros/src/codegen/post_init.rs +++ b/macros/src/codegen/post_init.rs @@ -48,6 +48,7 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec { // let doc = format!(" RTIC internal: {}:{}", file!(), line!()); // stmts.push(quote!(#[doc = #doc])); + #[allow(clippy::cast_possible_truncation)] let idx = Index { index: i as u32, span: Span::call_site(), diff --git a/macros/src/codegen/pre_init.rs b/macros/src/codegen/pre_init.rs index 7aaf20fc79..91c9991274 100644 --- a/macros/src/codegen/pre_init.rs +++ b/macros/src/codegen/pre_init.rs @@ -41,12 +41,12 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec *priority, - Some(Ownership::CoOwned { priority }) => *priority, + Some(Ownership::Owned { priority } | Ownership::CoOwned { priority }) => *priority, Some(Ownership::Contended { ceiling }) => *ceiling, None => 0, }; @@ -89,9 +88,9 @@ pub fn codegen( cfgs, true, &shared_name, - quote!(#ty), + "e!(#ty), ceiling, - ptr, + &ptr, )); } } diff --git a/macros/src/codegen/shared_resources_struct.rs b/macros/src/codegen/shared_resources_struct.rs index 7ae8d8086e..90cbc1beef 100644 --- a/macros/src/codegen/shared_resources_struct.rs +++ b/macros/src/codegen/shared_resources_struct.rs @@ -35,33 +35,8 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2, let mangled_name = util::static_shared_resource_ident(name); let shared_name = util::need_to_lock_ident(name); - if !res.properties.lock_free { - if access.is_shared() { - lt = Some(quote!('a)); - - fields.push(quote!( - #(#cfgs)* - pub #name: &'a #ty - )); - } else { - // Resource proxy - lt = Some(quote!('a)); - - fields.push(quote!( - #(#cfgs)* - pub #name: shared_resources::#shared_name<'a> - )); - - values.push(quote!( - #(#cfgs)* - #name: shared_resources::#shared_name::new(priority) - - )); - - // continue as the value has been filled, - continue; - } - } else { + if res.properties.lock_free { + // Lock free resources of `idle` and `init` get 'static lifetime let lt = if ctxt.runs_once() { quote!('static) } else { @@ -73,6 +48,30 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2, #(#cfgs)* pub #name: &#lt #mut_ #ty )); + } else if access.is_shared() { + lt = Some(quote!('a)); + + fields.push(quote!( + #(#cfgs)* + pub #name: &'a #ty + )); + } else { + // Resource proxy + lt = Some(quote!('a)); + + fields.push(quote!( + #(#cfgs)* + pub #name: shared_resources::#shared_name<'a> + )); + + values.push(quote!( + #(#cfgs)* + #name: shared_resources::#shared_name::new(priority) + + )); + + // continue as the value has been filled, + continue; } let expr = if access.is_exclusive() { @@ -97,7 +96,7 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2, pub __marker__: core::marker::PhantomData<&'a ()> )); - values.push(quote!(__marker__: core::marker::PhantomData)) + values.push(quote!(__marker__: core::marker::PhantomData)); } } diff --git a/macros/src/codegen/software_tasks.rs b/macros/src/codegen/software_tasks.rs index 0357003f26..77559493bc 100644 --- a/macros/src/codegen/software_tasks.rs +++ b/macros/src/codegen/software_tasks.rs @@ -43,7 +43,7 @@ pub fn codegen( ( quote!(rtic::export::SCFQ<#cap_lit_p1>), quote!(rtic::export::Queue::new()), - Box::new(|| util::link_section_uninit()), + Box::new(|| Some(util::link_section_uninit())), ) }; mod_app.push(quote!( diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index 2a344d256b..32e288c56d 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -5,6 +5,7 @@ use rtic_syntax::ast::App; use crate::{analyze::Analysis, check::Extra, codegen::util}; /// Generates timer queues and timer queue handlers +#[allow(clippy::too_many_lines)] pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec { let mut items = vec![]; diff --git a/macros/src/codegen/util.rs b/macros/src/codegen/util.rs index 46eace4c39..6a07732c34 100644 --- a/macros/src/codegen/util.rs +++ b/macros/src/codegen/util.rs @@ -25,9 +25,9 @@ pub fn impl_mutex( cfgs: &[Attribute], resources_prefix: bool, name: &Ident, - ty: TokenStream2, + ty: &TokenStream2, ceiling: u8, - ptr: TokenStream2, + ptr: &TokenStream2, ) -> TokenStream2 { let (path, priority) = if resources_prefix { (quote!(shared_resources::#name), quote!(self.priority())) @@ -117,11 +117,11 @@ fn link_section_index() -> usize { INDEX.fetch_add(1, Ordering::Relaxed) } -// NOTE `None` means in shared memory -pub fn link_section_uninit() -> Option { +/// Add `link_section` attribute +pub fn link_section_uninit() -> TokenStream2 { let section = format!(".uninit.rtic{}", link_section_index()); - Some(quote!(#[link_section = #section])) + quote!(#[link_section = #section]) } // Regroups the inputs of a task diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 13b6a7c213..2b52601756 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -20,7 +20,10 @@ mod tests; /// Attribute used to declare a RTIC application /// /// For user documentation see the [RTIC book](https://rtic.rs) - +/// +/// # Panics +/// +/// Should never panic, cargo feeds a path which is later converted to a string #[proc_macro_attribute] pub fn app(args: TokenStream, input: TokenStream) -> TokenStream { let mut settings = Settings::default(); @@ -61,7 +64,10 @@ pub fn app(args: TokenStream, input: TokenStream) -> TokenStream { #[cfg(feature = "debugprint")] println!("OUT_DIR\n{:#?}", out_str); - if !out_dir.exists() { + if out_dir.exists() { + #[cfg(feature = "debugprint")] + println!("\ntarget/ exists\n"); + } else { // Set out_dir to OUT_DIR out_dir = Path::new(&out_str); @@ -80,24 +86,19 @@ pub fn app(args: TokenStream, input: TokenStream) -> TokenStream { .to_str() .unwrap() .starts_with(target_triple_prefix) - //|| path.ends_with(&out_dir_root) { if let Some(out) = path.parent() { out_dir = out; #[cfg(feature = "debugprint")] println!("{:#?}\n", out_dir); break; - } else { - // If no parent, just use it - out_dir = path; - break; } + // If no parent, just use it + out_dir = path; + break; } } } - } else { - #[cfg(feature = "debugprint")] - println!("\ntarget/ exists\n"); } // Try to write the expanded code to disk diff --git a/src/export.rs b/src/export.rs index a124c78b3c..838ae8435e 100644 --- a/src/export.rs +++ b/src/export.rs @@ -1,3 +1,4 @@ +#![allow(clippy::inline_always)] use core::{ cell::Cell, sync::atomic::{AtomicBool, Ordering}, @@ -61,7 +62,7 @@ impl Barrier { } pub fn release(&self) { - self.inner.store(true, Ordering::Release) + self.inner.store(true, Ordering::Release); } pub fn wait(&self) { @@ -91,7 +92,7 @@ impl Priority { // These two methods are used by `lock` (see below) but can't be used from the RTIC application #[inline(always)] fn set(&self, value: u8) { - self.inner.set(value) + self.inner.set(value); } /// Get the current priority @@ -160,7 +161,7 @@ pub unsafe fn lock( } /// Lock the resource proxy by setting the PRIMASK -/// and running the closure with interrupt::free +/// and running the closure with ``interrupt::free`` /// /// # Safety /// @@ -188,6 +189,7 @@ pub unsafe fn lock( } #[inline] +#[must_use] pub fn logical2hw(logical: u8, nvic_prio_bits: u8) -> u8 { ((1 << nvic_prio_bits) - logical) << (8 - nvic_prio_bits) } diff --git a/src/lib.rs b/src/lib.rs index 871141f62c..0c0d0cc7dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,6 +36,7 @@ html_favicon_url = "https://raw.githubusercontent.com/rtic-rs/cortex-m-rtic/master/book/en/src/RTIC.svg" )] //deny_warnings_placeholder_for_ci +#![allow(clippy::inline_always)] use cortex_m::{interrupt::InterruptNumber, peripheral::NVIC}; pub use cortex_m_rtic_macros::app; @@ -61,7 +62,7 @@ pub fn pend(interrupt: I) where I: InterruptNumber, { - NVIC::pend(interrupt) + NVIC::pend(interrupt); } use core::cell::UnsafeCell; @@ -72,12 +73,12 @@ use core::cell::UnsafeCell; /// /// Soundness: /// 1) Unsafe API for internal use only -/// 2) get_mut(&self) -> *mut T +/// 2) ``get_mut(&self) -> *mut T`` /// returns a raw mutable pointer to the inner T /// casting to &mut T is under control of RTIC /// RTIC ensures &mut T to be unique under Rust aliasing rules. /// -/// Implementation uses the underlying UnsafeCell +/// Implementation uses the underlying ``UnsafeCell`` /// self.0.get() -> *mut T /// /// 3) get(&self) -> *const T @@ -85,14 +86,14 @@ use core::cell::UnsafeCell; /// casting to &T is under control of RTIC /// RTIC ensures &T to be shared under Rust aliasing rules. /// -/// Implementation uses the underlying UnsafeCell +/// Implementation uses the underlying ``UnsafeCell`` /// self.0.get() -> *mut T, demoted to *const T -/// +/// #[repr(transparent)] pub struct RacyCell(UnsafeCell); impl RacyCell { - /// Create a RacyCell + /// Create a ``RacyCell`` #[inline(always)] pub const fn new(value: T) -> Self { RacyCell(UnsafeCell::new(value)) diff --git a/src/tq.rs b/src/tq.rs index 9033022bcd..0f585ba4dd 100644 --- a/src/tq.rs +++ b/src/tq.rs @@ -17,7 +17,7 @@ where /// # Safety /// /// Writing to memory with a transmute in order to enable - /// interrupts of the SysTick timer + /// interrupts of the ``SysTick`` timer /// /// Enqueue a task without checking if it is full #[inline] @@ -33,11 +33,8 @@ where { // Check if the top contains a non-empty element and if that element is // greater than nr - let if_heap_max_greater_than_nr = self - .0 - .peek() - .map(|head| nr.instant < head.instant) - .unwrap_or(true); + let if_heap_max_greater_than_nr = + self.0.peek().map_or(true, |head| nr.instant < head.instant); if if_heap_max_greater_than_nr { if Mono::DISABLE_INTERRUPT_ON_EMPTY_QUEUE && self.0.is_empty() { @@ -92,7 +89,7 @@ where } } - /// Dequeue a task from the TimerQueue + /// Dequeue a task from the ``TimerQueue`` pub fn dequeue(&mut self, disable_interrupt: F, mono: &mut Mono) -> Option<(Task, u8)> where F: FnOnce(),