about summary refs log tree commit diff
path: root/tests/ui/parser
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-12-27 19:24:31 +0000
committerbors <bors@rust-lang.org>2023-12-27 19:24:31 +0000
commit88d69b72b4ccfd4e4b64451a7a5d9fd23d2249a3 (patch)
treeee06621ba34b79cf6fb813a928424d9450fc8ed9 /tests/ui/parser
parenta861c8965eaff66901710cc384a59f6b0b1a7700 (diff)
parent3eb48a35c8ae8335da66dc2bdb4f60e6ae22e1dd (diff)
Auto merge of #119099 - fmease:always-const-trait-bounds, r=fee1-dead
 Introduce `const Trait` (always-const trait bounds)

Feature `const_trait_impl` currently lacks a way to express “always const” trait bounds. This makes it impossible to define generic items like fns or structs which contain types that depend on const method calls (\*). While the final design and esp. the syntax of effects / keyword generics isn't set in stone, some version of “always const” trait bounds will very likely form a part of it. Further, their implementation is trivial thanks to the `effects` backbone.

Not sure if this needs t-lang sign-off though.

(\*):

```rs
#![feature(const_trait_impl, effects, generic_const_exprs)]

fn compute<T: const Trait>() -> Type<{ T::generate() }> { /*…*/ }

struct Store<T: const Trait>
where
    Type<{ T::generate() }>:,
{
    field: Type<{ T::generate() }>,
}
```

Lastly, “always const” trait bounds are a perfect fit for `generic_const_items`.

```rs
#![feature(const_trait_impl, effects, generic_const_items)]

const DEFAULT<T: const Default>: T = T::default();
```

Previously, we (oli, fee1-dead and I) wanted to reinterpret `~const Trait` as `const Trait` in generic const items which would've been quite surprising and not very generalizable.
Supersedes #117530.

---

cc `@oli-obk`

As discussed
r? fee1-dead (or compiler)
Diffstat (limited to 'tests/ui/parser')
-rw-r--r--tests/ui/parser/bounds-type.rs1
-rw-r--r--tests/ui/parser/bounds-type.stderr8
-rw-r--r--tests/ui/parser/macro/mbe-bare-trait-object-maybe-trait-bound.rs16
-rw-r--r--tests/ui/parser/trait-object-delimiters.rs2
-rw-r--r--tests/ui/parser/trait-object-delimiters.stderr4
5 files changed, 27 insertions, 4 deletions
diff --git a/tests/ui/parser/bounds-type.rs b/tests/ui/parser/bounds-type.rs
index 4ae4549ea58..bd5f6105f51 100644
--- a/tests/ui/parser/bounds-type.rs
+++ b/tests/ui/parser/bounds-type.rs
@@ -13,6 +13,7 @@ struct S<
     T: ~const ?Tr, // OK
     T: ~const Tr + 'a, // OK
     T: ~const 'a, //~ ERROR `~const` may only modify trait bounds, not lifetime bounds
+    T: const 'a, //~ ERROR `const` may only modify trait bounds, not lifetime bounds
 >;
 
 fn main() {}
diff --git a/tests/ui/parser/bounds-type.stderr b/tests/ui/parser/bounds-type.stderr
index 005bc1e54bd..d1210e88d66 100644
--- a/tests/ui/parser/bounds-type.stderr
+++ b/tests/ui/parser/bounds-type.stderr
@@ -10,5 +10,11 @@ error: `~const` may only modify trait bounds, not lifetime bounds
 LL |     T: ~const 'a,
    |        ^^^^^^
 
-error: aborting due to 2 previous errors
+error: `const` may only modify trait bounds, not lifetime bounds
+  --> $DIR/bounds-type.rs:16:8
+   |
+LL |     T: const 'a,
+   |        ^^^^^
+
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/parser/macro/mbe-bare-trait-object-maybe-trait-bound.rs b/tests/ui/parser/macro/mbe-bare-trait-object-maybe-trait-bound.rs
new file mode 100644
index 00000000000..fe062d62e5a
--- /dev/null
+++ b/tests/ui/parser/macro/mbe-bare-trait-object-maybe-trait-bound.rs
@@ -0,0 +1,16 @@
+// Check that `?Trait` matches the macro fragment specifier `ty`.
+// Syntactically trait object types can be "bare" (i.e., lack the prefix `dyn`),
+// even in newer editions like Rust 2021.
+// Therefore the arm `?$Trait:path` shouldn't get reached.
+
+// edition: 2021
+// check-pass
+
+macro_rules! check {
+    ($Ty:ty) => {};
+    (?$Trait:path) => { compile_error!("non-ty"); };
+}
+
+check! { ?Trait }
+
+fn main() {}
diff --git a/tests/ui/parser/trait-object-delimiters.rs b/tests/ui/parser/trait-object-delimiters.rs
index e9b13defe03..240ae3084d6 100644
--- a/tests/ui/parser/trait-object-delimiters.rs
+++ b/tests/ui/parser/trait-object-delimiters.rs
@@ -8,7 +8,7 @@ fn foo2(_: &dyn (Drop + AsRef<str>)) {} //~ ERROR incorrect parentheses around t
 fn foo2_no_space(_: &dyn(Drop + AsRef<str>)) {} //~ ERROR incorrect parentheses around trait bounds
 
 fn foo3(_: &dyn {Drop + AsRef<str>}) {} //~ ERROR expected parameter name, found `{`
-//~^ ERROR expected one of `!`, `(`, `)`, `*`, `,`, `?`, `for`, `~`, lifetime, or path, found `{`
+//~^ ERROR expected one of `!`, `(`, `)`, `*`, `,`, `?`, `const`, `for`, `~`, lifetime, or path, found `{`
 //~| ERROR at least one trait is required for an object type
 
 fn foo4(_: &dyn <Drop + AsRef<str>>) {} //~ ERROR expected identifier, found `<`
diff --git a/tests/ui/parser/trait-object-delimiters.stderr b/tests/ui/parser/trait-object-delimiters.stderr
index 51954675093..2ddb734cee0 100644
--- a/tests/ui/parser/trait-object-delimiters.stderr
+++ b/tests/ui/parser/trait-object-delimiters.stderr
@@ -34,11 +34,11 @@ error: expected parameter name, found `{`
 LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {}
    |                 ^ expected parameter name
 
-error: expected one of `!`, `(`, `)`, `*`, `,`, `?`, `for`, `~`, lifetime, or path, found `{`
+error: expected one of `!`, `(`, `)`, `*`, `,`, `?`, `const`, `for`, `~`, lifetime, or path, found `{`
   --> $DIR/trait-object-delimiters.rs:10:17
    |
 LL | fn foo3(_: &dyn {Drop + AsRef<str>}) {}
-   |                -^ expected one of 10 possible tokens
+   |                -^ expected one of 11 possible tokens
    |                |
    |                help: missing `,`