diff options
author | 2018-12-15 16:14:06 +0000 | |
---|---|---|
committer | 2018-12-15 16:14:06 +0000 | |
commit | 0cabf09a7ac11962b57a75e52a6cc0c5aa2709a8 (patch) | |
tree | 8565f0edc28016ea1acc1f14dd63591d21c3fe32 /cortex-m-rt | |
parent | c7e6e5f78203b55b0094bd26d78e17c9c9d155a2 (diff) | |
parent | c69ff66f4c1d353be5d683ca8c131a04e997e4ed (diff) | |
download | cortex-m-0cabf09a7ac11962b57a75e52a6cc0c5aa2709a8.tar.gz cortex-m-0cabf09a7ac11962b57a75e52a6cc0c5aa2709a8.tar.zst cortex-m-0cabf09a7ac11962b57a75e52a6cc0c5aa2709a8.zip |
Merge #159
159: static mut transform: forward `#[cfg]` r=therealprof a=japaric
as reported in japaric/cortex-m-rtfm#110 the following code fails to compile
``` rust
#[entry]
fn main() -> ! {
#[cfg(something)]
static mut FOO: u32 = 0; //~ ERROR cannot find value `FOO` in this scope
}
```
the issue is that the expansion of the static looks like this:
``` rust
let FOO = unsafe {
#[cfg(never)]
static mut FOO: u32 = 0;
&mut FOO
};
```
so when the `#[cfg]` evals to false the static is gone but the `let FOO` is not
removed.
this PR forwards `#[cfg]` attributes to the `let` expression and fixes the error
``` rust
#[cfg(never)] // <- added
let FOO = unsafe {
#[cfg(never)]
static mut FOO: u32 = 0;
&mut FOO
};
```
Co-authored-by: Jorge Aparicio <jorge@japaric.io>
Diffstat (limited to 'cortex-m-rt')
-rw-r--r-- | cortex-m-rt/examples/cfg-static.rs | 25 | ||||
-rw-r--r-- | cortex-m-rt/macros/src/lib.rs | 41 |
2 files changed, 60 insertions, 6 deletions
diff --git a/cortex-m-rt/examples/cfg-static.rs b/cortex-m-rt/examples/cfg-static.rs new file mode 100644 index 0000000..2ffee13 --- /dev/null +++ b/cortex-m-rt/examples/cfg-static.rs @@ -0,0 +1,25 @@ +//! using `#[cfg]` on `static` shouldn't cause compile errors + +#![deny(unsafe_code)] +#![deny(warnings)] +#![no_main] +#![no_std] + +extern crate cortex_m_rt as rt; +extern crate panic_halt; + +use rt::{entry, exception}; + +#[entry] +fn main() -> ! { + #[cfg(never)] + static mut COUNT: u32 = 0; + + loop {} +} + +#[exception] +fn SysTick() { + #[cfg(never)] + static mut FOO: u32 = 0; +} diff --git a/cortex-m-rt/macros/src/lib.rs b/cortex-m-rt/macros/src/lib.rs index 1013f5e..7528586 100644 --- a/cortex-m-rt/macros/src/lib.rs +++ b/cortex-m-rt/macros/src/lib.rs @@ -16,8 +16,8 @@ use std::collections::HashSet; use std::sync::atomic::{AtomicUsize, Ordering}; use std::time::{SystemTime, UNIX_EPOCH}; use syn::{ - parse, spanned::Spanned, FnArg, Ident, Item, ItemFn, ItemStatic, ReturnType, Stmt, Type, - Visibility, + parse, spanned::Spanned, AttrStyle, Attribute, FnArg, Ident, Item, ItemFn, ItemStatic, + PathArguments, ReturnType, Stmt, Type, Visibility, }; static CALL_COUNT: AtomicUsize = AtomicUsize::new(0); @@ -128,15 +128,17 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream { let vars = statics .into_iter() .map(|var| { - let attrs = var.attrs; + let (ref cfgs, ref attrs) = extract_cfgs(var.attrs); let ident = var.ident; let ty = var.ty; let expr = var.expr; quote!( #[allow(non_snake_case)] + #(#cfgs)* let #ident: &'static mut #ty = unsafe { #(#attrs)* + #(#cfgs)* static mut #ident: #ty = #expr; &mut #ident @@ -405,7 +407,6 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { // further type check of the input argument let #pat: &cortex_m_rt::ExceptionFrame = #pat; - #(#stmts)* } ) @@ -446,15 +447,17 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { let vars = statics .into_iter() .map(|var| { - let attrs = var.attrs; + let (ref cfgs, ref attrs) = extract_cfgs(var.attrs); let ident = var.ident; let ty = var.ty; let expr = var.expr; quote!( #[allow(non_snake_case)] + #(#cfgs)* let #ident: &mut #ty = unsafe { #(#attrs)* + #(#cfgs)* static mut #ident: #ty = #expr; &mut #ident @@ -603,15 +606,17 @@ pub fn interrupt(args: TokenStream, input: TokenStream) -> TokenStream { let vars = statics .into_iter() .map(|var| { - let attrs = var.attrs; + let (ref cfgs, ref attrs) = extract_cfgs(var.attrs); let ident = var.ident; let ty = var.ty; let expr = var.expr; quote!( #[allow(non_snake_case)] + #(#cfgs)* let #ident: &mut #ty = unsafe { #(#attrs)* + #(#cfgs)* static mut #ident: #ty = #expr; &mut #ident @@ -776,3 +781,27 @@ fn extract_static_muts(stmts: Vec<Stmt>) -> Result<(Vec<ItemStatic>, Vec<Stmt>), Ok((statics, stmts)) } + +fn extract_cfgs(attrs: Vec<Attribute>) -> (Vec<Attribute>, Vec<Attribute>) { + let mut cfgs = vec![]; + let mut not_cfgs = vec![]; + + for attr in attrs { + if eq(&attr, "cfg") { + cfgs.push(attr); + } else { + not_cfgs.push(attr); + } + } + + (cfgs, not_cfgs) +} + +/// Returns `true` if `attr.path` matches `name` +fn eq(attr: &Attribute, name: &str) -> bool { + attr.style == AttrStyle::Outer && attr.path.segments.len() == 1 && { + let pair = attr.path.segments.first().unwrap(); + let segment = pair.value(); + segment.arguments == PathArguments::None && segment.ident.to_string() == name + } +} |