Conversation
`query_get_at`, `query_ensure`, and `query_ensure_error_guarantee` are very similar functions, but they all use different control flow styles which obscures the similarities. This commit rewrites them to all use a `match`.
Two places where `ensure_ok` can be used but currently isn't. (These queries are marked with `return_result_from_ensure_ok`, which means that `ensure_ok` returns `Result<(), ErrorGuaranteed>`.) This is potentially a perf win, because `ensure_ok` query calls can be faster.
|
Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt Some changes occurred to the CTFE machinery Some changes occurred to constck cc @fee1-dead |
|
|
| $(#[$attr])* | ||
| #[inline(always)] | ||
| pub fn $name(self, key: query_helper_param_ty!($($K)*)) { | ||
| crate::query::inner::query_ensure_ok_or_done( | ||
| self.tcx, | ||
| &self.tcx.query_system.query_vtables.$name, | ||
| $crate::query::IntoQueryParam::into_query_param(key), | ||
| $crate::query::EnsureMode::Ok, | ||
| ) | ||
| } |
There was a problem hiding this comment.
Question: Would it make sense to forbid ensure_ok calls for queries that return Result<_, ErrorGuaranteed>?
(By gating this method with #[cfg(not($returns_error_guaranteed))].)
I haven't fully considered the consequences, but intuitively it feels like a footgun to allow such calls.
There was a problem hiding this comment.
I tried this before filing the PR and had problems here. Currently that forces tcx.foo() being supported for every query. It's possible this might be adjusted away, but it felt like a bridge too far for this PR.
There was a problem hiding this comment.
To clarify, I meant forbidding tcx.ensure_ok().$query(..), not tcx.$query(..).
But it turns out that I was planning to get rid of call_query_method_fn anyway:
There was a problem hiding this comment.
Sorry I misread. Back to the original question: I tried forbidding it like you suggested. There are two places it causes problems. A line in compiler/rustc_interface/src/passes.rs:
tcx.ensure_ok().mir_borrowck(def_id);and a line in src/librustdoc/core.rs:
tcx.sess.time("wf_checking", || tcx.ensure_ok().check_type_wf(()));Both of these queries return Result<_, ErrorGuaranteed> but neither was marked with return_result_from_ensure_ok. They could be changed to use ensure_result() (which requires a let _ = ...) but I don't think it's worthwhile. After all, every query that returns a value (i.e. most of them) can be called with ensure_ok, so it seems weird to ban ensure_ok just for the Result<_, ErrorGuaranteed> ones.
`ensure_ok` provides a special, more efficient way of calling a query when its return value isn't needed. But there is a complication: if the query is marked with the `return_result_from_ensure_ok` modifier, then it will return `Result<(), ErrorGuaranteed`. This is clunky and feels tacked on. It's annoying to have to add a modifier to a query to declare information present in its return type, and it's confusing that queries called via `ensure_ok` have different return types depending on the modifier. This commit: - Eliminates the `return_result_from_ensure_ok` modifier. The proc macro now looks at the return type and detects if it matches `Result<_, ErrorGuarantee>`. If so, it adds the modifier `returns_result_with_error_guarantee`. (Aside: We need better terminology to distinguish modifiers written by the user in a `query` declaration (e.g. `cycle_delayed_bug`) from modifiers added by the proc macro (e.g. `cycle_error_handling`.)) - Introduces `ensure_result`, which replaces the use of `ensure_ok` for queries that return `Result<_, ErrorGuarantee>`. As a result, `ensure_ok` can now only be used for the "ignore the return value" case.
edf3729 to
bde722a
Compare
|
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| if try_get_cached(tcx, &query.cache, &key).is_none() { | ||
| (query.execute_query_fn)(tcx, DUMMY_SP, key, QueryMode::Ensure { ensure_mode }); | ||
| match try_get_cached(tcx, &query.cache, &key) { | ||
| Some(_value) => {} |
There was a problem hiding this comment.
I suspect this is going to be reverted next time anyone runs clippy on the compiler.
There was a problem hiding this comment.
I tried clippy on a test program with the same structure and it didn't complain.
|
Finished benchmarking commit (61d1293): comparison URL. Overall result: ✅ improvements - no action neededBenchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf. @bors rollup=never Instruction countOur most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.
Max RSS (memory usage)This benchmark run did not return any relevant results for this metric. CyclesResults (secondary -1.9%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeResults (primary 0.1%, secondary 0.1%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Bootstrap: 481.183s -> 478.51s (-0.56%) |
The interaction of
ensure_okand thereturn_result_from_ensure_okquery modifier is weird and hacky. This PR cleans it up. Details in the individual commits.r? @Zalathar