推断出的 const 泛型参数:征集测试!

2025 年 3 月 5 日 · BoxyUwU 代表 const 泛型项目组

我们很高兴地宣布,feature(generic_arg_infer) 功能正接近稳定化。在这篇文章中,我们想稍微谈谈这个功能的作用,以及接下来的计划。

什么是 feature(generic_arg_infer)

feature(min_const_generics)2021 年初 稳定 时,它不包含使用 _ 作为显式 const 参数的能力

fn foo() {
  // This errors due to `_` as an array length being unsupported
  let a: [u8; _] = [Default::default()];
  // This is legal as `_` is permitted as a type argument
  let b: [_; 1] = a;
}

这完全是语法上的限制;可以完全省略可能涉及 const 参数的泛型参数列表

fn foo<const N: usize>(_: [u8; N]) {}

fn bar() {
  // This errors due to `_` as a const argument being unsupported
  foo::<_>([1]);
  // This is legal as even though the const argument is *inferred*
  // there is no explicit `_` written.
  foo([1]);
}

编译器一直能够推断 const 泛型参数的值,只是显式要求推断 const 参数的能力尚不稳定。

目前也无法推断重复表达式的长度。这样做需要将表达式移动到另一个函数中,该函数以数组长度为泛型。

fn foo() {
    // This errors due to `_` as a repeat count being unsupported
    let a: [_; 1] = [String::new(); _];
}

有了 feature(generic_arg_infer),所有之前的示例都能编译了。这应该会让人觉得是 Rust "理所当然" 应该支持的功能。

接下来的计划

我们最近 大幅重写了它的实现,现在应该可以稳定化了。我们非常希望您能在最新的 nightly 版本上试用它,并报告遇到的任何问题。

致谢

我最近推动这个功能准备进行测试的工作,离不开许多其他人的帮助。

非常感谢 @lcnr@JulianKnodt 提供了 generic_arg_infer 的初始实现,@camelid 重构了 const 泛型参数的表示方式使其更加灵活,@voidc 帮助统一了我们处理数组长度和 const 泛型参数的方式,@lcnr 在抽象推断类型/const/泛型参数差异的设计工作,最后感谢 @compiler-errors 审查了关于此功能的许多 PR 和实现决策。