Skip to content

Commit 84a0f1e

Browse files
committed
Emit ForbiddenBound fatally if meeting complex bound
1 parent fbab541 commit 84a0f1e

File tree

5 files changed

+67
-10
lines changed

5 files changed

+67
-10
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
2-
use rustc_ast::{self as ast, AttrVec, NodeId, PatKind, attr, token};
2+
use rustc_ast::{self as ast, AttrVec, GenericBound, NodeId, PatKind, attr, token};
33
use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, Features};
44
use rustc_session::Session;
55
use rustc_session::parse::{feature_err, feature_warn};
@@ -152,7 +152,14 @@ impl<'a> PostExpansionVisitor<'a> {
152152
for param in params {
153153
if !param.bounds.is_empty() {
154154
let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
155-
self.sess.dcx().emit_err(errors::ForbiddenBound { spans });
155+
if param.bounds.iter().any(|bound| matches!(bound, GenericBound::Trait(_))) {
156+
// Issue #149695
157+
// Abort immediately otherwise items defined in complex bounds will be lowered into HIR,
158+
// which will cause ICEs when errors of the items visit unlowered parents.
159+
self.sess.dcx().emit_fatal(errors::ForbiddenBound { spans });
160+
} else {
161+
self.sess.dcx().emit_err(errors::ForbiddenBound { spans });
162+
}
156163
}
157164
}
158165
}

tests/ui/closures/binder/bounds-on-closure-type-binders.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,4 @@ fn main() {
1010
// Regression test for issue #119067
1111
let _ = for<T: Trait> || -> () {};
1212
//~^ ERROR bounds cannot be used in this context
13-
//~| ERROR late-bound type parameter not allowed on closures
1413
}

tests/ui/closures/binder/bounds-on-closure-type-binders.stderr

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,5 @@ error: bounds cannot be used in this context
44
LL | let _ = for<T: Trait> || -> () {};
55
| ^^^^^
66

7-
error: late-bound type parameter not allowed on closures
8-
--> $DIR/bounds-on-closure-type-binders.rs:11:17
9-
|
10-
LL | let _ = for<T: Trait> || -> () {};
11-
| ^
12-
13-
error: aborting due to 2 previous errors
7+
error: aborting due to 1 previous error
148

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//@ edition 2024
2+
3+
#![feature(non_lifetime_binders)]
4+
fn produce() -> for<A: A<{ //~ ERROR expected trait, found type parameter `A`
5+
//~^ ERROR bounds cannot be used in this context
6+
#[derive(Hash)]
7+
enum A {}
8+
struct A<A>; //~ ERROR the name `A` is defined multiple times
9+
}>> Trait {} //~ ERROR cannot find trait `Trait` in this scope
10+
11+
fn main() {}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
error[E0428]: the name `A` is defined multiple times
2+
--> $DIR/bad-bounds.rs:8:5
3+
|
4+
LL | enum A {}
5+
| ------ previous definition of the type `A` here
6+
LL | struct A<A>;
7+
| ^^^^^^^^^^^^ `A` redefined here
8+
|
9+
= note: `A` must be defined only once in the type namespace of this block
10+
11+
error[E0404]: expected trait, found type parameter `A`
12+
--> $DIR/bad-bounds.rs:4:24
13+
|
14+
LL | fn produce() -> for<A: A<{
15+
| _____________________-__^
16+
| | |
17+
| | found this type parameter
18+
LL | |
19+
LL | | #[derive(Hash)]
20+
LL | | enum A {}
21+
LL | | struct A<A>;
22+
LL | | }>> Trait {}
23+
| |__^ not a trait
24+
25+
error[E0405]: cannot find trait `Trait` in this scope
26+
--> $DIR/bad-bounds.rs:9:5
27+
|
28+
LL | }>> Trait {}
29+
| ^^^^^ not found in this scope
30+
31+
error: bounds cannot be used in this context
32+
--> $DIR/bad-bounds.rs:4:24
33+
|
34+
LL | fn produce() -> for<A: A<{
35+
| ________________________^
36+
LL | |
37+
LL | | #[derive(Hash)]
38+
LL | | enum A {}
39+
LL | | struct A<A>;
40+
LL | | }>> Trait {}
41+
| |__^
42+
43+
error: aborting due to 4 previous errors
44+
45+
Some errors have detailed explanations: E0404, E0405, E0428.
46+
For more information about an error, try `rustc --explain E0404`.

0 commit comments

Comments
 (0)