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

rustc: include ParamEnv in global trait select/eval cache keys. #66963

Open
wants to merge 1 commit into
base: master
from

Conversation

@eddyb
Copy link
Member

eddyb commented Dec 2, 2019

Without #66821, this doesn't cache more than before, but it does include Reveal in the trait select/eval cache keys (via ParamEnv), which is what caused the test failures in #66821.

IIUC, this is a bug fix, because before this PR, cached select/eval results:

  • if Reveal::UserFacing, could limit what Reveal::All sees (and cause ICEs?)
  • if Reveal::All, could expose more to Reveal::UserFacing than intended

The second case is the worse one IMO, I just hope we don't find people relying on it, on crater.

r? @nikomatsakis cc @rust-lang/compiler

@eddyb eddyb force-pushed the eddyb:choose-what-you-reveal-carefully branch from 59d8369 to 1d1298e Dec 2, 2019
@eddyb

This comment has been minimized.

Copy link
Member Author

eddyb commented Dec 2, 2019

@bors try @rust-timer queue (I don't want to cause a perf regression)

@rust-timer

This comment has been minimized.

Copy link

rust-timer commented Dec 2, 2019

Awaiting bors try build completion

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Dec 2, 2019

⌛️ Trying commit 1d1298e with merge 7cb0689...

bors added a commit that referenced this pull request Dec 2, 2019
rustc: include ParamEnv in global trait select/eval cache keys.

Without #66821, this doesn't cache more than before, but it *does* include `Reveal` in the trait select/eval cache keys (via `ParamEnv`), which is what caused the test failures in #66821.

IIUC, this is a bug fix, because before this PR, cached select/eval results:
* if `Reveal::UserFacing`, could limit what `Reveal::All` sees (and cause ICEs?)
* if `Reveal::All`, could expose more to `Reveal::UserFacing` than intended

The second case is the worse one IMO, I just hope we don't find people relying on it, on crater.

r? @nikomatsakis cc @rust-lang/compiler
bors added a commit that referenced this pull request Dec 2, 2019
rustc: allow non-empty ParamEnv's in global trait select/eval caches.

*Based on #66963*

This appears to alleviate the symptoms of #65510 locally (without fixing WF directly), and is potentially easier to validate as sound (since it's a more ad-hoc version of queries we already have).

I'm opening this PR primarily to test the effects on perf.

r? @nikomatsakis cc @rust-lang/wg-traits
@bors

This comment has been minimized.

Copy link
Contributor

bors commented Dec 2, 2019

☀️ Try build successful - checks-azure
Build commit: 7cb0689 (7cb06892a23b4da510686618c8730f0b2e8bd952)

@rust-timer

This comment has been minimized.

Copy link

rust-timer commented Dec 2, 2019

Queued 7cb0689 with parent 2da942f, future comparison URL.

@eddyb

This comment has been minimized.

Copy link
Member Author

eddyb commented Dec 2, 2019

@craterbot check

@craterbot

This comment has been minimized.

Copy link
Collaborator

craterbot commented Dec 2, 2019

👌 Experiment pr-66963 created and queued.
🤖 Automatically detected try build 7cb0689
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

Copy link
Contributor

nikomatsakis left a comment

I agree this is likely a bug fix and seems pretty reasonable. I'm curious to see the performance impact. I'm also curious to understand the behavior of the test case.

@@ -1079,12 +1079,10 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
if !is_default {
true
} else if obligation.param_env.reveal == Reveal::All {
debug_assert!(!poly_trait_ref.needs_infer());

This comment has been minimized.

Copy link
@nikomatsakis

nikomatsakis Dec 2, 2019

Contributor

To be clear, did you see this debug assertion fail?

This comment has been minimized.

Copy link
@eddyb

eddyb Dec 2, 2019

Author Member

Yes, in a run-pass specialization test, as I assume this can happen inside a temporary inference context inside a normalization query.

@@ -1143,15 +1148,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let tcx = self.tcx();
if self.can_use_global_caches(param_env) {
let cache = tcx.evaluation_cache.hashmap.borrow();
if let Some(cached) = cache.get(&trait_ref) {
if let Some(cached) = cache.get(&param_env.and(trait_ref)) {

This comment has been minimized.

Copy link
@nikomatsakis

nikomatsakis Dec 2, 2019

Contributor

ok, so, in this case the only purpose is to capture the reveal mode, correct?

This comment has been minimized.

Copy link
@eddyb

eddyb Dec 2, 2019

Author Member

Yes, I can change to be literally that if e.g. it's a perf problem.

This comment has been minimized.

Copy link
@nikomatsakis

nikomatsakis Dec 5, 2019

Contributor

I wouldn't expect that to have a perf impact, but might be worth including in a comment somewhere.

@@ -1,5 +1,14 @@
error[E0277]: the trait bound `T: TraitWithAssoc` is not satisfied

This comment has been minimized.

Copy link
@nikomatsakis

nikomatsakis Dec 2, 2019

Contributor

Huh, this error is definitely not great. Do you understand what's going on here? (I don't, at least not yet)

This comment has been minimized.

Copy link
@eddyb

eddyb Dec 2, 2019

Author Member

I think this is because T ends up in the context of the impl Trait which doesn't have the parameter nor the relevant bound in its ParamEnv.
It's not great but this is a pre-existing bug in the existential type aliases feature that was being hidden because the Reveal mode was getting ignored after the first time.

@rust-timer

This comment has been minimized.

Copy link

rust-timer commented Dec 3, 2019

Finished benchmarking try commit 7cb0689, comparison URL.

@eddyb

This comment has been minimized.

Copy link
Member Author

eddyb commented Dec 3, 2019

The perf regression could be from one of two things:

  • more data to hash/compare in the cache keys
    • including the caller_bounds field of ParamEnv, even if it's always empty
    • we could just use (Reveal, T) instead of ParamEnvAnd<T>
      • however, if we do end up landing #66821, it will go back to ParamEnvAnd<T>
  • more cache misses, because the Reveal mode doesn't match
    • there's a potential correlation here between how much perf regressed and how many cache entries could've been tainted (but "most of the time" it was probably fine)
    • cc @wesleywiser could we track global trait select/eval in -Z self-profile?
@craterbot

This comment has been minimized.

Copy link
Collaborator

craterbot commented Dec 4, 2019

🚧 Experiment pr-66963 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Dec 5, 2019

@eddyb well the perf impact looks fairly small to me:

image

Not sure if it's worth worrying about, especially if we expect some improvements down the line.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants
You can’t perform that action at this time.