Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
InnocentusLime opened this issue Apr 16, 2021 · 4 comments

Comments

@InnocentusLime
Copy link

InnocentusLime commented Apr 16, 2021

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.

@Lokathor
Copy link
Owner

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.

@InnocentusLime
Copy link
Author

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

@InnocentusLime
Copy link
Author

InnocentusLime commented Apr 16, 2021

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
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants