-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
regression: a value of type HashMap<Pulse, u64>
cannot be built from
#135669
Comments
Minimized (zipped for your convenience: foo.zip): src/lib.rs // This crate is in edition 2021
bar::create_macro! {{
// This code works on edition 2021, but not edition 2018
let _ = [1i32].into_iter().collect::<Vec<i32>>();
}}
create_fn!(); bar/src/lib.rs // This crate is in edition 2018
#[macro_export]
macro_rules! create_macro {
($body:tt) => {
macro_rules! create_fn {
() => {
fn a() {
$body
}
};
}
};
} Cargo.toml[workspace]
members = ["bar"]
[package]
name = "foo"
version = "0.1.0"
edition = "2021"
[dependencies]
bar = { path = "bar" } bar/Cargo.toml[package]
edition = "2018"
name = "bar"
version = "0.1.0" In stable, the function body is compiled as edition 2021. In beta, it is compiled as edition 2018. For context: This is the intended usage pattern of the parameterized_test crate. |
Hm, yea, I can see how that doesn't look to be working quite as I intended. I would expect substitutions to retain whatever edition the input has, but it makes sense that the macro_rules compiler is ignoring that. I would be fine reverting #133274 if that is what people want. It did not have a high importance for edition compatibility. I don't recall how many crates would fail in the 2024 edition without it, though. I think it should eventually be fixed, but may require deeper changes if it is possible. |
@rustbot labels -T-libs +T-lang +I-lang-nominated Let's nominate to sign off on this regression. I talked this one over with @ehuss, and the conclusion we came to is that it's probably best to just accept this if the breakage looks as minimal as what we're seeing here. Keeping the #133274 PR is helpful to the edition migration, and more broadly, this behavior -- while itself not right either -- at least gives the caller the ability to fix this problem. What it does, essentially, is to leak out to the caller the edition of the crate that defines the macro, but we have of course other places that's also true, e.g.: |
I think the model is this---
And then the question I don't know is:
Or is my mental model broken here somehow...? Are the editions of the pasted-in tokens being changed? |
@theemathas do you know whether this code would error (building on your example)... // code in Edition 2024
bar::create_macro! {{
let gen = 3; // <-- ERROR
}}
create_fn!(); ...my expectation is that it will, because the span of the |
@nikomatsakis Your example with Will follow up here shortly with some more information. |
@ehuss I see -- that is surprising to me (that it overwrites the edition of the substitutions). It is not my mental model at all. I'm trying to remember now if we decided that ultimately that was better at some point or what. That said, if we do that, I think that the model of "use the edition of the crate definition" feels better than "edition of the crate consumer". |
This isn't actually "inference". See https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html The token used is the |
I don't think there is a general rule of thumb to describe which tokens affect edition behavior. It depends on the particular feature. For For To try to explain the example above a little more explicitly, let's look at the behavior on stable (before #133274).
After #133274, it is:
Note that there is something really wonky here which I don't really understand. I don't think it is related to this issue, but it is weird looking. I unfortunately don't remember the context from #84429. (For the record, I still don't fully understand expansion contexts, and so this is just the best interpretation I have.) |
My take on this issue is that we should leave the behavior as is but separately investigate whether macros rules interpolation can be made to preserve edition information. Of course this may itself have fallout.
…On Wed, Jan 29, 2025, at 6:02 PM, Eric Huss wrote:
> what tokens control which inference behavior we use here? Presumably it's the fn token?
>
I don't think there is a general rule of thumb to describe which tokens affect edition behavior. It depends on the particular feature.
For `let gen = 3`, the edition of the `gen` token is used to determine the edition behavior.
For `let _ = [1i32].into_iter().collect::<Vec<i32>>();`, the edition of the `into_iter` token is the one that determines the edition behavior.
To try to explain the example above a little more explicitly, let's look at the behavior on stable (before #133274 <#133274>). `foo` is 2021, `bar` is 2018.
1. When bar is built, it has a macro called `create_macro` with a bunch of spans equal to 2018.
2. When foo calls `create_macro`, it expands to a local macro called `create_fn`, and `create_fn` has the local edition (2021) (because it uses the local crate's edition when compiling a macro).
3. The input (`let _ = …`) has the local edition (2021).
4. When foo calls `create_fn`, it expands to the function with all tokens at edition 2021.
5. Compilation succeeds.
After #133274 <#133274>, it is:
1. Same
2. When foo calls `create_macro`, it expands to a local macro called `create_fn`, and `create_fn` is created *with the edition of `create_macro`* which is 2018 (because #133274 <#133274> changed it so that it uses the edition of the macro definition).
3. (Same) The input (`let _ = …`) has the local edition (2021).
4. Because the input was embedded in `create_fn`, when `create_fn` was compiled the input's spans ended up with 2018. I believe this is happening around here <https://github.com/rust-lang/rust/blob/ae5de6c759cd337ecdb2de4e94f47eaafb5d4606/compiler/rustc_expand/src/mbe/macro_rules.rs#L508-L515>.
5. Compilation fails.
Note that there is something really wonky here <https://github.com/rust-lang/rust/blob/ae5de6c759cd337ecdb2de4e94f47eaafb5d4606/compiler/rustc_expand/src/mbe/quoted.rs#L74-L88> which I don't really understand. I don't think it is related to this issue, but it is weird looking. I unfortunately don't remember the context from #84429 <#84429>.
(For the record, I still don't fully understand expansion contexts, and so this is just the best interpretation I have.)
—
Reply to this email directly, view it on GitHub <#135669 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AABF4ZXNQ5AFJKAED6FEKXD2NFMYBAVCNFSM6AAAAABVNEJ6QOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMMRTGEYTEOJXGA>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
This adds tests to check the behavior of how nested macro_rules definitions work across edition boundaries. This covers a change in behavior due to rust-lang#133274. See rust-lang#135669
This adds tests to check the behavior of how nested macro_rules definitions work across edition boundaries. This covers a change in behavior due to rust-lang#133274. See rust-lang#135669
Posted #136509 to at least add a test that would have caught this change in behavior. |
This adds tests to check the behavior of how nested macro_rules definitions work across edition boundaries. This covers a change in behavior due to rust-lang#133274. See rust-lang#135669
This adds tests to check the behavior of how nested macro_rules definitions work across edition boundaries. This covers a change in behavior due to rust-lang#133274. See rust-lang#135669
…r=jieyouxu Add tests for nested macro_rules edition behavior This adds tests to check the behavior of how nested macro_rules definitions work across edition boundaries. This covers a change in behavior due to rust-lang#133274. See rust-lang#135669
…r=jieyouxu Add tests for nested macro_rules edition behavior This adds tests to check the behavior of how nested macro_rules definitions work across edition boundaries. This covers a change in behavior due to rust-lang#133274. See rust-lang#135669
Rollup merge of rust-lang#136509 - ehuss:nested-macro-rules-edition, r=jieyouxu Add tests for nested macro_rules edition behavior This adds tests to check the behavior of how nested macro_rules definitions work across edition boundaries. This covers a change in behavior due to rust-lang#133274. See rust-lang#135669
We're deciding to accept this one-crate breakage and keep the behavior in the PR. @rfcbot fcp merge |
Team member @traviscross has proposed to merge this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns. |
@rfcbot reviewed |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
Checking @nikomatsakis' box per his comment in #133081 (comment):
|
Add tests for nested macro_rules edition behavior This adds tests to check the behavior of how nested macro_rules definitions work across edition boundaries. This covers a change in behavior due to rust-lang/rust#133274. See rust-lang/rust#135669
Whoops :) Thanks @traviscross and @ehuss for redirecting my comments. |
The text was updated successfully, but these errors were encountered: