Eliminate lifting#155921
Conversation
Various places where `lift` just isn't necessary.
By moving the lifetimes from the closures to the enclosing function, we no longer need to call `lift` within them.
By using 'tcx in the right places and avoiding HRTBs, we can avoid some more lifting.
As in the previous commits, increased use of 'tcx and avoidance of HRTBs avoids the need for some lifting.
Once again, increased use of 'tcx avoids the need for some lifting.
Thanks to the previous commits, none of this code used any more and it can all be removed. Specifically: - The `Lift` trait. - The `Lift` and `Lift_Generic` proc macros, and all their uses. - The declarative macros used to impl `Lift` for various types. - The `rustc_macros::lift` and `rustc_type_ir::lift` modules. This commit also eliminates two FIXME comments.
|
@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.
|
Finished benchmarking commit (c6cff6a): comparison URL. Overall result: no relevant changes - no action neededBenchmarking means the PR may be perf-sensitive. Consider adding rollup=never if this change is not fit for rolling up. @rustbot label: -S-waiting-on-perf -perf-regression Instruction countThis perf run didn't have relevant results for this metric. Max RSS (memory usage)Results (primary 2.1%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (secondary -2.5%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeThis perf run didn't have relevant results for this metric. Bootstrap: 489.39s -> 486.341s (-0.62%) |
| /// will do all required instantiations as they run. | ||
| /// | ||
| /// Note: the `Lift` impl is currently not used by rustc, but is used by | ||
| /// rustc_codegen_cranelift when the `jit` feature is enabled. |
There was a problem hiding this comment.
@bjorn3: I think this comment is out of date? I can't find any matches for \blift or \bLift in rustc_codegen_cranelift.
There was a problem hiding this comment.
@bjorn3 said this on Zulip:
cg_clif used to support lazy codegen in jit mode. That lifted an Instance received from the codegeb stub to the TyCtxt to codegen using. I removed this support a while back.
So the comment is out of date and can be safely removed.
| let ptr = tlv.get(); | ||
| assert!(!ptr.is_null()); | ||
| f(unsafe { *(ptr as *const &CompilerInterface<'_>) }) | ||
| f(unsafe { *(ptr as *const &CompilerInterface<'tcx>) }) |
There was a problem hiding this comment.
I think this change is ok but it does involve unsafe so I will highlight it.
There was a problem hiding this comment.
Same here, a safety comment would help!
|
r? @oli-obk |
| pub fn with_context_opt<'a, 'tcx: 'a, F, R>(f: F) -> R | ||
| where | ||
| F: for<'a, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'tcx>>) -> R, | ||
| F: FnOnce(Option<&ImplicitCtxt<'a, 'tcx>>) -> R, |
There was a problem hiding this comment.
Here and in related functions, the caller gets to dictate what 'tcx is, but there's no guarantee that the thread-local context actually lives that long, which could be a soundness problem if the return type R contains things with lifetime 'tcx.
In other words, I suspect that the for<'tcx> might be load-bearing for soundness.
There was a problem hiding this comment.
yes, that is my conclusion, too, this is unsound. In contrast to the Symbol unsoundness, where you need to move one Symbol from a TyCtxt instance to another, here you can just stack allocate a value and call this function with the short lifetimes, and it will assume your object lifes for the entirety of TyCtxt.
I don't remember if we have code that actually causes a problem here tho... Still, we could just fix that code to not require 'tcx lifetimes
| // Ensure that `ImplicitCtxt` is `DynSync`. | ||
| sync::assert_dyn_sync::<ImplicitCtxt<'_, '_>>(); | ||
|
|
||
| unsafe { f(Some(downcast(context))) } |
There was a problem hiding this comment.
As @Zalathar said:
The parts that remove
for<'tcx>bounds from thread-local-context callbacks seem like the scariest bits to me, as it might be unsound to let the caller dictate what'tcxis.
It would be great to have some safety comments both here and on downcast(). (And maybe erase().)
Separately, I'm curious how query_depth is synced between implicit and explicit contexts (if at all). But I'm not sure if removing Lift will make any existing issues worse.
| let ptr = tlv.get(); | ||
| assert!(!ptr.is_null()); | ||
| f(unsafe { *(ptr as *const &CompilerInterface<'_>) }) | ||
| f(unsafe { *(ptr as *const &CompilerInterface<'tcx>) }) |
There was a problem hiding this comment.
Same here, a safety comment would help!
There was a problem hiding this comment.
I think what you want is achievable, but you'd need to remove all the 'tcx lifetimes from the pretty printing infra and thus allow pretty printing arbitrary Ty<'_>, and thus subsequently are able to just not lift inside display impls while keeping the hkl on with_context_opt.
| pub fn with_context_opt<'a, 'tcx: 'a, F, R>(f: F) -> R | ||
| where | ||
| F: for<'a, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'tcx>>) -> R, | ||
| F: FnOnce(Option<&ImplicitCtxt<'a, 'tcx>>) -> R, |
There was a problem hiding this comment.
yes, that is my conclusion, too, this is unsound. In contrast to the Symbol unsoundness, where you need to move one Symbol from a TyCtxt instance to another, here you can just stack allocate a value and call this function with the short lifetimes, and it will assume your object lifes for the entirety of TyCtxt.
I don't remember if we have code that actually causes a problem here tho... Still, we could just fix that code to not require 'tcx lifetimes
|
Reminder, once the PR becomes ready for a review, use |
The
Lifttrait exists to work around some lifetime mismatches. But with a small number of lifetime tweaks we can eliminate it entirely. Details in individual commits.