Skip to content

Commit 4158ee8

Browse files
committed
Emit ForbiddenBound when parsing
1 parent 5d04477 commit 4158ee8

7 files changed

Lines changed: 81 additions & 16 deletions

File tree

compiler/rustc_ast_passes/src/errors.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,6 @@ pub(crate) struct AsyncFnInConstTraitOrTraitImpl {
9595
pub const_keyword: Span,
9696
}
9797

98-
#[derive(Diagnostic)]
99-
#[diag("bounds cannot be used in this context")]
100-
pub(crate) struct ForbiddenBound {
101-
#[primary_span]
102-
pub spans: Vec<Span>,
103-
}
104-
10598
#[derive(Diagnostic)]
10699
#[diag("late-bound const parameters cannot be used currently")]
107100
pub(crate) struct ForbiddenConstParam {

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,6 @@ impl<'a> PostExpansionVisitor<'a> {
143143
self.sess.dcx().emit_err(errors::ForbiddenConstParam { const_param_spans });
144144
}
145145
}
146-
147-
for param in params {
148-
if !param.bounds.is_empty() {
149-
let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
150-
self.sess.dcx().emit_err(errors::ForbiddenBound { spans });
151-
}
152-
}
153146
}
154147
}
155148

compiler/rustc_parse/src/errors.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4423,6 +4423,13 @@ pub(crate) struct MisspelledKw {
44234423
pub is_incorrect_case: bool,
44244424
}
44254425

4426+
#[derive(Diagnostic)]
4427+
#[diag("bounds cannot be used in this context")]
4428+
pub(crate) struct ForbiddenBound {
4429+
#[primary_span]
4430+
pub spans: Vec<Span>,
4431+
}
4432+
44264433
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
44274434
pub(super) enum TokenDescription {
44284435
ReservedIdentifier,

compiler/rustc_parse/src/parser/ty.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1433,8 +1433,24 @@ impl<'a> Parser<'a> {
14331433
self.expect_lt()?;
14341434
let params = self.parse_generic_params()?;
14351435
self.expect_gt()?;
1436+
1437+
// Parameters must not have bounds
1438+
let params = params
1439+
.into_iter()
1440+
.map(|mut param| {
1441+
if param.bounds.is_empty() {
1442+
param
1443+
} else {
1444+
let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
1445+
self.dcx().emit_err(errors::ForbiddenBound { spans });
1446+
param.bounds.clear();
1447+
param
1448+
}
1449+
})
1450+
.collect::<ThinVec<_>>();
1451+
14361452
// We rely on AST validation to rule out invalid cases: There must not be
1437-
// type or const parameters, and parameters must not have bounds.
1453+
// type or const parameters
14381454
Ok((params, Some(lo.to(self.prev_token.span))))
14391455
} else {
14401456
Ok((ThinVec::new(), None))

tests/ui/traits/const-traits/conditionally-const-trait-bound-syntax.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55

66
struct S<
77
T: for<'a> [const] Tr<'a> + 'static + [const] std::ops::Add,
8-
T: for<'a: 'b> [const] m::Trait<'a>,
8+
T: for<'a> [const] m::Trait<'a>,
99
>;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//@ edition: 2024
2+
3+
#![feature(non_lifetime_binders)]
4+
#![expect(incomplete_features)]
5+
6+
fn produce() -> for<A: A<{ //~ ERROR expected a type, found a trait
7+
//~^ ERROR bounds cannot be used in this context
8+
//~^^ ERROR late-bound type parameter not allowed on trait object types
9+
#[derive(Hash)]
10+
enum A {}
11+
struct A<A>;
12+
}>> Trait {} //~ ERROR cannot find trait `Trait` in this scope
13+
14+
fn main() {}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
error: bounds cannot be used in this context
2+
--> $DIR/bad-bounds.rs:6:24
3+
|
4+
LL | fn produce() -> for<A: A<{
5+
| ________________________^
6+
LL | |
7+
LL | |
8+
LL | | #[derive(Hash)]
9+
LL | | enum A {}
10+
LL | | struct A<A>;
11+
LL | | }>> Trait {}
12+
| |__^
13+
14+
error[E0405]: cannot find trait `Trait` in this scope
15+
--> $DIR/bad-bounds.rs:12:5
16+
|
17+
LL | }>> Trait {}
18+
| ^^^^^ not found in this scope
19+
20+
error: late-bound type parameter not allowed on trait object types
21+
--> $DIR/bad-bounds.rs:6:21
22+
|
23+
LL | fn produce() -> for<A: A<{
24+
| ^
25+
26+
error[E0782]: expected a type, found a trait
27+
--> $DIR/bad-bounds.rs:6:17
28+
|
29+
LL | fn produce() -> for<A: A<{
30+
| _________________^
31+
LL | |
32+
LL | |
33+
LL | | #[derive(Hash)]
34+
LL | | enum A {}
35+
LL | | struct A<A>;
36+
LL | | }>> Trait {}
37+
| |_________^
38+
39+
error: aborting due to 4 previous errors
40+
41+
Some errors have detailed explanations: E0405, E0782.
42+
For more information about an error, try `rustc --explain E0405`.

0 commit comments

Comments
 (0)