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

Implement generic const items #113522

Merged
merged 9 commits into from
Jul 28, 2023
Merged

Implement generic const items #113522

merged 9 commits into from
Jul 28, 2023

Conversation

fmease
Copy link
Member

@fmease fmease commented Jul 10, 2023

This implements generic parameters and where-clauses on free and associated const items under the experimental feature gate generic_const_items. See rust-lang/lang-team#214.

Tracking issue: #113521.
Fixes #104400.

This PR doesn't include rustfmt support as per nightly style procedure and it doesn't add rustdoc JSON support (see related Zulip topic).

CC @scottmcm @compiler-errors @WalterSmuts
r? @oli-obk

Resolved Questions
  • Q: Should const ADD<const N: usize, const M: usize>: usize = N M; ADD::<0, 1> trigger the error generic parameters may not be used in const operations (which can be unlocked with #![feature(generic_const_exprs)]). Currently it doesn't. Or does this fall under this paragraph?
  • Q: Should const UNUSED: () = () where String: Copy; (with #![feature(trivial_bounds)] and with UNUSED unused) succeed compilation? Currently it doesn't: evaluation of constant value failed // entering unreachable code

@rustbot rustbot added A-rustdoc-json Area: Rustdoc JSON backend A-testsuite Area: The testsuite used to check the correctness of rustc S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Jul 10, 2023
@rust-log-analyzer

This comment has been minimized.

@rustbot rustbot removed the A-rustdoc-json Area: Rustdoc JSON backend label Jul 10, 2023
@lcnr lcnr added the needs-fcp This change is insta-stable, so needs a completed FCP to proceed. label Jul 10, 2023
@lcnr
Copy link
Contributor

lcnr commented Jul 10, 2023

some thoughts without looking at the PR:

  • please rename the feature gate to generic_const_items because generic_consts is too general and therefore confusing
  • while I am strongly in favor of this feature, I would like this work to go through the proper lang/types team procedures. Afaict @scottmcm mentioned that they would second a lang proposal for them, so please open a lang MCP (I think that's how t-lang currently does stuff)
  • I would you to potentially split this into multiple PRs, implementing parsing nameres first and then implementing type system support in a separate PR. I don't think we have a single expert able to sufficiently review everything here and would like to avoid having multiple reviewers with overlapping responsibilities here. It should also avoid some merge conflicts hopefully

Should const ADD<const N: usize, const M: usize>: usize = N M; ADD::<0, 1> trigger the error generic parameters may not be used in const operations (which can be unlocked with #![feature(generic_const_exprs)]). Currently it doesn't. Or does this fall under this paragraph?

It should not, ADD::<0, 1> does not depend on any generic parameters itself. THis is similar to <() as TraitAdd<0, 1>>::ASSOC which is already allowed.

  • Should const UNUSED: () = () where String: Copy; (with #![feature(trivial_bounds)] and with UNUSED unused) succeed compilation? Currently it doesn't: evaluation of constant value failed // entering unreachable code

ideally yes, but I think this is something with can deal with later. Const evaluation with invalid bounds is generally somewhat meh rn and not something you have to deal with in this PR.

@fmease fmease changed the title Implement generic consts Implement generic const items Jul 10, 2023
Copy link
Contributor

@cjgillot cjgillot left a comment

Choose a reason for hiding this comment

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

Some preliminary remarks on this PR.

I disagree with @lcnr about splitting into multiple PRs. Having a single PR makes it much easier to check the global consistency of the implementation. The PR is already neatly split into consistent commits, which makes this practical. We can have multiple assigned reviewers on this single PR 1 coordinating the review.

I'm available for the AST HIR nameres part.

compiler/rustc_ast_passes/src/ast_validation.rs Outdated Show resolved Hide resolved
compiler/rustc_ast_lowering/src/item.rs Outdated Show resolved Hide resolved
compiler/rustc_resolve/src/late.rs Outdated Show resolved Hide resolved
compiler/rustc_resolve/src/late.rs Outdated Show resolved Hide resolved
compiler/rustc_resolve/src/late.rs Outdated Show resolved Hide resolved
compiler/rustc_resolve/src/late.rs Outdated Show resolved Hide resolved
compiler/rustc_resolve/src/late.rs Outdated Show resolved Hide resolved
compiler/rustc_resolve/src/late.rs Outdated Show resolved Hide resolved
@oli-obk
Copy link
Contributor

oli-obk commented Jul 10, 2023

It was my understanding that adding a new feature gate only needs a lang team member who's ok with it, not a lang team FCP (MCPs have been discontinued). I also think that this feature is ok to review in one PR, but I will likely ask some general things to happen in other PRs and this one to be rebased over them.

@cjgillot cjgillot self-assigned this Jul 10, 2023
@rustbot rustbot added the A-rustdoc-json Area: Rustdoc JSON backend label Jul 11, 2023
compiler/rustc_ast/src/visit.rs Outdated Show resolved Hide resolved
compiler/rustc_ast/src/visit.rs Outdated Show resolved Hide resolved
compiler/rustc_ast_pretty/src/pprust/state/item.rs Outdated Show resolved Hide resolved
compiler/rustc_parse/src/parser/item.rs Outdated Show resolved Hide resolved
compiler/rustc_parse/src/parser/item.rs Outdated Show resolved Hide resolved
compiler/rustc_parse/src/parser/item.rs Outdated Show resolved Hide resolved
compiler/rustc_parse/src/parser/item.rs Show resolved Hide resolved
compiler/rustc_parse/src/parser/item.rs Outdated Show resolved Hide resolved
compiler/rustc_parse/src/parser/item.rs Show resolved Hide resolved
compiler/rustc_parse/src/parser/item.rs Outdated Show resolved Hide resolved
@bors
Copy link
Contributor

bors commented Jul 13, 2023

☔ The latest upstream changes (presumably #113646) made this pull request unmergeable. Please resolve the merge conflicts.

@rust-log-analyzer

This comment has been minimized.

@fmease fmease force-pushed the generic-consts branch 2 times, most recently from 53d06c1 to 4465212 Compare July 16, 2023 19:18
compiler/rustc_resolve/src/late.rs Outdated Show resolved Hide resolved
compiler/rustc_hir_analysis/src/check/wfcheck.rs Outdated Show resolved Hide resolved
compiler/rustc_resolve/src/late.rs Outdated Show resolved Hide resolved
Comment on lines 9 to 24
const CREATE<T: ~const Create>: T = T::create();

pub const K0: i32 = CREATE::<i32>;
pub const K1: i32 = CREATE; // arg inferred

#[const_trait]
trait Create {
fn create() -> Self;
}

impl const Create for i32 {
fn create() -> i32 {
4096
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

impl Create for u32 {
    fn create() -> u32 {
        println!("foobar");
        42
    }
}

will probably still compile (modulo the inference example), and then die in const eval. We'll need to interpret ~const (or just const) bounds as always-const, instead of maybe-const in const items. This can happen in a follow up though.

cc @fee1-dead

Copy link
Member

Choose a reason for hiding this comment

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

Ooh this is interesting. This should probably happen during astconv when ~const gets desugared into generic params for the trait. And in this case the generic param should just be host = false (disabling the host effect thus making this a const trait bound)

I think this would fit nicely into the PR where constness is removed from TraitPredicate.

tests/ui/generic-const-items/inference-failure.rs Outdated Show resolved Hide resolved
@fmease
Copy link
Member Author

fmease commented Jul 28, 2023

Rebased, CI green & none of the PRs rolled up in #114181 (pending) should lead to any kind of conflict 🤞
Could sb. reapprove? Thanks in advance! <3

@compiler-errors
Copy link
Member

@bors r=cjgillot

@bors
Copy link
Contributor

bors commented Jul 28, 2023

📌 Commit 203d400 has been approved by cjgillot

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 Jul 28, 2023
@bors
Copy link
Contributor

bors commented Jul 28, 2023

⌛ Testing commit 203d400 with merge 04abc37...

@bors
Copy link
Contributor

bors commented Jul 28, 2023

☀️ Test successful - checks-actions
Approved by: cjgillot
Pushing 04abc37 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Jul 28, 2023
@bors bors merged commit 04abc37 into rust-lang:master Jul 28, 2023
12 checks passed
@rustbot rustbot added this to the 1.73.0 milestone Jul 28, 2023
@fmease fmease deleted the generic-consts branch July 28, 2023 23:53
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (04abc37): comparison URL.

Overall result: ❌ regressions - ACTION NEEDED

Next Steps: If you can justify the regressions found in this perf run, please indicate this with @rustbot label: perf-regression-triaged along with sufficient written justification. If you cannot justify the regressions please open an issue or create a new PR that fixes the regressions, add a comment linking to the newly created issue or PR, and then add the perf-regression-triaged label to this PR.

@rustbot label: perf-regression
cc @rust-lang/wg-compiler-performance

Instruction count

This is a highly reliable metric that was used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
0.7% [0.3%, 1.0%] 17
Regressions ❌
(secondary)
0.9% [0.3%, 1.4%] 9
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 0.7% [0.3%, 1.0%] 17

Max RSS (memory usage)

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
2.1% [1.6%, 3.0%] 4
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-2.4% [-2.5%, -2.3%] 2
All ❌✅ (primary) - - 0

Cycles

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-3.5% [-5.2%, -1.8%] 6
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) -3.5% [-5.2%, -1.8%] 6

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 649.861s -> 649.942s (0.01%)

@rustbot rustbot added the perf-regression Performance regression. label Jul 29, 2023
@nnethercote
Copy link
Contributor

@fmease: a few perf regressions there, is that expected? Any ideas how to mitigate them?

@fmease
Copy link
Member Author

fmease commented Jul 29, 2023

The regressions are somewhat expected (we're doing more work per const item). While I've expected a benchmark like many-assoc-items to regress, I'm surprised that perf is worse for free const items as well (libc contains a number of them).

I'm looking into it. Maybe we can short-circuit in some places.

@rustbot rustbot added the F-generic_const_items `#![feature(generic_const_items)]` label Jul 29, 2023
@rylev
Copy link
Member

rylev commented Aug 5, 2023

@rustbot label: perf-regression-triaged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-rustdoc-json Area: Rustdoc JSON backend A-testsuite Area: The testsuite used to check the correctness of rustc F-generic_const_items `#![feature(generic_const_items)]` merged-by-bors This PR was explicitly merged by bors. perf-regression Performance regression. perf-regression-triaged The performance regression has been triaged. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

no place to add evaluatable bounds to assoc const items