Skip to content

"meta-variable x repeats N times, but y repeats M times" error is confusing #96184

@clarfonthey

Description

@clarfonthey

So, I ran into this when writing up a macro for a project. I'm not really sure what a minimal example would be, but here's some slightly-shorter-than-what-I-wrote code: (playground link)

macro_rules! test_cons {
    (
        $ty:ident {
            array: [$($arr:literal),*],
            $(
                $from:ident: $val:expr,
            )*
        }
    ) => {
        $(
            test_arrays! { ($ty::$from)($val) == [$($arr),*] }
        )*
    }
}

macro_rules! test_arrays {
    (($method:path)($val:expr) == [$($arr:literal),*]) => {
        {
            let x = $method($val);
            assert_eq!(x.to_array(), [$($arr),*], "{}({:?}).to_array() != {:?}", stringify!($method), $val, [$($arr),*]);
        }
    }
}

fn do_test() {
    test_cons! {
        MyTy {
            array: [1, 2, 3],
            from_array: [1, 2, 3],
            from_shorter_array: [1, 2],
        }
    }
}

In case it's not obvious what I'm trying to do here: I want to verify that MyTy::from_array([1, 2, 3]).to_array() == [1, 2, 3] and that MyTy::from_shorter_array([1, 2]).to_array() == [1, 2, 3]. This is shorter than the original macro I wrote, but should be enough to demonstrate the error.

The current output is:

error: meta-variable `from` repeats 2 times, but `arr` repeats 3 times
  [--> src/lib.rs:10:10
](https://play.rust-lang.org/#)   |
10 |           $(
   |  __________^
11 | |             test_arrays! { ($ty::$from)($val) == [$($arr),*] }
12 | |         )*
   | |_________^

That's it. No suggestions for what might be wrong, not even a link to an error code. Just saying that what I wrote is wrong. I tried messing around with metavar expressions as specified in #83527 but I don't know what exactly would would help here.

Basically, I have no idea what exactly the circumstances for this error are, or what I'm doing wrong here, but either way, this error is extremely confusing and could be improved to at least explain what the compiler thinks is happening, and what I could do to fix that.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)D-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions