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

Use TypingMode throughout the compiler instead of ParamEnv #132460

Merged
merged 2 commits into from
Nov 19, 2024

Conversation

lcnr
Copy link
Contributor

@lcnr lcnr commented Nov 1, 2024

Hopefully the biggest single PR as part of rust-lang/types-team#128.

infcx.typing_env while defining opaque types

I don't know how'll be able to correctly handle opaque types when using something taking a TypingEnv while defining opaque types. To correctly handle the opaques we need to be able to pass in the current opaque_type_storage and return constraints, i.e. we need to use a proper canonical query. We should migrate all the queries used during HIR typeck and borrowck where this matters to proper canonical queries. This is

layout_of and Reveal::All

We convert the ParamEnv to Reveal::All right at the start of the layout_of query, so I've changed callers of layout_of to already use a post analysis TypingEnv when encountering it.

let param_env = param_env.with_reveal_all_normalized(tcx);

Ty::is_[unpin|sized|whatever]

I haven't migrated fn is_item_raw to use TypingEnv, will do so in a followup PR, this should significantly reduce the amount of typing_env.param_env. At some point there will probably be zero such uses as using the type system while ignoring the typing_mode is incorrect.

MirPhase and phase-transitions

When inside of a MIR-body, we can mostly use its MirPhase to figure out the right typing_mode. This does not work during phase transitions, most notably when transitioning from Analysis to Runtime:

// These next passes must be executed together.
&add_call_guards::CriticalCallEdges,
// Must be done before drop elaboration because we need to drop opaque types, too.
&reveal_all::RevealAll,
// Calling this after reveal_all ensures that we don't deal with opaque types.
&add_subtyping_projections::Subtyper,
&elaborate_drops::ElaborateDrops,
// This will remove extraneous landing pads which are no longer
// necessary as well as forcing any call in a non-unwinding
// function calling a possibly-unwinding function to abort the process.
&abort_unwinding_calls::AbortUnwindingCalls,
// AddMovesForPackedDrops needs to run after drop
// elaboration.
&add_moves_for_packed_drops::AddMovesForPackedDrops,
// `AddRetag` needs to run after `ElaborateDrops` but before `ElaborateBoxDerefs`.
// Otherwise it should run fairly late, but before optimizations begin.
&add_retag::AddRetag,
&elaborate_box_derefs::ElaborateBoxDerefs,
&coroutine::StateTransform,
&Lint(known_panics_lint::KnownPanicsLint),

All these passes still run with MirPhase::Analysis, but we should only use Reveal::All once we're run the RevealAll pass. This required me to manually construct the right TypingEnv in all these passes. Given that it feels somewhat easy to accidentally miss this going forward, I would maybe like to change Body::phase to an Option and replace it at the start of phase transitions. This then makes it clear that the MIR is currently in a weird state.

r? @ghost

@rustbot rustbot added PG-exploit-mitigations Project group: Exploit mitigations 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. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Nov 1, 2024
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@bors
Copy link
Contributor

bors commented Nov 1, 2024

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

@lcnr lcnr force-pushed the questionable-uwu branch from fcc8c1b to 36542fc Compare November 4, 2024 13:53
@rust-log-analyzer

This comment has been minimized.

@lcnr lcnr force-pushed the questionable-uwu branch from 36542fc to f0f4405 Compare November 4, 2024 14:34
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@lcnr lcnr mentioned this pull request Nov 4, 2024
3 tasks
@lcnr lcnr removed the PG-exploit-mitigations Project group: Exploit mitigations label Nov 5, 2024
@rustbot rustbot added the PG-exploit-mitigations Project group: Exploit mitigations label Nov 5, 2024
@rust-log-analyzer

This comment has been minimized.

@lcnr
Copy link
Contributor Author

lcnr commented Nov 8, 2024

PseudoCanonicalInput may end up defining opaque types now, drop that from the typing mode

@rust-log-analyzer

This comment has been minimized.

@lcnr lcnr force-pushed the questionable-uwu branch from 6eddc58 to 3f906ca Compare November 8, 2024 14:55
@rust-log-analyzer

This comment has been minimized.

@lcnr lcnr force-pushed the questionable-uwu branch from 3f906ca to ed391c3 Compare November 8, 2024 15:10
@lcnr lcnr force-pushed the questionable-uwu branch from ed391c3 to 1d78b92 Compare November 8, 2024 15:13
@lcnr
Copy link
Contributor Author

lcnr commented Nov 8, 2024

@bors try @rust-timer queue

@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 Nov 8, 2024
@bors
Copy link
Contributor

bors commented Nov 8, 2024

⌛ Trying commit 1d78b92 with merge dcde587...

bors added a commit to rust-lang-ci/rust that referenced this pull request Nov 8, 2024
`TypingMode` sure seems like a good idea

## `infcx.typing_env` while defining opaque types

I don't know how'll be able to correctly handle opaque types when using something taking a `TypingEnv` while defining opaque types. To correctly handle the opaques we need to be able to pass in the current `opaque_type_storage` and return constraints, i.e. we need to use a proper canonical query. We should migrate all the queries used during HIR typeck and borrowck where this matters to proper canonical queries. This is

## `layout_of` and `Reveal::All`

We convert the `ParamEnv` to `Reveal::All` right at the start of the `layout_of` query, so I've changed callers of `layout_of` to already use a post analysis `TypingEnv` when encountering it.

https://github.com/rust-lang/rust/blob/ca87b535a05097df6abbe2a031b057de2cefac5b/compiler/rustc_ty_utils/src/layout.rs#L51

r? `@ghost`
@rust-log-analyzer

This comment has been minimized.

debug_assert_eq!(self.param_env.reveal(), Reveal::All);
TypingMode::PostAnalysis
ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env: self.param_env }
Copy link
Member

@RalfJung RalfJung Nov 15, 2024

Choose a reason for hiding this comment

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

This is also used by Miri. So if Miri should use TypingMode::fully_monomorphized(), then something seems wrong here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the param_env is always empty in MIRI, so ty::TypingEnv { typing_mode: ty::TypingMode::PostAnalysis, param_env: self.param_env } is equal to ty::TypingEnv::fully_monomorphized()

Copy link
Member

Choose a reason for hiding this comment

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

Ah, okay.

rustc_span::DUMMY_SP,
typing_env.param_env,
MiriMachine::new(config, layout_cx)
);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
);
);
assert_eq!(ecx.typing_env(), typing_env);

Does this make sense? Currently it seems a bit odd that we only pass part of the typing env to InterpCx.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The assert should hold, I don't like adding that assert from a style perspective however

a question here is the following:

  • const evaluation should always run in the PostAnalysis/Reveal::All mode, so we don't need to store the TypingMode in the interpcx
  • we still want to assert that users of const eval pass in the correct typing_env and don't accidentally switch to PostAnalysis without noticing
  • not sure about the final result from my chat with @compiler-errors, but I think we probably want to store a full TypingEnv in the InterpCx and const eval in general and just assert that the TypingMode is PostAnalysis. Storing another 16? bytes in the context really shouldn't matter I think

Copy link
Member

Choose a reason for hiding this comment

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

I don't like adding that assert from a style perspective however

It seems currently there is a non-local invariant encoded by how typing_env() is implemented on InterpCx. I'd like to ensure that we realize if this ever breaks.

we still want to assert that users of const eval pass in the correct typing_env and don't accidentally switch to PostAnalysis without noticing

That sounds reasonable, but that's a different assertion -- that would be somewhere in the const_eval queries. This here is about Miri.

I think we probably want to store a full TypingEnv in the InterpCx and const eval in general and just assert that the TypingMode is PostAnalysis. Storing another 16? bytes in the context really shouldn't matter I think

I'm fine with that as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

do you mind me changing InterpCx to contain the typing_env directly in a followup PR?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah feel free to stage this however.

@lcnr lcnr force-pushed the questionable-uwu branch 2 times, most recently from e96e4bc to 278c91b Compare November 15, 2024 13:51
@compiler-errors compiler-errors changed the title TypingMode sure seems like a good idea Use TypingMode throughout the compiler instead of ParamEnv Nov 15, 2024
compiler/rustc_middle/src/ty/mod.rs Show resolved Hide resolved
@@ -1126,7 +1126,7 @@ fn check_type_defn<'tcx>(
let ty = tcx.type_of(variant.tail().did).instantiate_identity();
let ty = tcx.erase_regions(ty);
assert!(!ty.has_infer());
ty.needs_drop(tcx, tcx.param_env(item.owner_id))
ty.needs_drop(tcx, ty::TypingEnv::non_body_analysis(tcx, item.owner_id.def_id))
Copy link
Member

Choose a reason for hiding this comment

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

why not wfcx.infcx.typing_env?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

🤷 fixed

@@ -1257,7 +1257,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> Option<FxIndexSet<UpvarMigrationInfo>> {
let ty = self.resolve_vars_if_possible(self.node_ty(var_hir_id));

if !ty.has_significant_drop(self.tcx, self.tcx.param_env(closure_def_id)) {
// FIXME(#132279): Using `non_body_analysis` here feels wrong.
Copy link
Member

Choose a reason for hiding this comment

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

i think i agree -- canonicalizing here would mean we can peek through opaques, which seems good?

Copy link
Member

Choose a reason for hiding this comment

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

later tho

compiler/rustc_hir_typeck/src/writeback.rs Show resolved Hide resolved
compiler/rustc_infer/src/infer/mod.rs Outdated Show resolved Hide resolved
compiler/rustc_middle/src/ty/context.rs Show resolved Hide resolved
@compiler-errors
Copy link
Member

i left some questions, but i think this can be rebased one more time, and i think i can do a final review of the delta, then ill approve after?

lcnr added 2 commits November 18, 2024 10:38
the behavior of the type system not only depends on the current
assumptions, but also the currentnphase of the compiler. This is
mostly necessary as we need to decide whether and how to reveal
opaque types. We track this via the `TypingMode`.
@compiler-errors
Copy link
Member

@bors r+ rollup=never p=1

@bors
Copy link
Contributor

bors commented Nov 18, 2024

📌 Commit 2e087d2 has been approved by compiler-errors

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 Nov 18, 2024
@bors
Copy link
Contributor

bors commented Nov 18, 2024

⌛ Testing commit 2e087d2 with merge b71fb5e...

@bors
Copy link
Contributor

bors commented Nov 19, 2024

☀️ Test successful - checks-actions
Approved by: compiler-errors
Pushing b71fb5e to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Nov 19, 2024
@bors bors merged commit b71fb5e into rust-lang:master Nov 19, 2024
7 checks passed
@rustbot rustbot added this to the 1.84.0 milestone Nov 19, 2024
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (b71fb5e): comparison URL.

Overall result: ❌✅ regressions and improvements - please read the text below

Our benchmarks found a performance regression caused by this PR.
This might be an actual regression, but it can also be just noise.

Next Steps:

  • If the regression was expected or you think it can be justified,
    please write a comment with sufficient written justification, and add
    @rustbot label: +perf-regression-triaged to it, to mark the regression as triaged.
  • If you think that you know of a way to resolve the regression, try to create
    a new PR with a fix for the regression.
  • If you do not understand the regression or you think that it is just noise,
    you can ask the @rust-lang/wg-compiler-performance working group for help (members of this group
    were already notified of this PR).

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

Instruction count

This is the most reliable metric that we have; it was used to determine the overall result at the top of this comment. However, even this metric can sometimes exhibit noise.

mean range count
Regressions ❌
(primary)
0.2% [0.1%, 0.4%] 8
Regressions ❌
(secondary)
0.9% [0.2%, 2.7%] 6
Improvements ✅
(primary)
-0.3% [-0.3%, -0.3%] 1
Improvements ✅
(secondary)
-0.8% [-0.9%, -0.7%] 5
All ❌✅ (primary) 0.1% [-0.3%, 0.4%] 9

Max RSS (memory usage)

Results (primary 0.6%, secondary 2.4%)

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)
1.5% [1.1%, 2.2%] 3
Regressions ❌
(secondary)
2.4% [2.4%, 2.4%] 1
Improvements ✅
(primary)
-2.1% [-2.1%, -2.1%] 1
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 0.6% [-2.1%, 2.2%] 4

Cycles

Results (secondary -2.0%)

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.4% [1.6%, 3.2%] 2
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-4.2% [-5.1%, -3.5%] 4
All ❌✅ (primary) - - 0

Binary size

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

Bootstrap: 789.97s -> 792.184s (0.28%)
Artifact size: 334.45 MiB -> 334.48 MiB (0.01%)

@pnkfelix
Copy link
Member

Visiting for rustc-perf triage

  • primary regressions to unicode-normalization profiles and (to a lesser extent) diesel, stm32f4, and cargo.
  • it seems like this regression was to some extent anticipated, at least from the perf run that was done while the PR was in development.

@lcnr and @compiler-errors , is that consistent with your view of the situation? The regression here seems like is probably acceptable (and perhaps just yet another instance of measurement bias in our perf system), but I don't want to mark this case as triaged without at least getting an ACK from either of you.

@lcnr
Copy link
Contributor Author

lcnr commented Nov 20, 2024

I think that a small negative perf hit is expected here but unavoidable. We need to track additional information in multiple queries

github-merge-queue bot pushed a commit to model-checking/kani that referenced this pull request Nov 28, 2024
Fix required due to the following changes to Rust's internal API:
- rust-lang/rust#132460
- rust-lang/rust#133212
- rust-lang/rust#131326

Resolves #3731

By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 and MIT licenses.

---------

Co-authored-by: Zyad Hassan <88045115+zhassan-aws@users.noreply.github.com>
bjorn3 pushed a commit to bjorn3/rust that referenced this pull request Dec 6, 2024
…rors

Use `TypingMode` throughout the compiler instead of `ParamEnv`

Hopefully the biggest single PR as part of rust-lang/types-team#128.

## `infcx.typing_env` while defining opaque types

I don't know how'll be able to correctly handle opaque types when using something taking a `TypingEnv` while defining opaque types. To correctly handle the opaques we need to be able to pass in the current `opaque_type_storage` and return constraints, i.e. we need to use a proper canonical query. We should migrate all the queries used during HIR typeck and borrowck where this matters to proper canonical queries. This is

## `layout_of` and `Reveal::All`

We convert the `ParamEnv` to `Reveal::All` right at the start of the `layout_of` query, so I've changed callers of `layout_of` to already use a post analysis `TypingEnv` when encountering it.

https://github.com/rust-lang/rust/blob/ca87b535a05097df6abbe2a031b057de2cefac5b/compiler/rustc_ty_utils/src/layout.rs#L51

## `Ty::is_[unpin|sized|whatever]`

I haven't migrated `fn is_item_raw` to use `TypingEnv`, will do so in a followup PR, this should significantly reduce the amount of `typing_env.param_env`. At some point there will probably be zero such uses as using the type system while ignoring the `typing_mode` is incorrect.

## `MirPhase` and phase-transitions

When inside of a MIR-body, we can mostly use its `MirPhase` to figure out the right `typing_mode`. This does not work during phase transitions, most notably when transitioning from `Analysis` to `Runtime`:

https://github.com/rust-lang/rust/blob/dae7ac133b9eda152784c075facb31a6688c92b1/compiler/rustc_mir_transform/src/lib.rs#L606-L625

All these passes still run with `MirPhase::Analysis`, but we should only use `Reveal::All` once we're run the `RevealAll` pass. This required me to manually construct the right `TypingEnv` in all these passes. Given that it feels somewhat easy to accidentally miss this going forward, I would maybe like to change `Body::phase` to an `Option` and replace it at the start of phase transitions. This then makes it clear that the MIR is currently in a weird state.

r? `@ghost`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. perf-regression Performance regression. PG-exploit-mitigations Project group: Exploit mitigations 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. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants