-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
forego caching for all participants in cycles, apart from root node #60444
forego caching for all participants in cycles, apart from root node #60444
Conversation
This comment has been minimized.
This comment has been minimized.
fdd7a95
to
1da50d2
Compare
This comment has been minimized.
This comment has been minimized.
1da50d2
to
bd005a2
Compare
src/librustc/traits/select.rs
Outdated
/// well as the second instance of `A: AutoTrait`) to supress | ||
/// caching. | ||
/// | ||
/// This is a simple, targeted fix. The correct fix requires |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in what sense are you using the word "correct" here?
Is this use of "correct" meant to imply that there are cases of unsound code that on master we currently incorrectly accept, and a correct fix would reject, but this targeted fix continues to accept?
Or is this use of "correct" just meant to emphasize that this fix is not ideal with respect to compiler efficiency?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, the latter -- efficiency.
@bors try |
…tion, r=<try> forego caching for all participants in cycles, apart from root node This is a targeted fix for #60010, which uncovered a pretty bad failure of our caching strategy in the face of coinductive cycles. The problem is explained in the comment in the PR on the new field, `in_cycle`, but I'll reproduce it here: > Starts out as false -- if, during evaluation, we encounter a > cycle, then we will set this flag to true for all participants > in the cycle (apart from the "head" node). These participants > will then forego caching their results. This is not the most > efficient solution, but it addresses #60010. The problem we > are trying to prevent: > > - If you have `A: AutoTrait` requires `B: AutoTrait` and `C: NonAutoTrait` > - `B: AutoTrait` requires `A: AutoTrait` (coinductive cycle, ok) > - `C: NonAutoTrait` requires `A: AutoTrait` (non-coinductive cycle, not ok) > > you don't want to cache that `B: AutoTrait` or `A: AutoTrait` > is `EvaluatedToOk`; this is because they were only considered > ok on the premise that if `A: AutoTrait` held, but we indeed > encountered a problem (later on) with `A: AutoTrait. So we > currently set a flag on the stack node for `B: AutoTrait` (as > well as the second instance of `A: AutoTrait`) to supress > caching. > > This is a simple, targeted fix. The correct fix requires > deeper changes, but would permit more caching: we could > basically defer caching until we have fully evaluated the > tree, and then cache the entire tree at once. I'm not sure what the impact of this fix will be in terms of existing crates or performance: we were accepting incorrect code before, so there will perhaps be some regressions, and we are now caching less. As the comment above notes, we could do a lot better than this fix, but that would involve more invasive rewrites. I thought it best to start with something simple. r? @pnkfelix -- but let's do crater/perf run cc @arielb1
(the change seems fine, though I would like a small revision to the comment where I noted a somewhat ambiguous of the word "correct") I'll try to get the crater and perf runs going. |
☀️ Try build successful - checks-travis |
@rust-timer build cf8e5a0 |
Success: Queued cf8e5a0 with parent 92b5e20, comparison URL. |
Finished benchmarking try commit cf8e5a0 |
Seems like it is a wash performance wise, which is great. |
@craterbot run mode=check-only |
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
🚧 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
This looks like an annoying problem, and I agree we shouldn't fix it the "right way" if Chalk is going to be merged soon-ish. I was afraid for some time that a problem like this might be present, but didn't have time to dig in deeper. I would have preferred to do a Tarjan's-style mechanism using |
I also think the performance impact here shouldn't be so horrible: every time this is hit, we do cache at least one trait, so we only evaluate each member of a cycle up to Would be nice to write this in a comment. r=me with that comment and a clean crater. |
🎉 Experiment
|
modify the comment on `in_cycle` to reflect changes requested by ariel and myself.
Dear crate authors, This PR fixes a soundness hole in our trait resolution caching scheme. I'm not sure how easily we'll be able to do a warning system for this fix (I can't immediately think of how to do one), so I'm contacting you to let you know that your crates may be affected. If you'd like to try out this build, you should be able to install it using @kennytm's rustup-toolchain-install-master script and installing the toolchain There are two crates from crates.io that appear to be affected:
I will take a look at those crates and see if I can offer any suggestions. There are also two crates appear unmaintained (last update was >2 years ago) and a git repository that appears similar (last commit was Sep 2018). Apologies if this is incorrect!
As these appear unmaintained, I don't plan to investigate them further. |
Hey @nikomatsakis, thanks for flagging!
I wasn't able to build this locally as the install script failed due to a missing component:detecting the channel of the `cf8e5a06b289fbcdaf75ca55c057b2cb09fff33b` toolchain... downloading ... error: missing component `rustc` on toolchain `cf8e5a06b289fbcdaf75ca55c057b2cb09fff33b` on channel `nightly` for target `x86_64-apple-darwin` I peeked at the build logs, it appears due to the compiler getting stuck when attempting to verify Send/Sync bounds on a very deeply recursive and generic type hierarchy. I'm happy to elaborate more on what the crate does so you don't have to do too much spelunking.The crate offers the functionality to parse shell programs. Each piece of the grammar is represented as a node which can hold generic sub-nodes. The reasoning for this is so that the crate consumer could customize their AST with different/custom nodes, while reusing existing implementations. The shell grammar is deeply recursive. Basically each command can vary in complexity (compound commands such as There are two "top-level" type definitions which seek to unify the entire AST tree concretely which are basically |
…r-investigation, r=pnkfelix forego caching for all participants in cycles, apart from root node This is a targeted fix for rust-lang#60010, which uncovered a pretty bad failure of our caching strategy in the face of coinductive cycles. The problem is explained in the comment in the PR on the new field, `in_cycle`, but I'll reproduce it here: > Starts out as false -- if, during evaluation, we encounter a > cycle, then we will set this flag to true for all participants > in the cycle (apart from the "head" node). These participants > will then forego caching their results. This is not the most > efficient solution, but it addresses rust-lang#60010. The problem we > are trying to prevent: > > - If you have `A: AutoTrait` requires `B: AutoTrait` and `C: NonAutoTrait` > - `B: AutoTrait` requires `A: AutoTrait` (coinductive cycle, ok) > - `C: NonAutoTrait` requires `A: AutoTrait` (non-coinductive cycle, not ok) > > you don't want to cache that `B: AutoTrait` or `A: AutoTrait` > is `EvaluatedToOk`; this is because they were only considered > ok on the premise that if `A: AutoTrait` held, but we indeed > encountered a problem (later on) with `A: AutoTrait. So we > currently set a flag on the stack node for `B: AutoTrait` (as > well as the second instance of `A: AutoTrait`) to supress > caching. > > This is a simple, targeted fix. The correct fix requires > deeper changes, but would permit more caching: we could > basically defer caching until we have fully evaluated the > tree, and then cache the entire tree at once. I'm not sure what the impact of this fix will be in terms of existing crates or performance: we were accepting incorrect code before, so there will perhaps be some regressions, and we are now caching less. As the comment above notes, we could do a lot better than this fix, but that would involve more invasive rewrites. I thought it best to start with something simple. r? @pnkfelix -- but let's do crater/perf run cc @arielb1
Rollup of 9 pull requests Successful merges: - #60130 (Add implementations of last in terms of next_back on a bunch of DoubleEndedIterators) - #60443 (as_ptr returns a read-only pointer) - #60444 (forego caching for all participants in cycles, apart from root node) - #60719 (Allow subdirectories to be tested by x.py test) - #60780 (fix Miri) - #60788 (default to $ARCH-apple-macosx10.7.0 LLVM triple for darwin targets) - #60799 (Allow late-bound regions in existential types) - #60808 (Improve the "must use" lint for `Future`) - #60819 (submodules: update clippy from 3710ec5 to ad3269c) Failed merges: r? @ghost
Confirming that increasing the recursion limit to 128 has fixed building my crates. However, I'm seeing a significant perf issue when building. I'll open a separate issue for this |
Unfortunately, that `: RefUnwindSafe` bound gives rustc a hard time, so let's remove it for know. See * #1283 * rust-lang/rust#60444 * rust-lang/rust#58291 closes #1283
I think this PR makes rustc unable to build itself with |
Short circuit Send and Sync impls for TokenTree Workaround to make the parallel compiler build after #60444. r? @nikomatsakis
This is a targeted fix for #60010, which uncovered a pretty bad failure of our caching strategy in the face of coinductive cycles. The problem is explained in the comment in the PR on the new field,
in_cycle
, but I'll reproduce it here:I'm not sure what the impact of this fix will be in terms of existing crates or performance: we were accepting incorrect code before, so there will perhaps be some regressions, and we are now caching less.
As the comment above notes, we could do a lot better than this fix, but that would involve more invasive rewrites. I thought it best to start with something simple.
r? @pnkfelix -- but let's do crater/perf run
cc @arielb1