Skip to content

Document inferred const args (feature(generic_arg_infer)) #1835

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

BoxyUwU
Copy link
Member

@BoxyUwU BoxyUwU commented May 26, 2025

Tracking: rust-lang/rust#85077
Stabilization: rust-lang/rust#141610
Stabilization report: rust-lang/rust#141610 (comment)

@rustbot rustbot added the S-waiting-on-review Status: The marked PR is awaiting review from a maintainer label May 26, 2025
@ehuss ehuss added the S-waiting-on-stabilization Waiting for a stabilization PR to be merged in the main Rust repository label May 26, 2025
@traviscross
Copy link
Contributor

@ehuss and I are reviewing this on a call. This is a bit tough to review in that the content was both moved and changed in one commit. If possible, it'd be helpful to us if this could be broken out into (at least) two commits; one to move the content, then the other or others to make the changes and additions.

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: The marked PR is awaiting some action (such as code changes) from the PR author. and removed S-waiting-on-review Status: The marked PR is awaiting review from a maintainer labels May 27, 2025
@BoxyUwU BoxyUwU force-pushed the const-generics-stuff branch from da274a2 to 48cfb78 Compare May 27, 2025 22:46
@BoxyUwU
Copy link
Member Author

BoxyUwU commented May 27, 2025

Sure, done

@BoxyUwU
Copy link
Member Author

BoxyUwU commented May 27, 2025

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: The marked PR is awaiting review from a maintainer and removed S-waiting-on-author Status: The marked PR is awaiting some action (such as code changes) from the PR author. labels May 27, 2025
@BoxyUwU
Copy link
Member Author

BoxyUwU commented Jun 7, 2025

@ehuss @traviscross any chance y'all will be able to get around to reviewing this soon? The stabilization PR is now ready to be merged and it'd be unfortunate to block a relatively minor feature that's already been waiting years, on this PR.

@BoxyUwU
Copy link
Member Author

BoxyUwU commented Jun 9, 2025

Alternatively I could file a separate smaller PR that just adds a small extra bit of wording to the existing section noting that _ can be used as an argument to const parameters. Then leave this more involved clean up/rework of const generics handling in the reference off of the "blocking" path for feature stabilization.

@ehuss
Copy link
Contributor

ehuss commented Jun 9, 2025

If possible, I think it would be best to drop the rearrangement commit. This probably isn't the organization we'll land on, and I would prefer to keep these as separate concerns so they don't block one another.

@BoxyUwU BoxyUwU force-pushed the const-generics-stuff branch from 48cfb78 to f356de0 Compare June 9, 2025 22:32
@BoxyUwU BoxyUwU changed the title Split const generics in two and document inferred consts Document inferred const args (feature(generic_arg_infer)) Jun 9, 2025
@BoxyUwU
Copy link
Member Author

BoxyUwU commented Jun 9, 2025

Ok this should be fine now

@BoxyUwU BoxyUwU force-pushed the const-generics-stuff branch 2 times, most recently from f5f99d4 to b63bb63 Compare June 9, 2025 23:02
@BoxyUwU BoxyUwU force-pushed the const-generics-stuff branch from b63bb63 to 4b5878f Compare June 9, 2025 23:09
@BoxyUwU
Copy link
Member Author

BoxyUwU commented Jun 11, 2025

@traviscross @ehuss friendly poke about this :)

Copy link
Contributor

@ehuss ehuss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little lost, as it seems like there are two distinct things being supported here:

  1. _ in generic args: foo::<_>()
  2. _ in array expression repeat lengths: [123; _]

Am I understanding that correctly? If so, shouldn't there be some update to the array expression chapter? And the underscore-expr.md may need a significant update to mention that it is allowed for array repeats.

Comment on lines +233 to +237
```grammar,const
InferredConst ->
`_`
| `(` InferredConst `)`
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I fully understand this grammar since it isn't referred to anywhere.

Am I understanding correctly that this is added for GenericArgsConst? Or is it somewhere else? That is, should it be:

GenericArgsConst ->
      BlockExpression
    | LiteralExpression
    | `-` LiteralExpression
    | SimplePathSegment
    | InferredConst

InferredConst ->
      `_`
    | `(` InferredConst `)`

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep exactly 👍 It's a little bit funny because it means that InferredType and InferredConst share the same grammar but I'm not sure that matters too much for this?

Comment on lines +243 to +244
r[items.generics.const.inferred.constraint]
It cannot be used in item signatures.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not quite following this. If we are defining this as a new form allowed in generic args, why would there be a rule that it is not allowed in item signatures?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't allow type inference in signatures in general, not just as a restriction on const arguments. For example this is an error on stable:

struct Foo<T>(T);
fn bar(param: Foo<_>) {}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this already stated in type.inferred.constraint (inferred.md)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah we state that for _ type arguments but I felt like like we should note that the restriction applies for _ const arguments too when discussing them as it might be confusing otherwise; people might get the idea that you can use _ const arguments in signatures.


r[items.generics.const.inferred.intro]
The inferred const asks the compiler to infer the const argument if possible
based on the surrounding information available.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a semi-realistic looking example here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yeah sure

@BoxyUwU
Copy link
Member Author

BoxyUwU commented Jun 11, 2025

I'm a little lost, as it seems like there are two distinct things being supported here

There is one thing being added, we support _ (optionally wrapped in arbitrary many parens) as const arguments. The repeat count of an array expr is a const argument so falls under the same thing as in let a: [u8; _] = .... This is equivalent in functionality to how we support _ (optionally wrapped in arbitrary many parens) as type arguments (e.g. let a: [_; 2]).

I didn't think the array-expr chapter would need updating as I've updated the definition of a const argument but it seems like the reference attempts to separately specify repeat expr counts from const arguments. This also means that the chapter does not currently talk about the fact that [0x1; N + 1] is illegal. I'm not sure what to do about that, can we just leave it as-is or would you prefer me to update the array-expr chapter to specify repeat counts as being const arguments.

And the underscore-expr.md may need a significant update

I don't think we need to update underscore-expr, this feature is (confusingly) entirely orthogonal from _ as an expression. [u8; _] isnt giving the _ expression new meaning, its adding a new kind of const argument that is not an expression.

@ehuss
Copy link
Contributor

ehuss commented Jun 11, 2025

The repeat count of an array expr is a const argument

If I'm understanding correctly, we define the array repeat length as a const expression with the limitations defined in const context among other places.

If we are adding _ as an allowed expression for a const expression in this context, then it seems like something that needs to be added to const chapter and the array chapter since there is nothing that says it is allowed in that position. For example, the const expr section doesn't say it is allowed. Similarly, as I understand it, the operand for the array expression length expression is any Expression with the restriction that it has to play by the const-expression limitations (and various other limitations like items.generics.const.standalone.

falls under the same thing as in let a: [u8; _] = ....

I'm not quite following this. That looks like an _ in type position which we define as the inferred type which seems to be something different from _ in expressiosn position.

I understand that there may be some implementation similarities, but as we define type vs expression as two different concepts, I would think that introducing _ in expression contexts for array lengths is something novel here.

This also means that the chapter does not currently talk about the fact that [0x1; N + 1] is illegal.

I believe these limitations are defined in https://doc.rust-lang.org/nightly/reference/const_eval.html#const-context and https://doc.rust-lang.org/nightly/reference/items/generics.html#r-items.generics.const.standalone.

@BoxyUwU
Copy link
Member Author

BoxyUwU commented Jun 11, 2025

Sorry I feel like I'm repeating myself a bit here and am not sure how to explain this better. This feature is orthogonal to underscores as an expression. It's not that _ is now a valid expression by itself, it's that there is a new kind of const generic argument (which happens to have the same syntax as the _ expression).

Maybe the core confusion here is about this distinction between a const expression and a const argument?

If I'm understanding correctly, we define the array repeat length as a const expression

I think the entire way that const generics are handled in the reference right now is just not structured right for this feature to be honest ^^.

It doesn't make sense to talk about const arguments as being "expressions with more restrictions"; _ arguments are not expressions and are instead a new kind of const argument. But as far as I can tell there is no distinct concept of a "const argument" in the reference (like how there are different kinds of for type arguments). Instead everywhere simply specifies things as being "const expressions" with some additional restrictions.

I originally tried to refactor the reference to properly talk about const arguments as a real concept in the type system section with different sections for each kind of const argument. But that was quite a big change and this seemed smaller/easier to review.

Do you think you'd prefer going back to the old approach that has more involved explanations of this topic? It sounds like the new version of this PR is actually quite confusing in practice which is unfortunate.

Admittedly, I'm finding this PR to be quite stressful. I'd really like to get generic_arg_infer stabilized and having it be blocked on this when there's such a disconnect between the language itself and how the reference specifies things is making me worried that it's going to wind up blocked for a really long time.

I'd be more than happy to put a bunch of time into documenting things in the reference and talking things over with you, but if that's where things need to go in order to get something you're happy with would it be possible to just land the stabilization PR first and continue work on documenting this afterwards?

I'm not quite following this. That looks like an _ in type position

I guess with this terminology it would be correct to say that the repeat count of array exprs is a type position ^^. Though being nitpicky it doesn't make sense to say that a _ there is an inferred type because it is not a type, its a const generic value. Hence why I've added the concept of an "inferred const" to the reference which roughly mirrors the structure of the inferred type documentation.

I believe these limitations are defined in https://doc.rust-lang.org/nightly/reference/const_eval.html#const-context and https://doc.rust-lang.org/nightly/reference/items/generics.html#r-items.generics.const.standalone.

Ah yes you're right it is documented 👍 Then I guess array-expr really doesn't need updating because it is specified as being a const generic argument :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: The marked PR is awaiting review from a maintainer S-waiting-on-stabilization Waiting for a stabilization PR to be merged in the main Rust repository
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants