Skip to content

Allow referencing generic parameters inside array length expressions #140524

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

Closed
tmandry opened this issue Apr 30, 2025 · 5 comments
Closed

Allow referencing generic parameters inside array length expressions #140524

tmandry opened this issue Apr 30, 2025 · 5 comments
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues. T-lang Relevant to the language team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@tmandry
Copy link
Member

tmandry commented Apr 30, 2025

Today this works:

fn bar<const N: usize>() {
    let x = [0u32; N];
}

but this does not:

trait Foo {
    const C: usize;
}

fn foo<T: Foo>() {
    let x = [0u32; T::C];
}

with the following error:

error: constant expression depends on a generic parameter
 --> src/lib.rs:7:20
  |
7 |     let y = [0u32; T::C];
  |                    ^^^^
  |
  = note: this may fail depending on what value the parameter takes

We talked about this in the lang meeting today, and the consensus of those present was that this is not a sufficient justification for disallowing this. In particular, we are happy to allow this and issue a post-monomorphization error in the cases where the value of the const makes the array too large.

Ideally I'd like us to FCP this issue to formalize the consensus, but first want to collect any context we might be missing.

cc @nikomatsakis who had some context and was going to post it here.
cc @rust-lang/types; is there another justification we're missing?
cc @rust-lang/lang

@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Apr 30, 2025
@lcnr
Copy link
Contributor

lcnr commented Apr 30, 2025

That is just feature(min_generic_const_args) or feature(generic_const_exprs). I am somewhat surprised by this issue 🤔

feature(min_generic_const_args) is already actively getting worked on by @BoxyUwU and a project goal: https://rust-lang.github.io/rust-project-goals/2024h2/min_generic_const_arguments.html

@lcnr
Copy link
Contributor

lcnr commented Apr 30, 2025

This is desirable and was an explicit limitation when stabilizing feature(min_generic_consts): #79135.

Handling this correctly has a lot of both technical and design questions, e.g. whether to allow constants which may result in monomorphization time evaluation errors in the type system and how equality of generic constants should work.

@compiler-errors
Copy link
Member

compiler-errors commented Apr 30, 2025

Yeah, this is definitely not something we support in the type system at the moment. I'm a bit surprised as well that the issue body suggests that we FCP this -- it feels somewhat premature, rather than straight-up asking whether this is something we can support 😸

At best this is a diagnostics issue for now, and we can be a bit more explicit in justifying why we don't support this. For the record, we accidentally stabilized a somewhat morally related code piece of code:

fn foo<T>() {
    let x = [0u32; std::mem::size_of::<&T>()];
}

This was not ever intended, though. See #76200 for an FCW. The only thing we support today (and we're definitely not planning to remove!!) is bare generic parameters, like [expr; C] and let x: [(); C]. Any more complex expressions are as lcnr said above should be gated under min_generic_const_args (or GCE) and should only be stabilized if/when those are.

@BoxyUwU BoxyUwU closed this as not planned Won't fix, can't repro, duplicate, stale Apr 30, 2025
@traviscross traviscross added T-lang Relevant to the language team, which will review and decide on the PR/issue. C-discussion Category: Discussion or questions that doesn't represent real issues. T-types Relevant to the types team, which will review and decide on the PR/issue. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Apr 30, 2025
@nikomatsakis
Copy link
Contributor

nikomatsakis commented Apr 30, 2025

OK, woah. It seems clear that this issue has upset folks. I assure you it was not the intent of @tmandry to step on any toes here, but rather to try and unblock what seemed to be a stalled conversation and to gather more context. If I am reading the room correctly, I think part of the frustration is that indeed the conversation is not especially stalled, there's ongoing work in the form of the project goal, etc. Is that correct? That is, perhaps this issue came off as a "why don't you just" sort of thing that is assuming things are easy when in fact they are complicated?

Let me give a bit of context as to the origin of this issue. We were in a lang-team meeting and discussing the distinction between, say, [0; C] and [0; T::FOO]. I was saying that my recollection as to the distinction there has to do with how, in const generics, we apply a "valtree transformation", so we know that the const C, at monomorphization time, will represent an integer value that we can compute. In contrast, this may not be the case for T::FOO. I remembered that a lot of the concerns in the past centered around the possibility of encountering overflow errors etc in a post-monomorphization context. My impression was that we were in a situation where most everybody agreed with what should be done but had a sense that "somebody else" might have concerns, and so we thought maybe some kind of issue and/or FCP might eliminate that fear.

Now that I think about it now, this explanation seems to have some holes. Among other things, even though C may have a valtree, it could still be a very large value (e.g., >isize::MAX), so there still seems to be the potential for a post-monomorphization error there. I had also forgotten about the project goal. And I was planning to go off and look for the hackmd I wrote when we were discussing stabilization of unsafe values in constants Rust-For-Linux because I remember understanding this more crisply at one point.

In any case, what I will say is, this is a pretty complex area and there has been a lot of shifts over time and questions over time. So I would encourage a bit of benefit of the doubt -- we're all just trying to wrap our head around what are the blockers and to reach a shared understanding of what the goal is, not to disparage anyone's work or push half-baked things to stabilization or anything like that!

@tmandry
Copy link
Member Author

tmandry commented Apr 30, 2025

I assure you it was not the intent of @tmandry to step on any toes here, but rather to try and unblock what seemed to be a stalled conversation and to gather more context.

That's accurate, and I'm happy to take feedback on how that can be communicated more clearly.

I'm a bit surprised as well that the issue body suggests that we FCP this -- it feels somewhat premature, rather than straight-up asking whether this is something we can support 😸

Is the issue not clear that it is asking for context? I don't think it's inappropriate to state my intention, as that can help clarify the kind of context that's needed.

We talked about this in the lang meeting today, and the consensus of those present was that this is not a sufficient justification for disallowing this.

Quoting myself: I can see how this is easy to interpret as "why don't you just". To be crystal clear, my intention has been to convey that the justification given in the error message is not enough of a reason to disallow this. This is now a moot point since that justification is itself not the blocker, but yes we might want to consider improving the diagnostic.

In any case, many thanks for your work on min_generic_const_args (@BoxyUwU in particular) and for the reminder that this is being worked on. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues. T-lang Relevant to the language team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants