-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Do not accept interpolated types as traits in trait impls #48502
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
@bors try |
⌛ Trying commit ba61b745c7aa0f6d5c608b73e25e03aa8c061f95 with merge 0c6cdef8a4781d48cd2df0423ca893bf143bd5e2... |
☀️ Test successful - status-travis |
cc @rust-lang/release -- needs crater |
Crater run started. |
Crater results: http://cargobomb-reports.s3.amazonaws.com/pr-48052/index.html. 'Blacklisted' crates (spurious failures etc) can be found |
6 legit regressions:
I think we can deprecate this. |
Reverse deps for breakage: https://gist.github.com/Mark-Simulacrum/e06765d8cd4a324da9fd47e4acf3fce7. I agree that it seems reasonable to deprecate this -- very few crates in the ecosystem are broken by this. |
Hmm, I'm of two minds here. To be clear, we are specifically talking about deprecating this behavior, right? macro_rules! foo {
($t:ty) => {
impl $t for ... { }
}
} This would be deprecated because In particular, I don't like that it matters what kind of fragment you use -- and hence that OTOH, I'm not sure if we have any room to change this until a hypothetical Macros 2.0, and I do feel like -- given that we have type tokens -- it is sort of "wrong" to use them in trait position. And not that many crates are affected. OTOOH, it does work today, and it seems like the kind of kludge we could keep working. @petrochenkov can you elaborate a bit more on the motivation here? |
That's basically the motivation. Since this does cause some breakage I don't think it's reasonable to make this an error, but we can warn to prevent this being used in new code. |
This PR is updated (error -> warning), PRs to affected crates are sent. |
if let Some(span) = ty_first_interpolated { | ||
self.diagnostic() | ||
.struct_span_warn(span, "expected a trait, found type") | ||
.note("this warning will become a hard error in a future release") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason we can't use the standard lint infrastructure?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's too early in the parser, we don't even have NodeId
s yet to attach the lint.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. Before we merge, let's try to follow the other steps though, i.e., create a tracking issue and so forth.
Just out of curiosity, why is |
A fair question. Using "type" here feels sort of like a "category error" -- that is, the idea is roughly that when you parse a trait as a type, you convert it into (That said, I still feel like macros should behave as if they were more-or-less copying tokens to the extent possible, in which case the actual fragment you use wouldn't matter.) |
Nominating for discussing in @rust-lang/lang meeting. |
I prefer the fragment distinction to be only used for matching and erased when expanding. |
That would be a pretty serious shift from the current scheme though. We should probably track it as a separate issue as part of macros 2.0 experimentation. |
@petrochenkov We already keep the original tokens for at least items, I believe. |
We discussed this in the @rust-lang/lang meeting today. I believe the consensus (correct me if I am mistaken) was that it generally makes sense to move towards a future where the precise fragment specifier that you used doesn't matter so much: so e.g. writing (Note though: we should not accept (As a side argument, it strikes me that -- for the same reason that we accept this in the parser -- it's perhaps convenient for macro authors to be able to use Moreover, on the other side of the scale, it doesn't seem like this particularly simplifies implementation (more the opposite: we need an extra check), nor enables any future uses. Therefore I move to close. (But feel free @petrochenkov or others to raise counterarguments.) @rfcbot fcp close |
Team member @nikomatsakis has proposed to close this. The next step is review by the rest of the tagged teams: No concerns currently listed. Once a majority of reviewers approve (and none object), 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! See this document for info about what commands tagged team members can give me. |
ping @rust-lang/lang -- FCP ticky marks await you! |
Given the crazy things that are possible with macro_rules, I have no problem with close here. That said, I'd love some kind of a "what do capture kinds even mean" intent document for macros 2.0, because it still feels really weird to me that you can use a capture as something totally different from what you said it was in the capture kind. (If it was just token based that would make sense, but iirc it's not in general...) |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
☔ The latest upstream changes (presumably #49154) made this pull request unmergeable. Please resolve the merge conflicts. |
Agreed -- macros 2.0 definitely needs more definition, it's in a bit of "see what you want to see" situation.
As I said in the meeting, I definitely feel like we should try to ensure you can think of them as token trees to the extent possible (modulo expression precedence, as discussed in ... some RFC or other). That is, |
@nikomatsakis Well, I just don't understand where the "token tree interpretation" starts and ends. Like I know I can use macro_rules! wha {
($lhs:expr ; $rhs:expr) => ($lhs $rhs)
//~^ ERROR macro expansion ignores token `*3` and any following
}
fn main() {
let z = wha!( 4 ; * 3 );
println!("{}", z);
} (And wait, " This thread certainly isn't the place to resolve or document that; I just hope |
@scottmcm I think that's consistent, in that you don't have tokens but one token ("tree") grouping together several tokens. That is, you can't take apart a fragment or "insert" anything into it. An interesting example that I would hope to work in the future, is taking I'm not sure how to formalize this, but one way to put it is that "syntactical elements used in the same level by the AST cannot come from different 'captured bags' of tokens". This would imply that e.g. an expression followed by a "captured bag" of more than one token can never parse (although maybe some people would want |
The final comment period is now complete. |
Fixes #46438
Needs crater run before proceeding.