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

lazily "compute" anon const default substs #87280

Merged
merged 17 commits into from
Aug 27, 2021

Conversation

lcnr
Copy link
Contributor

@lcnr lcnr commented Jul 19, 2021

Continuing the work of #83086, this implements the discussed solution for the unused substs problem. As of now, anonymous constants inherit all of their parents generics, even if they do not use them, e.g. in fn foo<T, const N: usize>() -> [T; N + 1], the array length has T as a generic parameter even though it doesn't use it. These unused substs cause some backwards incompatible, and imo incorrect behavior, e.g. #78369.


We do not actually filter any generic parameters here and the default_anon_const_substs query still a dummy which only checks that

  • we now prevent the previously existing query cycles and are able to call predicates_of(parent) when computing the substs of anonymous constants
  • the default anon consts substs only include the typeflags we assume it does.

Implementing that filtering will be left as future work.


The idea of this PR is to delay the creation of the anon const substs until after we've computed predicates_of for the parent of the anon const. As the predicates of the parent can however contain the anon const we still have to create a ty::Const for it.

We do this by changing the substs field of ty::Unevaluated to an option and modifying accesses to instead call the method unevaluated.substs(tcx) which returns the substs as before. If the substs - now substs_ - of ty::Unevaluated are None, it means that the anon const currently has its default substs, i.e. the substs it has when first constructed, which are the generic parameters it has available. To be able to call unevaluated.substs(tcx) in a TypeVisitor, we add the non-defaulted method fn tcx_for_anon_const_substs(&self) -> Option<TyCtxt<'tcx>>. In case tcx_for_anon_const_substs returns None, unknown anon const default substs are skipped entirely.

Even when substs_ is None we still have to treat the constant as if it has its default substs. To do this, TypeFlags are modified so that it is clear whether they can still change when exposing any anon const default substs. A new flag, HAS_UNKNOWN_DEFAULT_CONST_SUBSTS, is added in case some default flags are missing.

The rest of this PR are some smaller changes to either not cause cycles by trying to access the default anon const substs too early or to be able to access the tcx in previously unused locations.

cc @rust-lang/project-const-generics
r? @nikomatsakis

@lcnr lcnr added A-const-generics Area: const generics (parameters and arguments) A-lazy-normalization Area: Lazy normalization (tracking issue: #60471) labels Jul 19, 2021
@rust-highfive
Copy link
Collaborator

Some changes occured to rustc_codegen_cranelift

cc @bjorn3

Some changes occurred in src/tools/clippy.

cc @rust-lang/clippy

Some changes occured to the CTFE / Miri engine

cc @rust-lang/miri

Some changes occured to the CTFE / Miri engine

cc @rust-lang/miri

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 19, 2021
@rust-log-analyzer

This comment has been minimized.

@lcnr lcnr force-pushed the lazy-anon-const-default-substs branch from ddae395 to 78a2a47 Compare July 19, 2021 14:34
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@oli-obk

This comment has been minimized.

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jul 19, 2021
@bors

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@bors

This comment has been minimized.

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 19, 2021
@lcnr lcnr force-pushed the lazy-anon-const-default-substs branch from 9aac53b to ae49d01 Compare July 20, 2021 07:27
@lcnr
Copy link
Contributor Author

lcnr commented Jul 20, 2021

@bors try @rust-timer queue

@rust-timer
Copy link
Collaborator

Awaiting bors try build completion.

@rustbot label: +S-waiting-on-perf

@bors
Copy link
Contributor

bors commented Jul 20, 2021

⌛ Trying commit ae49d0183a9a652553f901f75932d78af30c3483 with merge e38962e0c798b6fd647d7306b9f7904a89a4fe6c...

@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Contributor

bors commented Jul 20, 2021

☀️ Try build successful - checks-actions
Build commit: e38962e0c798b6fd647d7306b9f7904a89a4fe6c (e38962e0c798b6fd647d7306b9f7904a89a4fe6c)

@rust-timer
Copy link
Collaborator

Queued e38962e0c798b6fd647d7306b9f7904a89a4fe6c with parent c9aa259, future comparison URL.

@lcnr lcnr force-pushed the lazy-anon-const-default-substs branch from ae49d01 to 892e471 Compare July 20, 2021 09:19
@rust-timer
Copy link
Collaborator

Finished benchmarking try commit (e38962e0c798b6fd647d7306b9f7904a89a4fe6c): comparison url.

Summary: This change led to significant regressions 😿 in compiler performance.

  • Very large regression in instruction counts (up to 16.5% on full builds of ctfe-stress-4-check)

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR led to changes in compiler perf.

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 fix the regressions and do another perf run. If the next run shows neutral or positive results, the label will be automatically removed.

@bors rollup=never
@rustbot label: +S-waiting-on-review -S-waiting-on-perf +perf-regression

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jul 20, 2021
@rust-log-analyzer
Copy link
Collaborator

The job dist-mips-linux failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)

@bors
Copy link
Contributor

bors commented Aug 26, 2021

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Aug 26, 2021
@lcnr
Copy link
Contributor Author

lcnr commented Aug 26, 2021

@bors retry

@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 Aug 26, 2021
@bors
Copy link
Contributor

bors commented Aug 26, 2021

⌛ Testing commit 7cbfa2e with merge 517c28e...

@bors
Copy link
Contributor

bors commented Aug 27, 2021

☀️ Test successful - checks-actions
Approved by: nikomatsakis
Pushing 517c28e to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Aug 27, 2021
@bors bors merged commit 517c28e into rust-lang:master Aug 27, 2021
@rustbot rustbot added this to the 1.56.0 milestone Aug 27, 2021
@lcnr lcnr deleted the lazy-anon-const-default-substs branch August 27, 2021 07:23
@rylev
Copy link
Member

rylev commented Sep 1, 2021

The performance hit was justified here so marking it as such.

@rustbot label +perf-regression-triaged

@rustbot rustbot added the perf-regression-triaged The performance regression has been triaged. label Sep 1, 2021
JohnTitor added a commit to JohnTitor/rust-semverver that referenced this pull request Oct 13, 2021
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Oct 25, 2021
Prevent duplicate caller bounds candidates by exposing default substs in Unevaluated

Fixes rust-lang#89334

The changes introduced in rust-lang#87280 allowed for "duplicate" caller bounds candidates to be assembled that only differed in their default substs having been "exposed" or not and resulted in an ambiguity error during trait selection. To fix this we expose the defaults substs during the creation of the ParamEnv.

r? `@lcnr`
yanok added a commit to yanok/rust that referenced this pull request Oct 28, 2021
This manifistated in rust-lang#90195 with compiler being unable to keep
one candidate for a trait impl, if where is a global impl and more
than one trait bound in the where clause.

Before rust-lang#87280 `candidate_should_be_dropped_in_favor_of` was using
`TypeFoldable::is_global()` that was enough to discard the two
`ParamCandidate`s. But rust-lang#87280 changed it to use
`TypeFoldable::is_known_global()` instead, which is pessimistic, so
now the compiler drops the global impl instead (because
`is_known_global` is not sure) and then can't decide between the
two `ParamCandidate`s.

Switching it to use `is_global` again solves the issue.

Fixes rust-lang#90195.
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Oct 30, 2021
Use `is_global` in `candidate_should_be_dropped_in_favor_of`

This manifistated in rust-lang#90195 with compiler being unable to keep
one candidate for a trait impl, if where is a global impl and more
than one trait bound in the where clause.

Before rust-lang#87280 `candidate_should_be_dropped_in_favor_of` was using
`TypeFoldable::is_global()` that was enough to discard the two
`ParamCandidate`s. But rust-lang#87280 changed it to use
`TypeFoldable::is_known_global()` instead, which is pessimistic, so
now the compiler drops the global impl instead (because
`is_known_global` is not sure) and then can't decide between the
two `ParamCandidate`s.

Switching it to use `is_global` again solves the issue.

Fixes rust-lang#90195.
bors added a commit to rust-lang-ci/rust that referenced this pull request Jan 16, 2022
…, r=lcnr

partially revertish `lazily "compute" anon const default substs`

reverts rust-lang#87280 except for some of the changes around `ty::Unevaluated` having a visitor and a generic for promoted
why revert: <rust-lang#92805 (comment)>

r? `@lcnr`
flip1995 pushed a commit to flip1995/rust that referenced this pull request Jan 27, 2022
…, r=lcnr

partially revertish `lazily "compute" anon const default substs`

reverts rust-lang#87280 except for some of the changes around `ty::Unevaluated` having a visitor and a generic for promoted
why revert: <rust-lang#92805 (comment)>

r? `@lcnr`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-generics Area: const generics (parameters and arguments) A-lazy-normalization Area: Lazy normalization (tracking issue: #60471) 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-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants