-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
fix multiple issues when promoting type-test subject #108691
Conversation
r? @Nilstrieb (rustbot has picked a reviewer for you, use r? to override) |
Don't require a region to have an `external_name` in order to be promoted.
Smarter and simpler!
74d14a3
to
10da771
Compare
@rustbot review |
Wow @aliemjay. Impressive. |
This comment has been minimized.
This comment has been minimized.
Want to go ahead and queue a crater run since these kinds of changes are always senstive. @bors try |
⌛ Trying commit 427dc18 with merge 303604bb848977091b2fdfc36579c25e56c6889c... |
☀️ Try build successful - checks-actions |
@craterbot check |
🚧 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
/// Represents a `ty::Ty` for use in [`ClosureOutlivesSubject`]. | ||
/// | ||
/// This indirection is necessary because the type may include `ReVar` regions, | ||
/// which is what we use internally within NLL code, | ||
/// and we can't use `ReVar`s in a query response. | ||
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)] | ||
pub struct ClosureOutlivesSubjectTy<'tcx> { | ||
inner: Ty<'tcx>, | ||
} | ||
|
||
impl<'tcx> ClosureOutlivesSubjectTy<'tcx> { | ||
// All regions of `ty` must be of kind `ReVar` | ||
// and must point to an early-bound region in the closure's signature. | ||
pub fn new(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self { | ||
let inner = tcx.fold_regions(ty, |r, depth| match r.kind() { | ||
ty::ReVar(vid) => { | ||
let br = ty::BoundRegion { | ||
var: ty::BoundVar::new(vid.index()), | ||
kind: ty::BrAnon(0u32, None), | ||
}; | ||
tcx.mk_re_late_bound(depth, br) | ||
} | ||
_ => bug!("unexpected region in ClosureOutlivesSubjectTy: {r:?}"), | ||
}); | ||
|
||
Self { inner } | ||
} | ||
|
||
pub fn instantiate( | ||
self, | ||
tcx: TyCtxt<'tcx>, | ||
mut map: impl FnMut(ty::RegionVid) -> ty::Region<'tcx>, | ||
) -> Ty<'tcx> { | ||
tcx.fold_regions(self.inner, |r, depth| match r.kind() { | ||
ty::ReLateBound(debruijn, br) => { | ||
debug_assert_eq!(debruijn, depth); | ||
map(ty::RegionVid::new(br.var.index())) | ||
} | ||
_ => bug!("unexpected region {r:?}"), | ||
}) | ||
} | ||
} | ||
|
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 don't really like this hack. Trying to think of a better alternative though.
I think it would be better to "formalize" this in some sense by having some way to have explicit "binders" of the captured regions, Or expanding on the concept of external_name
a bit.
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.
Is it a hard-and-fast rule that ty::Binder
is the only binder for ReLateBound
regions? I don't think so -- we already have Canonical<T>
which serves as a binder too. The only limitation is that the type can't implement TypeFoldable
/Visitable because these only support ty::Binder.
I tweaked it a bit in a later commit to make it more clear.
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 think the concern for me is less about Binder
, and more so that we aren't being explicit about the "bound variables" contained within (and what they mean to those that receive the "canonical" form).
What seems better to me is some more explicit "closure nameable" set of "bound vars" that this has access to. When borrow checking the context around the closure, the mapping between the "real" variables and the ones available to the closure is clear (maybe even trivial), but even if not in that context, it's still "just a set of bound vars".
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 agree. This binder needs to store more context, but this is preexisting problem - the parent struct ClosureOutlivesRequirements
is already littered by RegionVid
s with no context. Actually this is exactly the reason I haven't made this binder type more generic like RegionVarBinder<T>
and made it explicit in the docs that it should be used in the context of ClosureOutlivesRequirements
. The RegionVid
s there are already used to index into the early-bound regions of the closure type.
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.
Yeah, definitely a preexisting problem that's just more pointy now. I think we can land, but we should chat about a followup for this (and if it's something you want to pursue or something we should offload to someone else).
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'm happy to work on a followup PR. Let me open an issue to track this..
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'm happy to work on a followup PR. Let me open an issue to track this..
did this happen?
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.
oops I missed that. I've opened #111310.
🎉 Experiment
|
@bors r+ rollup=never |
Going to both stable and beta nominate. Unfortunately, we're going to miss the 1.67 stable to backport, but it's probably still worth getting this into 1.68. |
☀️ Test successful - checks-actions |
Finished benchmarking commit (8824994): comparison URL. Overall result: no relevant changes - no action needed@rustbot label: -perf-regression Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)This benchmark run did not return any relevant results for this metric. CyclesResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
|
ty::ReVar(vid) => { | ||
let br = ty::BoundRegion { | ||
var: ty::BoundVar::new(vid.index()), | ||
kind: ty::BrAnon(0u32, None), |
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.
doesn't matter too much, but this should be vid.index()
instead of 0
, shouldn't it?
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.
yeah I changed it in 97381d2.
…k-Simulacrum [beta] backport This PR backports: - rust-lang#108901: fix: evaluate with wrong obligation stack - rust-lang#108754: Retry `pred_known_to_hold_modulo_regions` with fulfillment if ambiguous - rust-lang#108691: fix multiple issues when promoting type-test subject It also bumps to the released stable. r? `@Mark-Simulacrum`
Multiple interdependent fixes. See linked issues for a short description of each.
When Promoting a type-test
T: 'a
from within the closure back to its parent function, there are a couple pre-existing bugs and limitations. They were exposed by the recent changes to opaque types because the type-test subject (T
) is no longer a simple ParamTy.Commit 1:
Fixes #108635
Fixes #107426
Commit 2:
Fixes #108639
Commit 3:
Fixes #107516