2

I am writing a Rust implementation of Lua, and I came to a point where I had a bunch of function definitions which were more or less the same thing over and over again. I decided to try my luck at writing a macro to do the work for me:

#![feature(macros_in_extern)]
#![feature(concat_idents)]

macro_rules! lua_func {
    ($name: ident, $ret: ty, $var: ident, $type: ty) => {
        let fn_name = concat_idents!(lua_, $name);
        pub fn fn_name (L: *mut lua_State, $var: $type) -> $ret
    };
}

extern "C" {
    lua_func!(toboolean, bool, idx, int);
}

When I do this

lua_func!(toboolean, bool, idx, int);

I expect it to expand to

pub fn lua_toboolean (L: *mut lua_State, idx: int) -> bool;

but running rustc --pretty expanded to test it empties my computer's RAM in a few seconds if I don't immediately do a ^C.

I say that this macro is the cause of the problem because when I removed the usage of the macro, the command ran successfully and outputted the text with all macros expanded.

What am I doing wrong?

rustc --version --verbose output:

rustc 1.30.0-nightly (3bc2ca7e4 2018-09-20)
binary: rustc
commit-hash: 3bc2ca7e4f8507f82a4c357ee19300166bcd8099
commit-date: 2018-09-20
host: x86_64-unknown-linux-gnu
release: 1.30.0-nightly
LLVM version: 8.0

With this version, the command rustc --pretty expanded -Z unstable-options with the MCVE file reproduces the problem on my computer.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Warpspeed SCP
  • 154
  • 2
  • 17
  • Your `concat_idents` won't work. [Is it possible to declare variables procedurally using Rust macros?](https://stackoverflow.com/q/23061702/155423) – Shepmaster Sep 21 '18 at 15:51
  • 3
    I suspect there may be some (mutually) recursive macro elsewhere in the code, while this declaration is not what is (directly) triggering the problem. – 9000 Sep 21 '18 at 15:56
  • *rustc version 1.30 (nightly)* — there are *many* nightlies with that version string. Please run `rustc --version --verbose` to get the complete identifier. – Shepmaster Sep 21 '18 at 16:27
  • 2
    *I was in a hurry to type the question out, hence the lack of all the details* — please note for next time that being in a hurry didn't help you, and in fact probably make things take longer. – Shepmaster Sep 21 '18 at 16:32
  • 2
    I can reproduce this. Considering that removing the `extern` block causes a compiler error, this seems to be a bug with `macros_in_extern`. You should report it as such. – Shepmaster Sep 21 '18 at 16:32
  • 1
    did so- [#54441](https://github.com/rust-lang/rust/issues/54441) – Warpspeed SCP Sep 21 '18 at 16:48

1 Answers1

2

This was a compiler bug: rust-lang/rust#54441. It is fixed as of Rust 1.31 and in nightlies newer than 1.31.0-nightly 4efdc04a5 2018-10-06.

dtolnay
  • 9,621
  • 5
  • 41
  • 62