Skip to content

Commit 898ed2f

Browse files
Enforce that ? and for<...> are not combined
1 parent 32c8bfd commit 898ed2f

File tree

6 files changed

+38
-4
lines changed

6 files changed

+38
-4
lines changed

compiler/rustc_parse/messages.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ parse_bare_cr = {$double_quotes ->
5353
5454
parse_bare_cr_in_raw_string = bare CR not allowed in raw string
5555
56+
parse_binder_and_polarity = `for<...>` binder not allowed with `{$polarity}` trait polarity modifier
57+
.label = there is not a well-defined meaning for a higher-ranked `{$polarity}` trait
58+
5659
parse_binder_before_modifiers = `for<...>` binder should be placed before trait bound modifiers
5760
.label = place the `for<...>` binder before any modifiers
5861

compiler/rustc_parse/src/errors.rs

+10
Original file line numberDiff line numberDiff line change
@@ -3050,3 +3050,13 @@ pub struct BinderBeforeModifiers {
30503050
#[label]
30513051
pub modifiers_span: Span,
30523052
}
3053+
3054+
#[derive(Diagnostic)]
3055+
#[diag(parse_binder_and_polarity)]
3056+
pub struct BinderAndPolarity {
3057+
#[primary_span]
3058+
pub polarity_span: Span,
3059+
#[label]
3060+
pub binder_span: Span,
3061+
pub polarity: &'static str,
3062+
}

compiler/rustc_parse/src/parser/ty.rs

+13
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,19 @@ impl<'a> Parser<'a> {
994994
let modifiers = self.parse_trait_bound_modifiers()?;
995995
let modifiers_span = modifiers_lo.to(self.prev_token.span);
996996

997+
if let Some(binder_span) = binder_span {
998+
match modifiers.polarity {
999+
BoundPolarity::Negative(polarity_span) | BoundPolarity::Maybe(polarity_span) => {
1000+
self.dcx().emit_err(errors::BinderAndPolarity {
1001+
binder_span,
1002+
polarity_span,
1003+
polarity: modifiers.polarity.as_str(),
1004+
});
1005+
}
1006+
BoundPolarity::Positive => {}
1007+
}
1008+
}
1009+
9971010
// Recover erroneous lifetime bound with modifiers or binder.
9981011
// e.g. `T: for<'a> 'a` or `T: ~const 'a`.
9991012
if self.token.is_lifetime() {

tests/ui/parser/bounds-type.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ struct S<
55
T: Tr + 'a, // OK
66
T: 'a, // OK
77
T:, // OK
8-
T: for<'a> ?Trait, // OK
8+
T: for<'a> ?Trait, //~ ERROR `for<...>` binder not allowed with `?` trait polarity modifier
99
T: Tr +, // OK
1010
T: ?'a, //~ ERROR `?` may only modify trait bounds, not lifetime bounds
1111

tests/ui/parser/bounds-type.stderr

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
error: `for<...>` binder not allowed with `?` trait polarity modifier
2+
--> $DIR/bounds-type.rs:8:16
3+
|
4+
LL | T: for<'a> ?Trait,
5+
| ---- ^
6+
| |
7+
| there is not a well-defined meaning for a higher-ranked `?` trait
8+
19
error: `?` may only modify trait bounds, not lifetime bounds
210
--> $DIR/bounds-type.rs:10:8
311
|
@@ -16,5 +24,5 @@ error: `const` may only modify trait bounds, not lifetime bounds
1624
LL | T: const 'a,
1725
| ^^^^^
1826

19-
error: aborting due to 3 previous errors
27+
error: aborting due to 4 previous errors
2028

tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-syntax.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
#![feature(const_trait_impl)]
55

66
struct S<
7-
T: for<'a> ~const ?Tr<'a> + 'static + ~const std::ops::Add,
8-
T: for<'a: 'b> ~const ?m::Trait<'a>,
7+
T: for<'a> ~const Tr<'a> + 'static + ~const std::ops::Add,
8+
T: for<'a: 'b> ~const m::Trait<'a>,
99
>;

0 commit comments

Comments
 (0)