diff options
| author | bors <bors@rust-lang.org> | 2023-12-27 19:24:31 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-12-27 19:24:31 +0000 |
| commit | 88d69b72b4ccfd4e4b64451a7a5d9fd23d2249a3 (patch) | |
| tree | ee06621ba34b79cf6fb813a928424d9450fc8ed9 /tests/ui/parser | |
| parent | a861c8965eaff66901710cc384a59f6b0b1a7700 (diff) | |
| parent | 3eb48a35c8ae8335da66dc2bdb4f60e6ae22e1dd (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.rs | 1 | ||||
| -rw-r--r-- | tests/ui/parser/bounds-type.stderr | 8 | ||||
| -rw-r--r-- | tests/ui/parser/macro/mbe-bare-trait-object-maybe-trait-bound.rs | 16 | ||||
| -rw-r--r-- | tests/ui/parser/trait-object-delimiters.rs | 2 | ||||
| -rw-r--r-- | tests/ui/parser/trait-object-delimiters.stderr | 4 |
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 `,` |
