Skip to content

Spurious "value assigned is never read" warnings during macro expansion #4381

Closed
@bstrie

Description

@bstrie
Contributor

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.

Activity

catamorphism

catamorphism commented on Apr 25, 2013

@catamorphism
Contributor

Seems non-critical for 0.7. Nominating for milestone 5 (production-ready).

graydon

graydon commented on May 2, 2013

@graydon
Contributor

accepted for production ready

huonw

huonw commented on Jul 23, 2013

@huonw
Member

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.

use std::comm;
fn main() {
    macro_rules! mlet(
        ($($var:ident = $val:expr),*) => (
            let ($($var),*) = ($($val),*);
        );
    );

    let (port, chan) = comm::stream();
    let chan = comm::SharedChan::new(chan);

    mlet!(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 = port.recv(), y = port.recv(), z = port.recv());
    println(fmt!("%d + %d + %d = %d", x, y, z, x + y + z));
}
bstrie

bstrie commented on Jul 23, 2013

@bstrie
ContributorAuthor

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:

use std::comm;
fn main() {
    macro_rules! mlet(
        ($($var:ident),* = $val:expr) => (
            let ($($var),*) = ($({let $var=0; let _ = $var; $val}),*);
        );
    );

    let (port, chan) = comm::stream();
    let chan = comm::SharedChan::new(chan);

    mlet!(s1, s2, 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());
    println(fmt!("%d + %d + %d = %d", x, y, z, x + y + z));
}

This does indeed no longer exhibit the bug, so I'm closing it.

added 2 commits that reference this issue on Jun 9, 2025

Merge pull request rust-lang#4381 from rust-lang/rustup-2025-06-07

0784b5b

Merge pull request rust-lang#4381 from rust-lang/rustup-2025-06-07

31e9806
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.A-syntaxextArea: Syntax extensions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @graydon@catamorphism@bstrie@huonw

        Issue actions

          Spurious "value assigned is never read" warnings during macro expansion · Issue #4381 · rust-lang/rust