Support async trait bounds in macros#121044
Conversation
|
rust/compiler/rustc_parse/src/parser/ty.rs Line 751 in eaff1af But inside of macro contexts, where |
| || self.is_kw_followed_by_ident(kw::Const) | ||
| || self.is_kw_followed_by_ident(kw::Async) |
There was a problem hiding this comment.
Ah, wait doesn't this stop impl const !Trait and impl const ?Trait from parsing (semantic error on master → syntactic error on this branch)?
There was a problem hiding this comment.
Yeah, I guess it does. Do we particularly care about this, though?
There was a problem hiding this comment.
Personally speaking I don't care. I just remember from when I was refactoring trait bound modifiers and looking through the git history that there was a PR years ago that explicitly set out to parse invalid modifier combinations to make it a semantic error.
I'm now on mobile and can't look for it, maybe it contains a motivation.
There was a problem hiding this comment.
#68140. This is not the PR I remember lol but it does mention the piece of information I'm after:
After a discussion in #wg-grammar on Discord, it was decided that the grammar should not encode the mutual exclusivity of trait bound modifiers. The grammar for trait bound modifiers remains
[?const] [?]. To encode this, I add a dummy variant toast::TraitBoundModifierthat is used when the syntax?const ?appears. This variant causes an error in AST validation and disappears during HIR lowering.
There was a problem hiding this comment.
In that case, I've changed this back to just a check_kw call. This does regress tests/ui/parser/bad-recover-kw-after-impl.rs, but I consider that to be a same manifestation of this impl async theoretical regression that we already have a test for.
| if (self.token.span.at_least_rust_2018() && self.token.is_keyword(kw::Async)) | ||
| || (self.token.span.is_rust_2015() && self.is_kw_followed_by_ident(kw::Async)) |
There was a problem hiding this comment.
Is it possible that the span/edition of an Interpolated ident differs from the span/edition of the corresponding uninterpolate'd ident? In other words does this PR break the following code?
// dep.rs ::: rustc +stage1 dep.rs --crate-type=lib --edition=2021
#[macro_export]
macro_rules! gen { ($Trait:ident) => { impl $Trait for () {} } }
// usr.rs ::: rustc +stage1 usr.rs --edition=2015 --extern=dep -L.
trait async {}
dep::gen! { async }
fn main() {}If so, we should check if we're inside an expansion or uninterp it first?
There was a problem hiding this comment.
Just checked out this branch and it does error while it shouldn't:
stderr
error: `async` trait implementations are unsupported
--> usr.rs:3:1
|
3 | dep::generate!(async);
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `dep::generate` (in Nightly builds, run with -Z macro-backtrace for more info)
error: missing trait in a trait impl
--> usr.rs:3:1
|
3 | dep::generate!(async);
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `dep::generate` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add a trait here
--> /home/fmease/programming/rust2/dep.rs:2:56
|
2 | macro_rules! generate { ($Trait:ident) => { impl $Trait Trait for () {} } }
| +++++
help: for an inherent impl, drop this `for`
--> /home/fmease/programming/rust2/dep.rs:2:56
2 - macro_rules! generate { ($Trait:ident) => { impl $Trait for () {} } }
2 + macro_rules! generate { ($Trait:ident) => { impl $Trait () {} } }
|
warning: trait `async` should have an upper camel case name
--> usr.rs:1:7
|
1 | trait async {}
| ^^^^^ help: convert the identifier to upper camel case: `Async`
|
= note: `#[warn(non_camel_case_types)]` on by default
error: aborting due to 2 previous errors; 1 warning emitted
And uninterpolate'ing does indeed fix this issue.
There was a problem hiding this comment.
You're absolutely right, and turns out all the other async checks also consider the uninterpolated span. Fixed that.
77ab04d to
9c8b107
Compare
|
Looks good to me. Thanks for fixing the other check, too! |
Rollup of 8 pull requests Successful merges: - rust-lang#121044 (Support async trait bounds in macros) - rust-lang#121175 (match lowering: test one or pattern at a time) - rust-lang#121340 (bootstrap: apply most of clippy's suggestions) - rust-lang#121347 (compiletest: support auxiliaries with auxiliaries) - rust-lang#121359 (miscellaneous type system improvements) - rust-lang#121366 (Remove `diagnostic_builder.rs`) - rust-lang#121379 (Remove an `unchecked_error_guaranteed` call.) - rust-lang#121396 (make it possible for outside crates to inspect a mir::ConstValue with the interpreter) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#121044 - compiler-errors:mbe-async-trait-bounds, r=fmease Support async trait bounds in macros r? fmease This is similar to your work on const trait bounds. This theoretically regresses `impl async $ident:ident` in macros, but I doubt this is occurring in practice.
r? fmease
This is similar to your work on const trait bounds. This theoretically regresses
impl async $ident:identin macros, but I doubt this is occurring in practice.