Closed
Description
We encountered an issue that starting with nightly-2025-02-23, the async-usercalls
crate fails to compile. We managed to come up with a minimal working run-make test, and found that the issue was introduced by commit 76b04437be91069260c72a6d59d130a4e127a9a8
as part of #133436.
Code
See this branch for a run-make test. Starting from nightly-2025-02-23
this fails with:
error: no rules expected `ty` metavariable
--> two/src/main.rs:9:13
|
4 | macro_rules! type_matcher {
| ------------------------- when calling this macro
...
9 | let _x: call_with_type!(type_matcher) = 42;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no rules expected this token in macro call
|
note: while trying to match `u64`
--> two/src/main.rs:5:6
|
5 | (u64) => { u64 };
| ^^^
= note: captured metavariables except for `:tt`, `:ident` and `:lifetime` cannot be compared to other tokens
= note: see <https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment> for more information
= help: try using `:tt` instead in the macro definition
= note: this error originates in the macro `call_with_type` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0308]: mismatched types
--> two/src/main.rs:9:45
|
9 | let _x: call_with_type!(type_matcher) = 42;
| ----------------------------- ^^ expected `()`, found integer
| |
| expected due to this
For more information about this error, try `rustc --explain E0308`.
error: could not compile `two` (bin "two") due to 2 previous errors
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
nightly-2025-02-22
compiler for some CI tests fortanix/rust-sgx#713petrochenkov commentedon Mar 26, 2025
cc @nnethercote
nnethercote commentedon Mar 26, 2025
It's late here, so I'll look at this closely tomorrow. But I will note an interesting thing from the crater run for #124141: there were several failures in the following form:
And the example involves a cross-crate boundary and a nested declarative macro, so it very much fits this pattern. In other words, it's possible that the code shouldn't have been compiling in its current form.
nnethercote commentedon Mar 26, 2025
My hunch from yesterday was correct: this is invalid code that the old compiler (pre-#133436) should not have accepted, and the new compiler (post-#133436) is now correctly rejecting it. Details below.
I reproduced the behaviour. I didn't use the run-make test, I just created two crates
one
andtwo
, wheretwo
depends onone
, and builttwo
. Thank you for minimizing, that was very helpful.If I combine
one
andtwo
into a single crate like this:then both the old compiler and the new compiler give the same error (modulo some very slight wording changes in the error message). I believe this is the correct behaviour here, and likewise giving an error when the code is split across two crates is also the correct behaviour. In other words, this code is invalid, the old compiler was incorrectly accepting it when it was split across two crates due to a bug in the handling of declarative macros across crate boundaries, and #133436 fixed the bug. This matches the handful of other failures seen in the crater run. (I don't know why async-usercalls didn't show up as a failure in that crater run.)
So I think there is nothing to be done on the compiler side, and the appropriate course of action is to fix the problem in async-usercalls. As the error message explains, changing the
ty
fragment specifier tott
is enough to fix the reduced test case, and hopefully the fix in the full crate is equally simple. Apologies for the inconvenience!jethrogb commentedon May 22, 2025
Why wasn't https://rustc-dev-guide.rust-lang.org/bug-fix-procedure.html followed to ensure a smooth transition for code that depended on the broken behavior? This is causing issues downstream of us.