Skip to content

Tracking Issue for function_arg_const_generics #163261

Description

@bit-aloo

The feature gate for the issue is #![feature(function_arg_const_generics)]. Using it requires #![feature(min_generic_const_args)] to be enabled as well.

Background

We are tracking this effort in https://github.com/rust-lang/project-const-generics/issues/66 . The idea is to support functions with const arguments. I think the main use case will be vendor intrinsics that take function arguments which must be compile time constants.

A bit of history, we previously used match statements to manually monomorphize these intrinsics, which leads to significant MIR bloat. We then introduced the #[rustc_args_required_const] attribute, which was removed in 2021, with const generics intended as its replacement. This eventually became #[rustc_legacy_const_generics], which we have been moving towards deprecating ever since. More on this can be found here: #146613.

#[rustc_legacy_const_generics(0)]
fn foo<const N: usize>() {}

foo::<1>(); // What we use now
foo(1);     // Legacy function argument syntax

Here, 0 is the position in the call argument list. Under the hood, we rewrite the call during AST lowering, after name resolution. Each call is checked against the callee's attribute, and the specified arguments are moved into the generic argument list. The moved args are wrapped in anon const blocks, so something like foo(1 + 2) works as well. By the time HIR exists, the call already looks like foo::<{ 1 + 2 }>().

There are a few restrictions with this approach:

  • Cross-crate only
  • Free functions only

The new feature is intended to replace this legacy mechanism by allowing const parameters directly in function and method argument lists. The proposed syntax is const IDENT: Ty, which would desugar into an ordinary const generic parameter with an arg position marker.

For example:

fn foo(const n: usize) {}
foo(42);

This will have its own feature gate, separate from but dependent on min_generic_const_args (mgca). The call arguments will go through mgca's existing direct const args lowering pipeline.

Super experimental.

About tracking issues

Tracking issues are used to record the overall progress of implementation.
They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.
Discussion comments will get marked as off-topic or deleted.
Repeated discussions on the tracking issue may lead to the tracking issue getting locked.

Steps

  • Implementation PR with basic feature support, covering parsing, the args position marker, lowering, and the necessary plumbing.
  • Follow up on which additional functionality we want to support and what restrictions we want to enforce.

Unresolved Questions

  • Should we support turbofish syntax? We should either support it fully or not at all, rather than allowing partial states between const parameters and arguments. The reason I am asking because stdarch's existing stable signatures use the turbofish form.
  • Should complex expressions be a hard error?
  • How should const parameters in function arguments be represented in function pointer types and Fn sugar? Or should we just error out for such cases.

Implementation history

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-genericsArea: const generics (parameters and arguments)B-experimentalBlocker: In-tree experiment; RFC pending, not yet approved or unneeded (requires FCP to stabilize).C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCF-gca_min_const_items`#![feature(gca_min_const_items)]` (previously: `min_generic_const_args`)T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions