Skip to content

Commit 2cc5c51

Browse files
committed
Fix ICE when using function pointer as const generic parameter
Add bounds check in prohibit_explicit_late_bound_lifetimes to prevent index out of bounds panic when args.args is empty. Add regression test to ensure function pointers in const generics produce proper error messages instead of ICE.
1 parent 46bb414 commit 2cc5c51

6 files changed

Lines changed: 95 additions & 6 deletions

File tree

compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,10 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes(
616616
}
617617

618618
if let Some(span_late) = def.has_late_bound_regions {
619+
if args.args.is_empty() {
620+
return ExplicitLateBound::No;
621+
}
622+
619623
let msg = "cannot specify lifetime arguments explicitly \
620624
if late bound lifetime parameters are present";
621625
let note = "the late bound lifetime parameter is introduced here";

tests/crashes/137084.rs

Lines changed: 0 additions & 6 deletions
This file was deleted.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//@ check-fail
2+
//
3+
// Regression test for https://github.com/rust-lang/rust/issues/137084
4+
// Previously caused ICE when using function item as const generic argument
5+
6+
#![feature(min_generic_const_args)]
7+
#![allow(incomplete_features)]
8+
9+
fn a<const b: i32>() {}
10+
fn d(e: &String) {
11+
a::<d>
12+
//~^ ERROR mismatched types
13+
//~| ERROR the constant `d` is not of type `i32`
14+
}
15+
16+
fn main() {}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/fn-item-as-const-arg-137084.rs:11:5
3+
|
4+
LL | fn a<const b: i32>() {}
5+
| -------------------- function `a` defined here
6+
LL | fn d(e: &String) {
7+
LL | a::<d>
8+
| ^^^^^^ expected `()`, found fn item
9+
|
10+
= note: expected unit type `()`
11+
found fn item `fn() {a::<d>}`
12+
help: try adding a return type
13+
|
14+
LL | fn d(e: &String) -> fn() {
15+
| +++++++
16+
help: use parentheses to call this function
17+
|
18+
LL | a::<d>()
19+
| ++
20+
21+
error: the constant `d` is not of type `i32`
22+
--> $DIR/fn-item-as-const-arg-137084.rs:11:9
23+
|
24+
LL | a::<d>
25+
| ^ expected `i32`, found fn item
26+
|
27+
note: required by a const generic parameter in `a`
28+
--> $DIR/fn-item-as-const-arg-137084.rs:9:6
29+
|
30+
LL | fn a<const b: i32>() {}
31+
| ^^^^^^^^^^^^ required by this const generic parameter in `a`
32+
33+
error: aborting due to 2 previous errors
34+
35+
For more information about this error, try `rustc --explain E0308`.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@ check-fail
2+
//
3+
// Regression test for https://github.com/rust-lang/rust/issues/151186
4+
5+
#![feature(min_generic_const_args)]
6+
#![allow(incomplete_features)]
7+
8+
trait Maybe<T> {}
9+
10+
trait MyTrait<const F: fn() -> ()> {}
11+
//~^ ERROR using function pointers as const generic parameters is forbidden
12+
13+
fn foo<'a>(x: &'a ()) -> &'a () { x }
14+
15+
impl<T> Maybe<T> for T where T: MyTrait<{ foo }> {}
16+
//~^ ERROR the constant `foo` is not of type `fn()`
17+
18+
fn main() {}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error: using function pointers as const generic parameters is forbidden
2+
--> $DIR/ice-151186-fn-ptr-in-where-clause.rs:10:24
3+
|
4+
LL | trait MyTrait<const F: fn() -> ()> {}
5+
| ^^^^^^^^^^
6+
|
7+
= note: the only supported types are integers, `bool`, and `char`
8+
9+
error: the constant `foo` is not of type `fn()`
10+
--> $DIR/ice-151186-fn-ptr-in-where-clause.rs:15:33
11+
|
12+
LL | impl<T> Maybe<T> for T where T: MyTrait<{ foo }> {}
13+
| ^^^^^^^^^^^^^^^^ expected fn pointer, found fn item
14+
|
15+
note: required by a const generic parameter in `MyTrait`
16+
--> $DIR/ice-151186-fn-ptr-in-where-clause.rs:10:15
17+
|
18+
LL | trait MyTrait<const F: fn() -> ()> {}
19+
| ^^^^^^^^^^^^^^^^^^^ required by this const generic parameter in `MyTrait`
20+
21+
error: aborting due to 2 previous errors
22+

0 commit comments

Comments
 (0)