tinyvec icon indicating copy to clipboard operation
tinyvec copied to clipboard

array_vec! doesn't seem to work in all cases until you reorder macros' match arms.

Open InnocentusLime opened this issue 5 years ago • 4 comments

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.

InnocentusLime avatar Apr 16 '21 16:04 InnocentusLime

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.

Lokathor avatar Apr 16 '21 17:04 Lokathor

Hmm... I think I can write up a PR for that!

InnocentusLime avatar Apr 16 '21 17:04 InnocentusLime

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

InnocentusLime avatar Apr 16 '21 19:04 InnocentusLime

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...

InnocentusLime avatar Apr 17 '21 18:04 InnocentusLime