Skip to content
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

Introduce feature(generic_const_parameter_types) #137617

Merged
merged 1 commit into from
Mar 1, 2025

Conversation

BoxyUwU
Copy link
Member

@BoxyUwU BoxyUwU commented Feb 25, 2025

Allows to define const generic parameters whose type depends on other generic parameters, e.g. Foo<const N: usize, const ARR: [u8; N]>;

Wasn't going to implement for this for a while until we could implement it with bad_inference.rs resolved but apparently the project simd folks would like to be able to use this for some intrinsics and the inference issue isn't really a huge problem there aiui. (cc @workingjubilee )

@rustbot
Copy link
Collaborator

rustbot commented Feb 25, 2025

r? @jieyouxu

rustbot has assigned @jieyouxu.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 25, 2025
@rustbot
Copy link
Collaborator

rustbot commented Feb 25, 2025

HIR ty lowering was modified

cc @fmease

Comment on lines -6 to -7
|
= note: const parameters may not be used in the type of const parameters
Copy link
Member Author

Choose a reason for hiding this comment

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

I couldn't figure out how to retain this note as now we just fail to resolve the N (i.e. it's res is a Res::Err) instead of previously where it would resolve to N and then we'd error when validating the resolution.

Honestly though I think this note didn't help very much anyway. It's almost a complete copy of the top level error message where its only new information is the kind of parameter that N is. I don't expect that to be very useful information and we don't provide it when you use a forward declared generic parameter in a parameter's default either:

error[E0128]: generic parameters with a default cannot use forward declared identifiers
 --> src/lib.rs:1:21
  |
1 | struct Foo<T = [u8; N], const N: usize = 1>(T);
  |                     ^ defaulted generic parameters cannot be forward declared

@rust-log-analyzer

This comment has been minimized.

Comment on lines +16 to +17
// Requires inferring `T`/`N` from `12_u8` and `2` respectively.
let a = foo::<_, _, { [12_u8; 2] }>();
Copy link
Member

Choose a reason for hiding this comment

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

hm, is it different for these cases?

fn main() {
    let a = foo::<_, _, { [5_u8, 6] }>();
    let b: [u8; 2] = foo::<_, _, { [5, 6] }>();
}

Copy link
Member Author

Choose a reason for hiding this comment

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

those would both error, the requirement is that from looking at the generic arguments to foo you must be able to determine the full inferred type of the const parameter without performing any type inference or trait solving. (though this is only the case when the argument is an anonymous constant, as opposed to a _ or a usage of a generic parameter or some mgca arg)

@jieyouxu
Copy link
Member

r? types

@rustbot rustbot added the T-types Relevant to the types team, which will review and decide on the PR/issue. label Feb 25, 2025
@rustbot rustbot assigned lcnr and unassigned jieyouxu Feb 25, 2025
@BoxyUwU BoxyUwU force-pushed the generic_const_parameter_types branch from 6c02c7d to 2fa5b32 Compare February 25, 2025 17:02
Copy link
Contributor

@lcnr lcnr left a comment

Choose a reason for hiding this comment

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

looking good :3

@BoxyUwU BoxyUwU force-pushed the generic_const_parameter_types branch from 2fa5b32 to 4d2677e Compare February 25, 2025 17:52
@fmease fmease added the F-generic_const_parameter_types `#![feature(generic_const_parameter_types)]` label Feb 25, 2025
Copy link
Contributor

@lcnr lcnr left a comment

Choose a reason for hiding this comment

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

final nit, then r=me

@BoxyUwU BoxyUwU force-pushed the generic_const_parameter_types branch 2 times, most recently from 362de31 to e35461a Compare February 26, 2025 14:52
@BoxyUwU BoxyUwU force-pushed the generic_const_parameter_types branch from e35461a to f47c2d5 Compare February 26, 2025 15:23
@BoxyUwU
Copy link
Member Author

BoxyUwU commented Feb 28, 2025

(changed impl non trivially in how we handle paths to const params so needs reivew again)

@@ -326,6 +326,12 @@ pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> {
self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
}

fn has_regions(&self) -> bool {
self.has_type_flags(
TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_RE_ERASED | TypeFlags::HAS_RE_BOUND,
Copy link
Contributor

Choose a reason for hiding this comment

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

🤔 we should support bound regions and not check for them

maybe has_free_or_erased_regions... or actually, has_free_regions should include RE_ERASED imo, so we should have has_free_non_erased_regions :<

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm yeah ur right there's no real reason to forbid bound regions. I was being a bit overly conservative here :3 I just removed has_regions entirely because if its only FREE_REGIONS | ERASED then its not that bad to just do it in-line in args lowering.

It is somewhat weird that has_free_regions doesnt proc on RE_ERASED 🤔

Copy link
Contributor

@lcnr lcnr left a comment

Choose a reason for hiding this comment

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

nit, then r=me, i don't rly care how u handle it

@BoxyUwU BoxyUwU force-pushed the generic_const_parameter_types branch from f47c2d5 to df5b279 Compare February 28, 2025 20:44
@BoxyUwU
Copy link
Member Author

BoxyUwU commented Feb 28, 2025

rebased and resolved nit

@bors r=lcnr

@bors
Copy link
Contributor

bors commented Feb 28, 2025

📌 Commit df5b279 has been approved by lcnr

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 28, 2025
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Mar 1, 2025
…pes, r=lcnr

Introduce `feature(generic_const_parameter_types)`

Allows to define const generic parameters whose type depends on other generic parameters, e.g. `Foo<const N: usize, const ARR: [u8; N]>;`

Wasn't going to implement for this for a while until we could implement it with `bad_inference.rs` resolved but apparently the project simd folks would like to be able to use this for some intrinsics and the inference issue isn't really a huge problem there aiui. (cc `@workingjubilee` )
bors added a commit to rust-lang-ci/rust that referenced this pull request Mar 1, 2025
…iaskrgr

Rollup of 8 pull requests

Successful merges:

 - rust-lang#136503 (Tweak output of const panic diagnostic)
 - rust-lang#137390 (tests: fix up new test for nocapture -> capture(none) change)
 - rust-lang#137617 (Introduce `feature(generic_const_parameter_types)`)
 - rust-lang#137719 (Add missing case explanation for doc inlined re-export of doc hidden item)
 - rust-lang#137763 (Use `mk_ty_from_kind` a bit less, clean up lifetime handling in borrowck)
 - rust-lang#137769 (Do not yeet `unsafe<>` from type when formatting unsafe binder)
 - rust-lang#137776 (Some `rustc_transmute` cleanups)
 - rust-lang#137800 (Remove `ParamEnv::without_caller_bounds`)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 415b207 into rust-lang:master Mar 1, 2025
6 checks passed
@rustbot rustbot added this to the 1.87.0 milestone Mar 1, 2025
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Mar 1, 2025
Rollup merge of rust-lang#137617 - BoxyUwU:generic_const_parameter_types, r=lcnr

Introduce `feature(generic_const_parameter_types)`

Allows to define const generic parameters whose type depends on other generic parameters, e.g. `Foo<const N: usize, const ARR: [u8; N]>;`

Wasn't going to implement for this for a while until we could implement it with `bad_inference.rs` resolved but apparently the project simd folks would like to be able to use this for some intrinsics and the inference issue isn't really a huge problem there aiui. (cc ``@workingjubilee`` )
jieyouxu added a commit to jieyouxu/rust that referenced this pull request Mar 12, 2025
…r=BoxyUwU

Disentangle `ForwardGenericParamBan` and `ConstParamTy` ribs

In rust-lang#137617, the `ConstParamTy` rib was adjusted to act kinda like the `ForwardGenericParamBan`. However, this means that it no longer served its purpose banning generics from *parent items*. Although we still are checking for param type validity using the `ConstParamTy_` trait, which means that we weren't accepting code we shouldn't, I think it's a bit strange for us not to be rejecting code like this during *resolution* and instead letting these malformed const generics leak into the type system:

```rust
trait Foo<T> {
  fn bar<const N: T>() {}
}
```

This PR does a few things:
1. Introduce a `ForwardGenericParamBanReason` enum, and start using the `ForwardGenericParamBan` rib to ban forward-declared params in const tys when `generic_const_parameter_types` is enabled.
2. Start using the `ConstParamTy` rib to ban *all* generics when `generic_const_parameter_types` is disabled.
3. Improve the diagnostics for both of the cases above, and for forward-declared params in parameter defaults too :3

r? `@BoxyUwU` or reassign
Manishearth added a commit to Manishearth/rust that referenced this pull request Mar 12, 2025
…r=BoxyUwU

Disentangle `ForwardGenericParamBan` and `ConstParamTy` ribs

In rust-lang#137617, the `ConstParamTy` rib was adjusted to act kinda like the `ForwardGenericParamBan`. However, this means that it no longer served its purpose banning generics from *parent items*. Although we still are checking for param type validity using the `ConstParamTy_` trait, which means that we weren't accepting code we shouldn't, I think it's a bit strange for us not to be rejecting code like this during *resolution* and instead letting these malformed const generics leak into the type system:

```rust
trait Foo<T> {
  fn bar<const N: T>() {}
}
```

This PR does a few things:
1. Introduce a `ForwardGenericParamBanReason` enum, and start using the `ForwardGenericParamBan` rib to ban forward-declared params in const tys when `generic_const_parameter_types` is enabled.
2. Start using the `ConstParamTy` rib to ban *all* generics when `generic_const_parameter_types` is disabled.
3. Improve the diagnostics for both of the cases above, and for forward-declared params in parameter defaults too :3

r? `@BoxyUwU` or reassign
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
F-generic_const_parameter_types `#![feature(generic_const_parameter_types)]` S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler 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

Successfully merging this pull request may close these issues.

8 participants