Closed
Description
The following program uses a macro (mlet!
) to abstract away the declaration of several variables:
use task::spawn;
fn main() {
macro_rules! mlet(
($($var:ident),+ = $val:expr) => (
let $($var = $val),+;
);
);
let (port, chan) = pipes::stream();
let chan = pipes::SharedChan(chan);
mlet!(s1, s2, s3 = chan.clone());
// The above line expands to the following, which doesn't throw any
// warnings when it's inserted manually rather than generated by the macro:
//let s1 = chan.clone(), s2 = chan.clone(), s3 = chan.clone();
do spawn { s1.send( (|a: int| a*2)(10) ) }
do spawn { s2.send( (|a: int| a*2)(20) ) }
do spawn { s3.send( (|a: int, b: int| a+b)(30, 40) ) }
mlet!(x, y, z = port.recv());
// The above line expands to the following, which doesn't throw any
// warnings when it's inserted manually rather than generated by the macro:
//let x = port.recv(), y = port.recv(), z = port.recv();
io::println(fmt!("%d + %d + %d = %d", x, y, z, x+y+z));
}
When compiling this code, I receive this output:
macro3.rs:6:19: 6:24 warning: value assigned to `s2` is never read
macro3.rs:6 let $($var = $val),+;
^~~~~
macro3.rs:4:4: 8:6 note: in expansion of mlet!
macro3.rs:13:4: 13:37 note: expansion site
macro3.rs:6:19: 6:24 warning: value assigned to `s3` is never read
macro3.rs:6 let $($var = $val),+;
^~~~~
macro3.rs:4:4: 8:6 note: in expansion of mlet!
macro3.rs:13:4: 13:37 note: expansion site
macro3.rs:6:19: 6:24 warning: value assigned to `y` is never read
macro3.rs:6 let $($var = $val),+;
^~~~~
macro3.rs:4:4: 8:6 note: in expansion of mlet!
macro3.rs:21:4: 21:33 note: expansion site
macro3.rs:6:19: 6:24 warning: value assigned to `z` is never read
macro3.rs:6 let $($var = $val),+;
^~~~~
macro3.rs:4:4: 8:6 note: in expansion of mlet!
macro3.rs:21:4: 21:33 note: expansion site
These warnings only appear when using the macros to generate the code. If you run the macro expansion pass (rustc --pretty expanded
) you see that the mlet!
lines turn into the following:
let s1 = chan.clone(), s2 = chan.clone(), s3 = chan.clone();
let x = port.recv(), y = port.recv(), z = port.recv();
Manually replacing the macro lines with these expanded lines does not cause the warnings to be printed upon compilation. Fix the compiler so that these spurious warnings do not occur during macro expansion.
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
catamorphism commentedon Apr 25, 2013
Seems non-critical for 0.7. Nominating for milestone 5 (production-ready).
graydon commentedon May 2, 2013
accepted for production ready
huonw commentedon Jul 23, 2013
Multiple
let
declaration like in the original testcase is deprecated, and the following seems to pass without issue, but it presumably exercises different code paths. I'm leaning towards closing this as out-of-date.bstrie commentedon Jul 23, 2013
In the interest of preserving the original intent of the macro, I've done some horrendous things to recreate it given our new declaration rules:
This does indeed no longer exhibit the bug, so I'm closing it.
Merge pull request rust-lang#4381 from rust-lang/rustup-2025-06-07
Merge pull request rust-lang#4381 from rust-lang/rustup-2025-06-07