Rollup merge of #151219 - enthropy7:main, r=BoxyUwU

Fixed ICE when using function pointer as const generic parameter

added bounds check in prohibit_explicit_late_bound_lifetimes to prevent index out of bounds panic when args.args is empty. also regression test here to ensure function pointers in const generics produce proper error messages instead of ICE.

Fixes rust-lang/rust#151186
Fixes rust-lang/rust#137084
This commit is contained in:
Jonathan Brouwer 2026-01-21 22:24:03 +01:00 committed by GitHub
commit afc18426cb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 90 additions and 12 deletions

View file

@ -627,13 +627,10 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes(
position: GenericArgPosition,
) -> ExplicitLateBound {
let param_counts = def.own_counts();
let infer_lifetimes = position != GenericArgPosition::Type && !args.has_lifetime_params();
if infer_lifetimes {
return ExplicitLateBound::No;
}
if let Some(span_late) = def.has_late_bound_regions {
if let Some(span_late) = def.has_late_bound_regions
&& args.has_lifetime_params()
{
let msg = "cannot specify lifetime arguments explicitly \
if late bound lifetime parameters are present";
let note = "the late bound lifetime parameter is introduced here";

View file

@ -1,6 +0,0 @@
//@ known-bug: #137084
#![feature(min_generic_const_args)]
fn a<const b: i32>() {}
fn d(e: &String) {
a::<d>
}

View file

@ -0,0 +1,14 @@
// Regression test for https://github.com/rust-lang/rust/issues/137084
// Previously caused ICE when using function item as const generic argument
#![feature(min_generic_const_args)]
#![allow(incomplete_features)]
fn a<const b: i32>() {}
fn d(e: &String) {
a::<d>
//~^ ERROR mismatched types
//~| ERROR the constant `d` is not of type `i32`
}
fn main() {}

View file

@ -0,0 +1,35 @@
error[E0308]: mismatched types
--> $DIR/fn-item-as-const-arg-137084.rs:9:5
|
LL | fn a<const b: i32>() {}
| -------------------- function `a` defined here
LL | fn d(e: &String) {
LL | a::<d>
| ^^^^^^ expected `()`, found fn item
|
= note: expected unit type `()`
found fn item `fn() {a::<d>}`
help: try adding a return type
|
LL | fn d(e: &String) -> fn() {
| +++++++
help: use parentheses to call this function
|
LL | a::<d>()
| ++
error: the constant `d` is not of type `i32`
--> $DIR/fn-item-as-const-arg-137084.rs:9:9
|
LL | a::<d>
| ^ expected `i32`, found fn item
|
note: required by a const generic parameter in `a`
--> $DIR/fn-item-as-const-arg-137084.rs:7:6
|
LL | fn a<const b: i32>() {}
| ^^^^^^^^^^^^ required by this const generic parameter in `a`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View file

@ -0,0 +1,16 @@
// Regression test for https://github.com/rust-lang/rust/issues/151186
#![feature(min_generic_const_args)]
#![allow(incomplete_features)]
trait Maybe<T> {}
trait MyTrait<const F: fn() -> ()> {}
//~^ ERROR using function pointers as const generic parameters is forbidden
fn foo<'a>(x: &'a ()) -> &'a () { x }
impl<T> Maybe<T> for T where T: MyTrait<{ foo }> {}
//~^ ERROR the constant `foo` is not of type `fn()`
fn main() {}

View file

@ -0,0 +1,22 @@
error: using function pointers as const generic parameters is forbidden
--> $DIR/ice-151186-fn-ptr-in-where-clause.rs:8:24
|
LL | trait MyTrait<const F: fn() -> ()> {}
| ^^^^^^^^^^
|
= note: the only supported types are integers, `bool`, and `char`
error: the constant `foo` is not of type `fn()`
--> $DIR/ice-151186-fn-ptr-in-where-clause.rs:13:33
|
LL | impl<T> Maybe<T> for T where T: MyTrait<{ foo }> {}
| ^^^^^^^^^^^^^^^^ expected fn pointer, found fn item
|
note: required by a const generic parameter in `MyTrait`
--> $DIR/ice-151186-fn-ptr-in-where-clause.rs:8:15
|
LL | trait MyTrait<const F: fn() -> ()> {}
| ^^^^^^^^^^^^^^^^^^^ required by this const generic parameter in `MyTrait`
error: aborting due to 2 previous errors