about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorStuart Cook <Zalathar@users.noreply.github.com>2025-09-11 14:06:32 +1000
committerGitHub <noreply@github.com>2025-09-11 14:06:32 +1000
commitd037d1097fe62a9ec5dfcb211cbe334f2d635428 (patch)
tree03c4c9f01c2acd93b69de74a971ebfe678b2ce78 /tests
parent77ec4781c6df92f6582fec484305501796477212 (diff)
parentf5dad62d4cdf139fb1c6cf2fa24ac525167501cc (diff)
downloadrust-d037d1097fe62a9ec5dfcb211cbe334f2d635428.tar.gz
rust-d037d1097fe62a9ec5dfcb211cbe334f2d635428.zip
Rollup merge of #146422 - fmease:less-greedy-maybe-const-bounds, r=estebank
Less greedily parse `[const]` bounds

> [!IMPORTANT]
> If you're coming here from any beta backport nomination thread on Zulip, only the last commit is truly relevant (the first commit doesn't need to be backported, it only contains test modifications)!

Don't consider `[` to start a bound, only consider `[const]` in its entirety to do so. This drastically reduces (but doesn't eliminate!) the chance of *real* breakages. Like `const`, `~const` and `async` before, `[const]` unavoidably brings along theoretical breakages, see preexisting tests: `macro-const-trait-bound-theoretical-regression.rs` and `macro-async-trait-bound-theoretical-regression.rs`.

Side note: It's unfortunate that we have to do this but apart from the known fact that MBE hurts forward compatibility, the `[const]` syntax is simply a bit scuffed (also CC'ing https://github.com/rust-lang/rust/issues/146122, section (3)).

Fixes [after beta backport] rust-lang/rust#146417.

* 1st commit: Restore the original test intentions of several preexisting related tests that were unfortunately lost over time
  * I've added a bunch of SCREAMING comments to make it less likely to be lost again
  * CC PR rust-lang/rust#119099 which added most of these tests
  * CC [#144409 (comment)](https://github.com/rust-lang/rust/pull/144409#discussion_r2337587513) for further context (NB: It's not the only PR that negatively affected the test intention)
* 2nd commit: Actually address the regression

r? `@oli-obk` or anyone
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.rs17
-rw-r--r--tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.stderr8
-rw-r--r--tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.rs33
-rw-r--r--tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.stderr22
-rw-r--r--tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.rs30
-rw-r--r--tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr92
-rw-r--r--tests/ui/traits/const-traits/macro-dyn-const-2015.rs15
-rw-r--r--tests/ui/traits/const-traits/macro-maybe-const-trait-bounds.rs25
8 files changed, 145 insertions, 97 deletions
diff --git a/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.rs b/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.rs
index ea67831b68e..a13a255d536 100644
--- a/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.rs
+++ b/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.rs
@@ -1,21 +1,22 @@
 // Demonstrates and records a theoretical regressions / breaking changes caused by the
 // introduction of async trait bounds.
 
-// Setting the edition to 2018 since we don't regress `demo! { dyn async }` in Rust <2018.
+// Setting the edition to >2015 since we didn't regress `demo! { dyn async }` in Rust 2015.
 //@ edition:2018
 
 macro_rules! demo {
-    ($ty:ty) => { compile_error!("ty"); };
+    ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
     //~^ ERROR ty
     //~| ERROR ty
-    (impl $c:ident Trait) => {};
-    (dyn $c:ident Trait) => {};
+
+    // DON'T MODIFY THE MATCHERS BELOW UNLESS THE ASYNC TRAIT MODIFIER SYNTAX CHANGES!
+
+    (impl $c:ident Trait) => { /* KEEP THIS EMPTY! */ };
+    (dyn $c:ident Trait) => { /* KEEP THIS EMPTY! */ };
 }
 
-demo! { impl async Trait }
-//~^ ERROR `async` trait bounds are unstable
+demo! { impl async Trait } //~ ERROR `async` trait bounds are unstable
 
-demo! { dyn async Trait }
-//~^ ERROR `async` trait bounds are unstable
+demo! { dyn async Trait } //~ ERROR `async` trait bounds are unstable
 
 fn main() {}
diff --git a/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.stderr b/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.stderr
index 6c3044e64d2..0292c53fb1c 100644
--- a/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.stderr
+++ b/tests/ui/async-await/async-fn/macro-async-trait-bound-theoretical-regression.stderr
@@ -1,7 +1,7 @@
 error: ty
   --> $DIR/macro-async-trait-bound-theoretical-regression.rs:8:19
    |
-LL |     ($ty:ty) => { compile_error!("ty"); };
+LL |     ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
    |                   ^^^^^^^^^^^^^^^^^^^^
 ...
 LL | demo! { impl async Trait }
@@ -12,7 +12,7 @@ LL | demo! { impl async Trait }
 error: ty
   --> $DIR/macro-async-trait-bound-theoretical-regression.rs:8:19
    |
-LL |     ($ty:ty) => { compile_error!("ty"); };
+LL |     ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
    |                   ^^^^^^^^^^^^^^^^^^^^
 ...
 LL | demo! { dyn async Trait }
@@ -21,7 +21,7 @@ LL | demo! { dyn async Trait }
    = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0658]: `async` trait bounds are unstable
-  --> $DIR/macro-async-trait-bound-theoretical-regression.rs:15:14
+  --> $DIR/macro-async-trait-bound-theoretical-regression.rs:18:14
    |
 LL | demo! { impl async Trait }
    |              ^^^^^
@@ -32,7 +32,7 @@ LL | demo! { impl async Trait }
    = help: use the desugared name of the async trait, such as `AsyncFn`
 
 error[E0658]: `async` trait bounds are unstable
-  --> $DIR/macro-async-trait-bound-theoretical-regression.rs:18:13
+  --> $DIR/macro-async-trait-bound-theoretical-regression.rs:20:13
    |
 LL | demo! { dyn async Trait }
    |             ^^^^^
diff --git a/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.rs b/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.rs
index ee04f74c8a6..9b03ec7553d 100644
--- a/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.rs
+++ b/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.rs
@@ -1,24 +1,23 @@
-// Ensure that we don't consider `const Trait` to
-// match the macro fragment specifier `ty` as that would be a breaking
-// change theoretically speaking. Syntactically trait object types can
-// be "bare", i.e., lack the prefix `dyn`.
-// By contrast, `?Trait` *does* match `ty` and therefore an arm like
-// `?$Trait:path` would never be reached.
-// See `parser/macro/mbe-bare-trait-object-maybe-trait-bound.rs`.
-// `[const] Trait` is already an error for a `ty` fragment,
-// so we do not need to prevent that.
+// Ensure that we don't consider `const Trait` to match the macro fragment specifier `ty`
+// as that would be a breaking change theoretically speaking.
+//
+// Syntactically trait object types can be "bare", i.e., lack the prefix `dyn`.
+// By contrast, `?Trait` *does* match `ty` and therefore an arm like `?$Trait:path`
+// would never be reached. See `parser/macro/macro-bare-trait-object-maybe-trait-bound.rs`.
+
+//@ check-pass (KEEP THIS AS A PASSING TEST!)
 
 macro_rules! check {
-    ($Type:ty) => {
-        compile_error!("ty");
-    };
-    (const $Trait:path) => {};
-    ([const] $Trait:path) => { [const] Trait };
+    ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
+
+    // DON'T MODIFY THE MATCHERS BELOW UNLESS THE CONST TRAIT MODIFIER SYNTAX CHANGES!
+
+    (const $Trait:path) => { /* KEEP THIS EMPTY! */ };
+    // We don't need to check `[const] Trait` here since that matches the `ty` fragment
+    // already anyway since `[` may begin a slice or array type. However, it'll then
+    // subsequently fail due to #146122 (section 3).
 }
 
 check! { const Trait }
-check! { [const] Trait }
-//~^ ERROR: expected identifier, found `]`
-//~| ERROR: const trait impls are experimental
 
 fn main() {}
diff --git a/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.stderr b/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.stderr
deleted file mode 100644
index a4e77154b17..00000000000
--- a/tests/ui/traits/const-traits/macro-bare-trait-objects-const-trait-bounds.stderr
+++ /dev/null
@@ -1,22 +0,0 @@
-error: expected identifier, found `]`
-  --> $DIR/macro-bare-trait-objects-const-trait-bounds.rs:20:16
-   |
-LL |     ($Type:ty) => {
-   |      -------- while parsing argument for this `ty` macro fragment
-...
-LL | check! { [const] Trait }
-   |                ^ expected identifier
-
-error[E0658]: const trait impls are experimental
-  --> $DIR/macro-bare-trait-objects-const-trait-bounds.rs:20:11
-   |
-LL | check! { [const] Trait }
-   |           ^^^^^
-   |
-   = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
-   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.rs b/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.rs
index 35e964eacec..3f70ffa7d10 100644
--- a/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.rs
+++ b/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.rs
@@ -1,22 +1,32 @@
 // Demonstrates and records a theoretical regressions / breaking changes caused by the
-// introduction of const trait bounds.
+// introduction of `const` and `[const]` trait bounds.
 
-// Setting the edition to 2018 since we don't regress `demo! { dyn const }` in Rust <2018.
+// Setting the edition to >2015 since we didn't regress `demo! { dyn const }` in Rust 2015.
+// See also test `traits/const-traits/macro-dyn-const-2015.rs`.
 //@ edition:2018
 
 trait Trait {}
 
 macro_rules! demo {
-    (impl $c:ident Trait) => { impl $c Trait {} };
-    //~^ ERROR inherent
-    //~| WARN trait objects without an explicit `dyn` are deprecated
-    //~| WARN this is accepted in the current edition
-    (dyn $c:ident Trait) => { dyn $c Trait {} }; //~ ERROR macro expansion
+    ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
+    //~^ ERROR ty
+    //~| ERROR ty
+    //~| ERROR ty
+    //~| ERROR ty
+
+    // DON'T MODIFY THE MATCHERS BELOW UNLESS THE CONST TRAIT MODIFIER SYNTAX CHANGES!
+
+    (impl $c:ident Trait) => { /* KEEP THIS EMPTY! */ };
+    (dyn $c:ident Trait) => { /* KEEP THIS EMPTY! */ };
+
+    (impl [const] Trait) => { /* KEEP THIS EMPTY! */ };
+    (dyn [const] Trait) => { /* KEEP THIS EMPTY! */ };
 }
 
-demo! { impl const Trait }
-//~^ ERROR const trait impls are experimental
+demo! { impl const Trait } //~ ERROR const trait impls are experimental
+demo! { dyn const Trait } //~ ERROR const trait impls are experimental
 
-demo! { dyn const Trait }
+demo! { impl [const] Trait } //~ ERROR const trait impls are experimental
+demo! { dyn [const] Trait } //~ ERROR const trait impls are experimental
 
 fn main() {}
diff --git a/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr b/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr
index 7a4061d9c18..383936b9df1 100644
--- a/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr
+++ b/tests/ui/traits/const-traits/macro-const-trait-bound-theoretical-regression.stderr
@@ -1,31 +1,49 @@
-error: inherent impls cannot be const
-  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:10:40
+error: ty
+  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:11:19
    |
-LL |     (impl $c:ident Trait) => { impl $c Trait {} };
-   |                                        ^^^^^ inherent impl for this type
+LL |     ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
+   |                   ^^^^^^^^^^^^^^^^^^^^
 ...
 LL | demo! { impl const Trait }
-   | --------------------------
-   | |            |
-   | |            const because of this
-   | in this macro invocation
+   | -------------------------- in this macro invocation
    |
-   = note: only trait implementations may be annotated with `const`
    = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: macro expansion ignores keyword `dyn` and any tokens following
-  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:14:31
+error: ty
+  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:11:19
    |
-LL |     (dyn $c:ident Trait) => { dyn $c Trait {} };
-   |                               ^^^
+LL |     ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
+   |                   ^^^^^^^^^^^^^^^^^^^^
 ...
 LL | demo! { dyn const Trait }
-   | ------------------------- caused by the macro expansion here
+   | ------------------------- in this macro invocation
    |
-   = note: the usage of `demo!` is likely invalid in item context
+   = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: ty
+  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:11:19
+   |
+LL |     ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
+   |                   ^^^^^^^^^^^^^^^^^^^^
+...
+LL | demo! { impl [const] Trait }
+   | ---------------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: ty
+  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:11:19
+   |
+LL |     ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
+   |                   ^^^^^^^^^^^^^^^^^^^^
+...
+LL | demo! { dyn [const] Trait }
+   | --------------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0658]: const trait impls are experimental
-  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:17:14
+  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:26:14
    |
 LL | demo! { impl const Trait }
    |              ^^^^^
@@ -34,24 +52,36 @@ LL | demo! { impl const Trait }
    = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:10:40
+error[E0658]: const trait impls are experimental
+  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:27:13
    |
-LL |     (impl $c:ident Trait) => { impl $c Trait {} };
-   |                                        ^^^^^
-...
-LL | demo! { impl const Trait }
-   | -------------------------- in this macro invocation
+LL | demo! { dyn const Trait }
+   |             ^^^^^
    |
-   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
-   = note: `#[warn(bare_trait_objects)]` (part of `#[warn(rust_2021_compatibility)]`) on by default
-   = note: this warning originates in the macro `demo` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: you might have intended to implement this trait for a given type
+   = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: const trait impls are experimental
+  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:29:14
+   |
+LL | demo! { impl [const] Trait }
+   |              ^^^^^^^
+   |
+   = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: const trait impls are experimental
+  --> $DIR/macro-const-trait-bound-theoretical-regression.rs:30:13
    |
-LL |     (impl $c:ident Trait) => { impl $c Trait for /* Type */ {} };
-   |                                              ++++++++++++++
+LL | demo! { dyn [const] Trait }
+   |             ^^^^^^^
+   |
+   = note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 8 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/traits/const-traits/macro-dyn-const-2015.rs b/tests/ui/traits/const-traits/macro-dyn-const-2015.rs
index fadfbe66788..0dfa482b986 100644
--- a/tests/ui/traits/const-traits/macro-dyn-const-2015.rs
+++ b/tests/ui/traits/const-traits/macro-dyn-const-2015.rs
@@ -1,14 +1,19 @@
-// Ensure that the introduction of const trait bound didn't regress this code in Rust 2015.
-// See also `mbe-const-trait-bound-theoretical-regression.rs`.
+// Ensure that the introduction of `const` and `[const]` trait bounds didn't regress this
+// Rust 2015 code. See also test `macro-const-trait-bound-theoretical-regression.rs`.
 
 //@ edition: 2015
-//@ check-pass
+//@ check-pass (KEEP THIS AS A PASSING TEST!)
 
 macro_rules! check {
-    ($ty:ty) => { compile_error!("ty"); };
-    (dyn $c:ident) => {};
+    ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
+
+    // DON'T MODIFY THE MATCHERS BELOW UNLESS THE CONST TRAIT MODIFIER SYNTAX CHANGES!
+
+    (dyn $c:ident) => { /* KEEP THIS EMPTY! */ };
+    (dyn [$c:ident]) => { /* KEEP THIS EMPTY! */ };
 }
 
 check! { dyn const }
+check! { dyn [const] }
 
 fn main() {}
diff --git a/tests/ui/traits/const-traits/macro-maybe-const-trait-bounds.rs b/tests/ui/traits/const-traits/macro-maybe-const-trait-bounds.rs
new file mode 100644
index 00000000000..75077577b8c
--- /dev/null
+++ b/tests/ui/traits/const-traits/macro-maybe-const-trait-bounds.rs
@@ -0,0 +1,25 @@
+// Ensure that we don't consider `[` to begin trait bounds to contain breakages.
+// Only `[const]` in its entirety begins a trait bound.
+// See also test `macro-const-trait-bound-theoretical-regression.rs`.
+
+//@ check-pass (KEEP THIS AS A PASSING TEST!)
+// Setting the edition to >2015 since we didn't regress `check! { dyn [const] Trait }` in Rust 2015.
+// See also test `traits/const-traits/macro-dyn-const-2015.rs`.
+//@ edition:2018
+
+macro_rules! check {
+    ($ty:ty) => { compile_error!("ty"); }; // KEEP THIS RULE FIRST AND AS IS!
+
+    // DON'T MODIFY THE MATCHERS BELOW UNLESS THE CONST TRAIT MODIFIER SYNTAX CHANGES!
+
+    (dyn [$($any:tt)*] Trait) => { /* KEEP THIS EMPTY! */ };
+    (impl [$($any:tt)*] Trait) => { /* KEEP THIS EMPTY! */ };
+}
+
+check!(dyn [T] Trait);
+
+// issue: <https://github.com/rust-lang/rust/issues/146417>
+check!(impl [T] Trait);
+check!(impl [T: Bound] Trait);
+
+fn main() {}