Local variables 'mask', 'offset' shadowed in macros
Closed this issue · 3 comments
A variable named mask
or offset
is shadowed by the imports within the modify_reg!
and write_reg!
macros:
let mask = 6;
ral::write_reg!(self, ®ister_block, register, field_foo: mask);
This results in the following compiler warning:
warning: unused variable: `mask`
--> tests/macros.rs:87:9
|
87 | let mask = 6;
| ^^^^ help: if this is intentional, prefix it with an underscore: `_mask`
Ah, nice catch. Is there a general solution here? We can name the interior variables something like __mask
instead, but of course it could still shadow an outer scope variable.
Using { use $periph::{$reg::$field::mask}; mask }
instead of mask
solved the problem for me.
A unique name for each constant was my first approach, though I do like using module-qualified constants. Either way works for me.
I'm also not sure of a general solution. Though this issue is only focused on two variable names, we can also demonstrate the shadowing by selecting a symbol imported by the globs, like RW::*
. I might not expect this kind of usage in real-world code, so relying on compiler warnings seems reasonable.
use stm32ral as stm32;
use ral_registers as ral;
const Input: u32 = 42; // Same name as a constant, 'Input', imported via glob.
let gpioa = gpio::GPIOA::take().unwrap();
ral::modify_reg!(stm32::gpio, gpioa, MODER, MODER1: Input);
warning: constant is never used: `Input`
--> tests/macros.rs:112:5
|
112 | const Input: u32 = 42;
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(dead_code)]` on by default
(First attempt: since each macro defines a new scope, and it seems each scope can re-define the same function, I thought about an immediately-invoked #[inline(always)]
function that could keep the scopes separate. I couldn't figure out the syntax, particularly when dealing with variable field-value inputs. Curious to know if / how codegen would work.)