about summary refs log tree commit diff
path: root/tests/ui/parser
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-07-25 04:43:18 +0200
committerGitHub <noreply@github.com>2024-07-25 04:43:18 +0200
commitcfc5f25b3d7c2f9fa37d0165085cdd4120939716 (patch)
treed0f2623102a192d2a45a1683529eb39405bb793b /tests/ui/parser
parente7d66eac5e8e8f60370c98d186aee9fa0ebd7845 (diff)
parent7da751a108a31b52650d055202e89a15f43ce0e7 (diff)
downloadrust-cfc5f25b3d7c2f9fa37d0165085cdd4120939716.tar.gz
rust-cfc5f25b3d7c2f9fa37d0165085cdd4120939716.zip
Rollup merge of #127054 - compiler-errors:bound-ordering, r=fmease
Reorder trait bound modifiers *after* `for<...>` binder in trait bounds

This PR suggests changing the grammar of trait bounds from:

```
[CONSTNESS] [ASYNCNESS] [?] [BINDER] [TRAIT_PATH]

const async ? for<'a> Sized
```

to

```
([BINDER] [CONSTNESS] [ASYNCNESS] | [?]) [TRAIT_PATH]
```

i.e., either

```
? Sized
```

or

```
for<'a> const async Sized
```

(but not both)

### Why?

I think it's strange that the binder applies "more tightly" than the `?` trait polarity. This becomes even weirder when considering that we (or at least, I) want to have `async` trait bounds expressed like:

```
where T: for<'a> async Fn(&'a ()) -> i32,
```

and not:

```
where T: async for<'a> Fn(&'a ()) -> i32,
```

### Fallout

No crates on crater use this syntax, presumably because it's literally useless. This will require modifying the reference grammar, though.

### Alternatives

If this is not desirable, then we can alternatively keep parsing `for<'a>` after the `?` but deprecate it with either an FCW (or an immediate hard error), and begin parsing `for<'a>` *before* the `?`.
Diffstat (limited to 'tests/ui/parser')
-rw-r--r--tests/ui/parser/bounds-type.rs15
-rw-r--r--tests/ui/parser/bounds-type.stderr52
2 files changed, 61 insertions, 6 deletions
diff --git a/tests/ui/parser/bounds-type.rs b/tests/ui/parser/bounds-type.rs
index a1971fa3146..7cee6def32f 100644
--- a/tests/ui/parser/bounds-type.rs
+++ b/tests/ui/parser/bounds-type.rs
@@ -1,19 +1,30 @@
 //@ compile-flags: -Z parse-only
+//@ edition: 2021
 
 struct S<
     T: 'a + Tr, // OK
     T: Tr + 'a, // OK
     T: 'a, // OK
     T:, // OK
-    T: ?for<'a> Trait, // OK
+    T: for<'a> ?Trait, //~ ERROR `for<...>` binder not allowed with `?` trait polarity modifier
     T: Tr +, // OK
     T: ?'a, //~ ERROR `?` may only modify trait bounds, not lifetime bounds
 
     T: ~const Tr, // OK
-    T: ~const ?Tr, // OK
+    T: ~const ?Tr, //~ ERROR `~const` trait not allowed with `?` trait polarity modifier
     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
+
+    T: async Tr, // OK
+    T: async ?Tr, //~ ERROR `async` trait not allowed with `?` trait polarity modifier
+    T: async Tr + 'a, // OK
+    T: async 'a, //~ ERROR `async` may only modify trait bounds, not lifetime bounds
+
+    T: const async Tr, // OK
+    T: const async ?Tr, //~ ERROR `const async` trait not allowed with `?` trait polarity modifier
+    T: const async Tr + 'a, // OK
+    T: const async '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 d1210e88d66..09c35c12b00 100644
--- a/tests/ui/parser/bounds-type.stderr
+++ b/tests/ui/parser/bounds-type.stderr
@@ -1,20 +1,64 @@
+error: `for<...>` binder not allowed with `?` trait polarity modifier
+  --> $DIR/bounds-type.rs:9:16
+   |
+LL |     T: for<'a> ?Trait,
+   |           ---- ^
+   |           |
+   |           there is not a well-defined meaning for a higher-ranked `?` trait
+
 error: `?` may only modify trait bounds, not lifetime bounds
-  --> $DIR/bounds-type.rs:10:8
+  --> $DIR/bounds-type.rs:11:8
    |
 LL |     T: ?'a,
    |        ^
 
+error: `~const` trait not allowed with `?` trait polarity modifier
+  --> $DIR/bounds-type.rs:14:15
+   |
+LL |     T: ~const ?Tr,
+   |        ------ ^
+   |        |
+   |        there is not a well-defined meaning for a `~const ?` trait
+
 error: `~const` may only modify trait bounds, not lifetime bounds
-  --> $DIR/bounds-type.rs:15:8
+  --> $DIR/bounds-type.rs:16:8
    |
 LL |     T: ~const 'a,
    |        ^^^^^^
 
 error: `const` may only modify trait bounds, not lifetime bounds
-  --> $DIR/bounds-type.rs:16:8
+  --> $DIR/bounds-type.rs:17:8
    |
 LL |     T: const 'a,
    |        ^^^^^
 
-error: aborting due to 3 previous errors
+error: `async` trait not allowed with `?` trait polarity modifier
+  --> $DIR/bounds-type.rs:20:14
+   |
+LL |     T: async ?Tr,
+   |        ----- ^
+   |        |
+   |        there is not a well-defined meaning for a `async ?` trait
+
+error: `async` may only modify trait bounds, not lifetime bounds
+  --> $DIR/bounds-type.rs:22:8
+   |
+LL |     T: async 'a,
+   |        ^^^^^
+
+error: `const async` trait not allowed with `?` trait polarity modifier
+  --> $DIR/bounds-type.rs:25:20
+   |
+LL |     T: const async ?Tr,
+   |        ----------- ^
+   |        |
+   |        there is not a well-defined meaning for a `const async ?` trait
+
+error: `const` may only modify trait bounds, not lifetime bounds
+  --> $DIR/bounds-type.rs:27:8
+   |
+LL |     T: const async 'a,
+   |        ^^^^^
+
+error: aborting due to 9 previous errors