array_vec! doesn't seem to work in all cases until you reorder macros' match arms.
The current array_vec macro seems to have problems with some inputs. If you give it the following input
// Somewhere in your codebase
struct T(i32);
impl T {
fn new(x:i32) -> T { T(x) }
}
// Calling the macro
fn main() {
array_vec!(T::new(2));
}
The compilation will terminate with an error saying
Expected type, found
2
This seems to be an issue even in general cases as shown by this example.
As of this writing, I am not sure if this is because of some kind of bug inside rustc or not, so I am opening the issue here for now.
yeah this is some macro rules nonsense stuff for sure.
I'd like to say "we just swap the match arm order", but we do have to be careful here because we could maybe break working code.
what i would like to see as a solution here is a PR with the macros fixed, and also with several test cases added to help codify the macro's intended usage to avoid future weird macro breaks.
Hmm... I think I can write up a PR for that!
Hmmm... Just swapping the rules in the macro around breaks other tests.... Looks like this issue isn't as simple as it seems...
The only thing that works for now is adding a distinct symbol to the "fully explicit" variant, but it's clearly not what we want, since tinyvec is a 1.x.x right now/
It seems Rust can't decide whether T is a type in that context and gets confused for some reason. Here's the tiniest example I could make
struct T(i32);
#[macro_export]
macro_rules! test {
($array_type:ty => $($elem:expr),+ $(,)?) => {};
($($elem:expr),+) => {};
}
fn main() {
test!(T(2));
}
This seems to be very wrong, because T(2) should be an expression and should never be considered as a type... I'll try making an issue.
UPD
rust-lang/rust#84259
So the issue boils down to Rust macros not doing backtracking parsing. It seems the issue was untouched for quite a while, so, I guess we should consider other ways of solving this if this issue needs solving to begin with...