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

ICE when forwarding macro $args:tt #45733

Closed
Boscop opened this issue Nov 3, 2017 · 5 comments
Closed

ICE when forwarding macro $args:tt #45733

Boscop opened this issue Nov 3, 2017 · 5 comments
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@Boscop
Copy link

Boscop commented Nov 3, 2017

I wanted to write a macro wrapper around another macro so that I don't have to pass the stringified 2nd arg manually:

macro_rules! gen_orm {
	($name:ident, $table:ident, $table_name:expr, {$($field:ident: $type:ty,)+}) => (
...

macro_rules! gen_orm2 {
	($name:ident, $table:ident, {$($field:ident: $type:ty,)+}) => (
		gen_orm!($name, $table, stringify!($table), {$($field:ident: $type:ty,)+});
		// error: no rules expected the token `:`                 -^-
	)
}

But I got the above error:

no rules expected the token :

But it works when I call gen_orm manually:
gen_orm!(Foo, foos, "foos", { meow: i32, percent: i32, });

So then I tried rewriting it into this:

macro_rules! gen_orm2 {
	($name:ident, $table:ident, $args:tt) => (
		gen_orm!($name, $table, stringify!($table), $args);
	)
}

so that it just forwards the args after the 2nd arg.

But lo and behold, rustc decided to ice on me:

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.22.0-nightly (325ba23d5 2017-09-19) running on x86_64-pc-windows-msvc

note: run with `RUST_BACKTRACE=1` for a backtrace

thread 'rustc' panicked at 'no entry found for key', src\libcore\option.rs:839:4
stack backtrace:
   0: _rdl_shrink_in_place
   1: std::panicking::Location::column
   2: std::panicking::Location::column
   3: std::panicking::rust_panic_with_hook
   4: std::panicking::begin_panic_fmt
   5: std::panicking::begin_panic_fmt
   6: rust_begin_unwind
   7: core::panicking::panic_fmt
   8: core::option::expect_failed
   9: rustc_resolve::macros::<impl syntax::ext::base::Resolver for rustc_resolve::Resolver<'a>>::check_unused_macros
  10: rustc_resolve::macros::<impl syntax::ext::base::Resolver for rustc_resolve::Resolver<'a>>::resolve_invoc
  11: syntax::ext::expand::MacroExpander::expand_crate
  12: syntax::ext::expand::MacroExpander::expand_crate
  13: rustc_driver::driver::count_nodes
  14: rustc_driver::driver::count_nodes
  15: rustc_driver::driver::compile_input
  16: rustc_driver::run_compiler
  17: <unknown>
  18: _rust_maybe_catch_panic
  19: <rustc_driver::derive_registrar::Finder as rustc::hir::itemlikevisit::ItemLikeVisitor<'v>>::visit_trait_item
  20: std::sys::imp::thread::Thread::new
  21: BaseThreadInitThunk

What's the correct way to achieve what I want (not having to write the stringified 2nd arg manually by forwarding)?

And why did it complain about : in the first place, when there is clearly a rule matching that?

I also get the ICE with:

macro_rules! gen_orm2 {
	($name:ident, $table:ident, $($args:tt)+) => (
		gen_orm!($name, $table, stringify!($table), $($args)+);
	)
}
@kennytm
Copy link
Member

kennytm commented Nov 3, 2017

rustc 1.22.0-nightly (325ba23 2017-09-19)

Hi, could you

  1. Run rustup update to get the latest nightly (the version should be 1.23), and
  2. Post the source file that causes the ICE, if it still persists after updating?

Thanks!

@kennytm kennytm added A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ labels Nov 3, 2017
@Boscop
Copy link
Author

Boscop commented Nov 3, 2017

Ah, I had a syntax error in the above code, I had :ident and :ty in the expansion -.-

But it should work with this:

macro_rules! gen_orm2 {
	($name:ident, $table:ident, {$($field:ident: $type:ty,)+}) => (
		gen_orm!($name, $table, stringify!($table), {$($field: $type,)+});
	)
}

But I still get the ICE with this.

@kennytm
Copy link
Member

kennytm commented Nov 3, 2017

Not reproducible, could please you post a complete example?

// Works fine in playground.

macro_rules! gen_orm {
	($name:ident, $table:ident, $table_name:expr, {$($field:ident: $type:ty,)+}) => ()
}

macro_rules! gen_orm2 {
	($name:ident, $table:ident, {$($field:ident: $type:ty,)+}) => (
		gen_orm!($name, $table, stringify!($table), {$($field: $type,)+});
	)
}

fn main() {
    gen_orm2!(Foo, foos, { meow: i32, percent: i32, });
}

@Boscop
Copy link
Author

Boscop commented Nov 3, 2017

Ah, thanks. After I updated my nightly it works now :)

But then I get another error because inside gen_orm I'm doing #[derive(Queryable, Identifiable, Associations)] #[table_name = $table_name] on a struct (for diesel), but it gets expanded to #[table_name = stringify!(foos)] so I get:

error: proc-macro derive panicked
message: called Result::unwrap() on an Err value: "failed to parse derive input: "#[table_name = stringify!(foos)]\npub struct Model {...

How can I stringify!() eagerly before it is passed on?

@Boscop Boscop closed this as completed Nov 3, 2017
@kennytm
Copy link
Member

kennytm commented Nov 3, 2017

@Boscop

How can I stringify!() eagerly before it is passed on?

Unfortunately no, that would require rust-lang/rfcs#1628.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
Development

No branches or pull requests

2 participants