-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Don't anonymize bound region names during typeck #89250
Conversation
Once this anonymization has performed, we have no way of recovering the original names during NLL borrow checking. Keeping the original names allows error messages in full NLL mode to contain the original bound region names. As a result, the typeck results may contain types that differ only in the names used for their bound regions. However, anonimization of bound regions does not guarantee that all distinct types are unqual (e.g. not subtypes of each other). For example, `for<'a> fn(&'a u32, &'a u32)` and `for<'b, 'c> fn(&'b u32, &'c u32)` are subtypes of each other, as explained here: https://github.com/rust-lang/rust/blob/63cc2bb3d07d6c726dfcdc5f95cbe5ed4760641a/compiler/rustc_infer/src/infer/nll_relate/mod.rs#L682-L690 Therefore, any code handling types with higher-ranked regions already needs to handle the case where two distinct `Ty`s are 'actually' equal.
(rust-highfive has picked a reviewer for you, use r? to override) |
@bors try @rust-timer queue |
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
⌛ Trying commit 78013f2 with merge 1ebe71fdc5fb1f660c40031059cb73ee72696e87... |
☀️ Try build successful - checks-actions |
Queued 1ebe71fdc5fb1f660c40031059cb73ee72696e87 with parent ac8dd1b, future comparison URL. |
Finished benchmarking commit (1ebe71fdc5fb1f660c40031059cb73ee72696e87): comparison url. Summary: This change led to moderate relevant regressions 😿 in compiler performance.
If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR led to changes in compiler perf. Next Steps: If you can justify the regressions found in this try perf run, please indicate this with @bors rollup=never |
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.
Changes look good.
struct EraseEarlyRegions<'tcx> { | ||
tcx: TyCtxt<'tcx>, | ||
} |
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.
Isn't there one of these already somewhere in the codebase?
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.
I thought so too, but I couldn't find one.
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.
I must have been thinking of the following, which looks like the exact opposite 😅
rust/compiler/rustc_typeck/src/hir_wf_check.rs
Lines 169 to 188 in be76bdf
struct EraseAllBoundRegions<'tcx> { | |
tcx: TyCtxt<'tcx>, | |
} | |
// Higher ranked regions are complicated. | |
// To make matters worse, the HIR WF check can instantiate them | |
// outside of a `Binder`, due to the way we (ab)use | |
// `ItemCtxt::to_ty`. To make things simpler, we just erase all | |
// of them, regardless of depth. At worse, this will give | |
// us an inaccurate span for an error message, but cannot | |
// lead to unsoundess (we call `delay_span_bug` at the start | |
// of `diagnostic_hir_wf_check`). | |
impl<'tcx> TypeFolder<'tcx> for EraseAllBoundRegions<'tcx> { | |
fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { | |
self.tcx | |
} | |
fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> { | |
if let ty::ReLateBound(..) = r { &ty::ReErased } else { r } | |
} | |
} |
📌 Commit 78013f2 has been approved by |
⌛ Testing commit 78013f2 with merge 67c26d34632e929389f62e064008339f1bc9cf7d... |
💔 Test failed - checks-actions |
The job Click to see the possible cause of the failure (guessed by this bot)
|
@bors retry |
☀️ Test successful - checks-actions |
Finished benchmarking commit (69c1c6a): comparison url. Summary: This benchmark run did not return any relevant changes. If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. @rustbot label: -perf-regression |
Once this anonymization has performed, we have no
way of recovering the original names during NLL
borrow checking. Keeping the original names allows
error messages in full NLL mode to contain the original
bound region names.
As a result, the typeck results may contain types that
differ only in the names used for their bound regions. However,
anonimization of bound regions does not guarantee that
all distinct types are unqual (e.g. not subtypes of each other).
For example,
for<'a> fn(&'a u32, &'a u32)
andfor<'b, 'c> fn(&'b u32, &'c u32)
are subtypes of each other,as explained here:
rust/compiler/rustc_infer/src/infer/nll_relate/mod.rs
Lines 682 to 690 in 63cc2bb
Therefore, any code handling types with higher-ranked regions already
needs to handle the case where two distinct
Ty
s are 'actually'equal.