-
Notifications
You must be signed in to change notification settings - Fork 13.8k
Strict region folders #110312
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
Strict region folders #110312
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -458,13 +458,13 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> { | |
} | ||
|
||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { | ||
if let ty::ReFree(fr) = *r { | ||
self.tcx.mk_re_free( | ||
match r.kind() { | ||
ty::ReFree(fr) => self.tcx.mk_re_free( | ||
fr.scope, | ||
self.mapping.get(&fr.bound_region).copied().unwrap_or(fr.bound_region), | ||
) | ||
} else { | ||
r | ||
), | ||
ty::ReEarlyBound(_) | ty::ReStatic => r, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably need to support |
||
r => bug!("unexpected region: {r:?}"), | ||
} | ||
} | ||
} | ||
|
@@ -765,11 +765,15 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( | |
let num_impl_substs = tcx.generics_of(impl_m.container_id(tcx)).params.len(); | ||
let ty = tcx.fold_regions(ty, |region, _| { | ||
match region.kind() { | ||
// Remap all free regions, which correspond to late-bound regions in the function. | ||
// Remap all free regions, which correspond to late-bound regions in the | ||
// function. | ||
ty::ReFree(_) => {} | ||
// Remap early-bound regions as long as they don't come from the `impl` itself. | ||
// Remap early-bound regions as long as they don't come from the `impl` | ||
// itself. | ||
ty::ReEarlyBound(ebr) if tcx.parent(ebr.def_id) != impl_m.container_id(tcx) => {} | ||
_ => return region, | ||
ty::ReEarlyBound(_) | | ||
ty::ReStatic => return region, | ||
r => bug!("unexpected region: {r:?}"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ReError here |
||
} | ||
let Some(ty::ReEarlyBound(e)) = map.get(®ion.into()).map(|r| r.expect_region().kind()) | ||
else { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1574,17 +1574,10 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> { | |
&& let hir::OpaqueTyOrigin::FnReturn(source) | hir::OpaqueTyOrigin::AsyncFn(source) = opaque.origin | ||
&& source == self.fn_def_id | ||
{ | ||
let opaque_ty = tcx.fold_regions(unshifted_opaque_ty, |re, depth| { | ||
if let ty::ReLateBound(index, bv) = re.kind() { | ||
if depth != ty::INNERMOST { | ||
return tcx.mk_re_error_with_message( | ||
DUMMY_SP, | ||
"we shouldn't walk non-predicate binders with `impl Trait`...", | ||
); | ||
} | ||
tcx.mk_re_late_bound(index.shifted_out_to_binder(self.depth), bv) | ||
} else { | ||
re | ||
let opaque_ty = tcx.fold_regions(unshifted_opaque_ty, |re, _depth| { | ||
match re.kind() { | ||
ty::ReEarlyBound(_) | ty::ReFree(_) => re, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably need to support |
||
r => bug!("unexpected region: {r:?}"), | ||
} | ||
}); | ||
for (bound, bound_span) in tcx | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -387,8 +387,10 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> { | |
|
||
fn ct_infer(&self, ty: Ty<'tcx>, _: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> { | ||
let ty = self.tcx.fold_regions(ty, |r, _| match *r { | ||
ty::ReErased => self.tcx.lifetimes.re_static, | ||
_ => r, | ||
// This is never reached in practice. If it ever is reached, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We do not hit this in practice, I checked. But as far as I know, |
||
// `ReErased` should be changed to `ReStatic`, and any other region | ||
// left alone. | ||
r => bug!("unexpected region: {r:?}"), | ||
}); | ||
self.tcx().const_error_with_message(ty, span, "bad placeholder constant") | ||
} | ||
|
@@ -1142,7 +1144,7 @@ fn infer_return_ty_for_fn_sig<'tcx>( | |
// Typeck doesn't expect erased regions to be returned from `type_of`. | ||
let fn_sig = tcx.fold_regions(fn_sig, |r, _| match *r { | ||
ty::ReErased => tcx.lifetimes.re_static, | ||
_ => r, | ||
r => bug!("unexpected region: {r:?}"), | ||
}); | ||
|
||
let mut visitor = HirPlaceholderCollector::default(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -270,7 +270,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | |
// Hack to make equality checks on types with inference variables and regions useful. | ||
let mut eraser = BottomUpFolder { | ||
tcx: self.tcx, | ||
lt_op: |_| self.tcx.lifetimes.re_erased, | ||
lt_op: |r| match r.kind() { | ||
ty::ReStatic | ty::ReVar(_) | ty::ReErased => self.tcx.lifetimes.re_erased, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This ICEs on struct Wrapper<'a, T>(&'a T);
fn foo<'a, T>() -> Wrapper<'a, T> {}
fn needs_i32(_: Wrapper<'static, i32>) {}
fn test<'a>() {
let x = foo::<'a, ()>();
needs_i32(x);
}
fn main() {} But also, I just rewrote all this code in #108687, so whatever. |
||
r => bug!("unexpected region: {r:?}"), | ||
}, | ||
ct_op: |c| c, | ||
ty_op: |t| match *t.kind() { | ||
ty::Infer(ty::TyVar(_)) => self.tcx.mk_ty_var(ty::TyVid::from_u32(0)), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -257,19 +257,20 @@ pub fn resolve_interior<'a, 'tcx>( | |
_ => mk_bound_region(None), | ||
} | ||
} | ||
// FIXME: these should use `BrNamed` | ||
// // FIXME: these should use `BrNamed` | ||
ty::ReEarlyBound(region) => { | ||
mk_bound_region(Some(fcx.tcx.def_span(region.def_id))) | ||
} | ||
ty::ReLateBound(_, ty::BoundRegion { kind, .. }) | ||
| ty::ReFree(ty::FreeRegion { bound_region: kind, .. }) => match kind { | ||
// ty::ReLateBound(_, ty::BoundRegion { kind, .. }) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Stray comment? I think it's ok to ICE on |
||
ty::ReFree(ty::FreeRegion { bound_region: kind, .. }) => match kind { | ||
ty::BoundRegionKind::BrAnon(span) => mk_bound_region(span), | ||
ty::BoundRegionKind::BrNamed(def_id, _) => { | ||
mk_bound_region(Some(fcx.tcx.def_span(def_id))) | ||
} | ||
ty::BoundRegionKind::BrEnv => mk_bound_region(None), | ||
}, | ||
_ => mk_bound_region(None), | ||
ty::ReStatic | ty::ReErased => mk_bound_region(None), | ||
r => bug!("unexpected region: {r:?}"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We must handle fn missing() -> &'missing () { &() }
async fn async_fn() {}
fn main() {
async {
let x = missing();
async_fn().await;
drop(x);
};
} |
||
}; | ||
let r = fcx.tcx.mk_re_late_bound(current_depth, br); | ||
r | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -774,7 +774,16 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EraseEarlyRegions<'tcx> { | |
} | ||
} | ||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { | ||
if r.is_late_bound() { r } else { self.tcx.lifetimes.re_erased } | ||
match r.kind() { | ||
ty::ReLateBound(..) => r, | ||
ty::ReEarlyBound(_) | ||
| ty::ReFree(..) | ||
| ty::ReStatic | ||
| ty::RePlaceholder(_) | ||
| ty::ReErased | ||
| ty::ReError(_) => self.tcx.lifetimes.re_erased, | ||
ty::ReVar(_) => bug!("unexpected region: {r:?}"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It makes me somewhat nervous that we need to handle |
||
} | ||
} | ||
} | ||
|
||
|
@@ -802,8 +811,15 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> { | |
} | ||
|
||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { | ||
debug_assert!(!r.is_late_bound(), "Should not be resolving bound region."); | ||
self.tcx.lifetimes.re_erased | ||
match r.kind() { | ||
ty::ReEarlyBound(_) | ||
| ty::ReFree(_) | ||
| ty::ReStatic | ||
| ty::ReVar(_) | ||
| ty::RePlaceholder(_) | ||
| ty::ReError(_) => self.tcx.lifetimes.re_erased, | ||
r => bug!("unexpected region: {r:?}"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ReLateBound and ReErased missing from here should be ok. |
||
} | ||
} | ||
|
||
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -220,12 +220,19 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for InferenceFudger<'a, 'tcx> { | |
} | ||
|
||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { | ||
if let ty::ReVar(vid) = *r && self.region_vars.0.contains(&vid) { | ||
let idx = vid.index() - self.region_vars.0.start.index(); | ||
let origin = self.region_vars.1[idx]; | ||
return self.infcx.next_region_var(origin); | ||
match r.kind() { | ||
ty::ReVar(vid) if self.region_vars.0.contains(&vid) => { | ||
let idx = vid.index() - self.region_vars.0.start.index(); | ||
let origin = self.region_vars.1[idx]; | ||
return self.infcx.next_region_var(origin); | ||
} | ||
ty::ReEarlyBound(_) | ||
| ty::ReLateBound(..) | ||
| ty::ReFree(_) | ||
| ty::ReStatic | ||
| ty::ReVar(_) => r, | ||
r => bug!("unexpected region: {r:?}"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ICE: fn test<T>(x: &'missing T) -> &'missing T { todo!() }
fn main() {
let &() = test(&());
} Need to handle |
||
} | ||
r | ||
} | ||
|
||
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -989,7 +989,18 @@ impl<'tcx> LexicalRegionResolutions<'tcx> { | |
where | ||
T: TypeFoldable<TyCtxt<'tcx>>, | ||
{ | ||
tcx.fold_regions(value, |r, _db| self.resolve_region(tcx, r)) | ||
tcx.fold_regions(value, |r, _db| { | ||
match r.kind() { | ||
ty::ReEarlyBound(_) | ||
| ty::ReFree(_) | ||
| ty::ReStatic | ||
| ty::ReVar(_) | ||
| ty::RePlaceholder(_) | ||
| ty::ReError(_) => {} | ||
r => bug!("unexpected region: {r:?}"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, also |
||
} | ||
self.resolve_region(tcx, r) | ||
}) | ||
} | ||
|
||
fn value(&self, rid: RegionVid) -> &VarValue<'tcx> { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -91,7 +91,13 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for OpportunisticRegionResolver<'a, 'tcx | |
.borrow_mut() | ||
.unwrap_region_constraints() | ||
.opportunistic_resolve_var(TypeFolder::interner(self), vid), | ||
_ => r, | ||
ty::ReEarlyBound(_) | ||
| ty::ReLateBound(..) | ||
| ty::ReFree(_) | ||
| ty::ReStatic | ||
| ty::RePlaceholder(_) | ||
| ty::ReErased => r, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm actually surprised |
||
r => bug!("unexpected region: {r:?}"), | ||
} | ||
} | ||
|
||
|
@@ -238,7 +244,13 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for FullTypeResolver<'a, 'tcx> { | |
.as_ref() | ||
.expect("region resolution not performed") | ||
.resolve_region(self.infcx.tcx, r)), | ||
_ => Ok(r), | ||
ty::ReEarlyBound(_) | ||
| ty::ReLateBound(..) | ||
| ty::ReFree(_) | ||
| ty::ReStatic | ||
| ty::RePlaceholder(_) | ||
| ty::ReError(_) => Ok(r), | ||
r => bug!("unexpected region: {r:?}"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -104,7 +104,13 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { | |
let proj_replacer = &mut BottomUpFolder { | ||
tcx: cx.tcx, | ||
ty_op: |ty| if ty == proj_ty { proj_term } else { ty }, | ||
lt_op: |lt| lt, | ||
lt_op: |lt| { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will (probably?) ICE if we ever make lints fire on code with errors previously run on it:
|
||
match lt.kind() { | ||
ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic => {} | ||
r => bug!("unexpected region: {r:?}"), | ||
} | ||
lt | ||
}, | ||
ct_op: |ct| ct, | ||
}; | ||
// For example, in `impl Trait<Assoc = impl Send>`, for all of the bounds on `Assoc`, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -116,11 +116,19 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> { | |
#[instrument(skip(self), level = "debug", ret)] | ||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { | ||
match *r { | ||
// All region variants occur in this match. | ||
ty::ReLateBound(debruijn, _) if debruijn < self.current_index => { | ||
debug!(?self.current_index, "skipped bound region"); | ||
r | ||
} | ||
_ => { | ||
ty::ReEarlyBound(_) | ||
| ty::ReLateBound(..) | ||
| ty::ReFree(_) | ||
| ty::ReStatic | ||
| ty::ReVar(_) | ||
| ty::RePlaceholder(_) | ||
| ty::ReErased | ||
| ty::ReError(_) => { | ||
debug!(?self.current_index, "folding free region"); | ||
(self.fold_region_fn)(r, self.current_index) | ||
} | ||
|
@@ -204,6 +212,7 @@ where | |
|
||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { | ||
match *r { | ||
// All region variants occur in this match. | ||
ty::ReLateBound(debruijn, br) if debruijn == self.current_index => { | ||
let region = self.delegate.replace_region(br); | ||
if let ty::ReLateBound(debruijn1, br) = *region { | ||
|
@@ -217,7 +226,14 @@ where | |
region | ||
} | ||
} | ||
_ => r, | ||
ty::ReEarlyBound(..) | ||
| ty::ReLateBound(..) | ||
| ty::ReFree(_) | ||
| ty::ReStatic | ||
| ty::ReVar(_) | ||
| ty::RePlaceholder(_) | ||
| ty::ReErased | ||
| ty::ReError(_) => r, | ||
} | ||
} | ||
|
||
|
@@ -452,7 +468,8 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Shifter<'tcx> { | |
let debruijn = debruijn.shifted_in(self.amount); | ||
self.tcx.mk_re_late_bound(debruijn, br) | ||
} | ||
_ => r, | ||
ty::ReEarlyBound(_) | ty::ReLateBound(..) | ty::ReStatic => r, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to handle type FuncTuple<A> = (A, fn(A));
type MetaFuncTuple = for<'a> fn(FuncTuple<&'missing &'a i32>);
fn main() {} |
||
r => bug!("unexpected region: {r:?}"), | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -840,7 +840,8 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for SubstFolder<'a, 'tcx> { | |
None => region_param_out_of_range(data, self.substs), | ||
} | ||
} | ||
_ => r, | ||
ty::ReLateBound(..) | ty::ReFree(_) | ty::ReStatic | ty::ReErased | ty::ReError(_) => r, | ||
r => bug!("unexpected region: {r:?}"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm surprised and skeptical that we can't get this to ICE with some This probably should be an ICE for |
||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -85,20 +85,20 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>( | |
} | ||
} | ||
|
||
pub(in crate::solve) fn replace_erased_lifetimes_with_bound_vars<'tcx>( | ||
fn replace_erased_lifetimes_with_bound_vars<'tcx>( | ||
tcx: TyCtxt<'tcx>, | ||
ty: Ty<'tcx>, | ||
) -> ty::Binder<'tcx, Ty<'tcx>> { | ||
debug_assert!(!ty.has_late_bound_regions()); | ||
let mut counter = 0; | ||
let ty = tcx.fold_regions(ty, |mut r, current_depth| { | ||
if let ty::ReErased = r.kind() { | ||
let ty = tcx.fold_regions(ty, |r, current_depth| match r.kind() { | ||
ty::ReErased => { | ||
let br = | ||
ty::BoundRegion { var: ty::BoundVar::from_u32(counter), kind: ty::BrAnon(None) }; | ||
counter += 1; | ||
r = tcx.mk_re_late_bound(current_depth, br); | ||
tcx.mk_re_late_bound(current_depth, br) | ||
} | ||
r | ||
r => bug!("unexpected region: {r:?}"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess this is fine. This probably should have some correctness comment saying that all (free) regions are erased here. |
||
}); | ||
let bound_vars = tcx.mk_bound_variable_kinds_from_iter( | ||
(0..counter).map(|_| ty::BoundVariableKind::Region(ty::BrAnon(None))), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -242,7 +242,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'_, 'tcx> { | |
} | ||
}, | ||
|
||
ty::ReError(_) => return r, | ||
r => bug!("unexpected region: {r:?}"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ICE: // compile-flags: -Ztrait-solver=next
struct Wrapper<'a, 'b>(&'a (), &'b ());
fn missing<'a>() -> Wrapper<'missing, 'a> { todo!() }
fn main() {
} |
||
}; | ||
|
||
let existing_bound_var = match self.canonicalize_mode { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -776,7 +776,12 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for BoundVarReplacer<'_, 'tcx> { | |
self.mapped_regions.insert(p, br); | ||
self.infcx.tcx.mk_re_placeholder(p) | ||
} | ||
_ => r, | ||
ty::ReEarlyBound(_) | ||
| ty::ReLateBound(..) | ||
| ty::ReFree(_) | ||
| ty::ReStatic | ||
| ty::RePlaceholder(_) => r, | ||
r => bug!("unexpected region: {r:?}"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ICE: trait Trait<'a, 'b> {
type Assoc;
}
fn foo() where for<'a> fn(<() as Trait<'a, 'missing>>::Assoc): Send {}
fn main() {
foo();
} Other than that, what's still missing? |
||
} | ||
} | ||
|
||
|
@@ -879,7 +884,12 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> { | |
.borrow_mut() | ||
.unwrap_region_constraints() | ||
.opportunistic_resolve_var(self.infcx.tcx, vid), | ||
_ => r0, | ||
ty::ReEarlyBound(_) | ||
| ty::ReLateBound(..) | ||
| ty::ReStatic | ||
| ty::RePlaceholder(_) | ||
| ty::ReErased => r0, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need |
||
r => bug!("unexpected region: {r:?}"), | ||
}; | ||
|
||
let r2 = match *r1 { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2459,7 +2459,13 @@ impl<'tcx> SelectionContext<'_, 'tcx> { | |
let value = value.fold_with(&mut BottomUpFolder { | ||
tcx: self.tcx(), | ||
ty_op: |_| err, | ||
lt_op: |l| l, | ||
lt_op: |lt| { | ||
match lt { | ||
// This is never reached in practice. If it ever is reached, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only reason we never hit this in practice is because our tests are lacking. We can take use std::marker::PhantomData;
pub trait StatefulFuture<S> {}
pub struct Never<T>(PhantomData<T>);
impl<T> StatefulFuture<T> for Never<T> {}
pub struct RaceBuilder<F, S> {
future: F,
_phantom: PhantomData<S>,
}
impl<T, F> RaceBuilder<T, F>
where
F: StatefulFuture<Option<T>>,
{
pub fn when(self) {}
}
pub struct Race<T, R> {
race: R,
_phantom: PhantomData<T>,
}
impl<T, R> Race<T, R>
where
R: Fn(RaceBuilder<T, Never<T>>),
{
pub fn new(race: R) {}
}
fn main() {
Race::new(|race| race.when()); //~ ERROR type annotations needed
} Also, this should return |
||
// it should just return `ReErased`. | ||
r => bug!("unexpected region: {r:?}"), | ||
} | ||
}, | ||
ct_op: |c| c, | ||
}); | ||
Normalized { value, obligations: vec![] } | ||
|
@@ -3007,16 +3013,16 @@ fn bind_generator_hidden_types_above<'tcx>( | |
|
||
// Only remap erased regions if we use them. | ||
if considering_regions { | ||
ty = tcx.fold_regions(ty, |mut r, current_depth| { | ||
if let ty::ReErased = r.kind() { | ||
ty = tcx.fold_regions(ty, |r, current_depth| match r.kind() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cjgillot made this so all lifetimes are explicitly erased, so I think this is ok. |
||
ty::ReErased => { | ||
let br = ty::BoundRegion { | ||
var: ty::BoundVar::from_u32(counter), | ||
kind: ty::BrAnon(None), | ||
}; | ||
counter += 1; | ||
r = tcx.mk_re_late_bound(current_depth, br); | ||
tcx.mk_re_late_bound(current_depth, br) | ||
} | ||
r | ||
r => bug!("unexpected region: {r:?}"), | ||
}) | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1045,7 +1045,8 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for NamedBoundVarSubstitutor<'a, 'tcx> { | |
ty::BrEnv => unimplemented!(), | ||
ty::BrAnon(..) => {} | ||
}, | ||
_ => (), | ||
ty::ReLateBound(..) | ty::ReStatic => (), | ||
r => bug!("unexpected region: {r:?}"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This probably ICEs on
But that's obscured by other canonicalizer+ReError bugs in chalk. |
||
}; | ||
|
||
r.super_fold_with(self) | ||
|
@@ -1141,8 +1142,9 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ParamsSubstitutor<'tcx> { | |
self.tcx.mk_re_late_bound(self.binder_index, br) | ||
} | ||
}, | ||
|
||
_ => r.super_fold_with(self), | ||
// Other region kinds might need the same treatment here. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Canonicalization already canonicalizes all free regions for chalk. We probably shouldn't even have this folder at all. Unrelated, but this ICEs on nightly already, lol:
|
||
ty::ReLateBound(..) => r.super_fold_with(self), | ||
compiler-errors marked this conversation as resolved.
Show resolved
Hide resolved
|
||
r => bug!("unexpected region: {r:?}"), | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -287,16 +287,18 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> { | |
// bounds of the RPITIT. Shift these binders back out when | ||
// constructing the top-level projection predicate. | ||
let shifted_alias_ty = self.tcx.fold_regions(unshifted_alias_ty, |re, depth| { | ||
if let ty::ReLateBound(index, bv) = re.kind() { | ||
if depth != ty::INNERMOST { | ||
return self.tcx.mk_re_error_with_message( | ||
DUMMY_SP, | ||
"we shouldn't walk non-predicate binders with `impl Trait`...", | ||
); | ||
match re.kind() { | ||
ty::ReEarlyBound(_) => re, | ||
ty::ReLateBound(index, bv) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This ICEs on #![feature(return_position_impl_trait_in_trait)]
use std::ops::Deref;
trait Foo {
fn test<'a: 'a>() -> impl Deref<Target = impl Sized> { &() }
}
fn main() {} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, that error is coming from somewhere else in borrowck. |
||
if depth != ty::INNERMOST { | ||
return self.tcx.mk_re_error_with_message( | ||
DUMMY_SP, | ||
"we shouldn't walk non-predicate binders with `impl Trait`...", | ||
); | ||
} | ||
self.tcx.mk_re_late_bound(index.shifted_out_to_binder(self.depth), bv) | ||
} | ||
self.tcx.mk_re_late_bound(index.shifted_out_to_binder(self.depth), bv) | ||
} else { | ||
re | ||
r => bug!("unexpected region: {r:?}"), | ||
} | ||
}); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
use rustc_data_structures::fx::FxHashSet; | ||
use rustc_hir as hir; | ||
use rustc_hir::lang_items::LangItem; | ||
use rustc_middle::ty::{self, Region, RegionVid, TypeFoldable, TypeSuperFoldable}; | ||
use rustc_middle::ty::{self, Region, RegionVid, TypeFoldable}; | ||
use rustc_trait_selection::traits::auto_trait::{self, AutoTraitResult}; | ||
use thin_vec::ThinVec; | ||
|
||
|
@@ -740,10 +740,10 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for RegionReplacer<'a, 'tcx> { | |
} | ||
|
||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { | ||
(match *r { | ||
ty::ReVar(vid) => self.vid_to_region.get(&vid).cloned(), | ||
_ => None, | ||
}) | ||
.unwrap_or_else(|| r.super_fold_with(self)) | ||
match *r { | ||
ty::ReVar(vid) => self.vid_to_region.get(&vid).cloned().unwrap_or(r), | ||
ty::ReEarlyBound(_) | ty::ReStatic | ty::ReLateBound(..) => r, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is probably fine. If I were being defensive, I'd also include Some comment to the effect of "these are the regions that can be seen in AST" as justification. |
||
r => 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 think
ReErased
is the only kind we expect here.