Rollup merge of #152323 - JohnTitor:issue-135845-2, r=lcnr
Fix ICE in borrowck when recovering `fn_sig` for `-> _` (Should be) a proper fix for rust-lang/rust#135845, replaces a dummy binder with a concrete one not to ICE, as mentioned in https://github.com/rust-lang/rust/pull/147631#issuecomment-3460724226. Fixes rust-lang/rust#135845 r? @lcnr @jackh726
This commit is contained in:
commit
9d662b5815
4 changed files with 101 additions and 8 deletions
|
|
@ -1063,6 +1063,70 @@ fn lower_fn_sig_recovering_infer_ret_ty<'tcx>(
|
|||
)
|
||||
}
|
||||
|
||||
/// Convert `ReLateParam`s in `value` back into `ReBound`s and bind it with `bound_vars`.
|
||||
fn late_param_regions_to_bound<'tcx, T>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
scope: DefId,
|
||||
bound_vars: &'tcx ty::List<ty::BoundVariableKind<'tcx>>,
|
||||
value: T,
|
||||
) -> ty::Binder<'tcx, T>
|
||||
where
|
||||
T: ty::TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
let value = fold_regions(tcx, value, |r, debruijn| match r.kind() {
|
||||
ty::ReLateParam(lp) => {
|
||||
// Should be in scope, otherwise inconsistency happens somewhere.
|
||||
assert_eq!(lp.scope, scope);
|
||||
|
||||
let br = match lp.kind {
|
||||
// These variants preserve the bound var index.
|
||||
kind @ (ty::LateParamRegionKind::Anon(idx)
|
||||
| ty::LateParamRegionKind::NamedAnon(idx, _)) => {
|
||||
let idx = idx as usize;
|
||||
let var = ty::BoundVar::from_usize(idx);
|
||||
|
||||
let Some(ty::BoundVariableKind::Region(kind)) = bound_vars.get(idx).copied()
|
||||
else {
|
||||
bug!("unexpected late-bound region {kind:?} for bound vars {bound_vars:?}");
|
||||
};
|
||||
|
||||
ty::BoundRegion { var, kind }
|
||||
}
|
||||
|
||||
// For named regions, look up the corresponding bound var.
|
||||
ty::LateParamRegionKind::Named(def_id) => bound_vars
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(idx, bv)| match bv {
|
||||
ty::BoundVariableKind::Region(kind @ ty::BoundRegionKind::Named(did))
|
||||
if did == def_id =>
|
||||
{
|
||||
Some(ty::BoundRegion { var: ty::BoundVar::from_usize(idx), kind })
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.unwrap(),
|
||||
|
||||
ty::LateParamRegionKind::ClosureEnv => bound_vars
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(idx, bv)| match bv {
|
||||
ty::BoundVariableKind::Region(kind @ ty::BoundRegionKind::ClosureEnv) => {
|
||||
Some(ty::BoundRegion { var: ty::BoundVar::from_usize(idx), kind })
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.unwrap(),
|
||||
};
|
||||
|
||||
ty::Region::new_bound(tcx, debruijn, br)
|
||||
}
|
||||
_ => r,
|
||||
});
|
||||
|
||||
ty::Binder::bind_with_vars(value, bound_vars)
|
||||
}
|
||||
|
||||
fn recover_infer_ret_ty<'tcx>(
|
||||
icx: &ItemCtxt<'tcx>,
|
||||
infer_ret_ty: &'tcx hir::Ty<'tcx>,
|
||||
|
|
@ -1138,13 +1202,22 @@ fn recover_infer_ret_ty<'tcx>(
|
|||
);
|
||||
}
|
||||
let guar = diag.emit();
|
||||
ty::Binder::dummy(tcx.mk_fn_sig(
|
||||
|
||||
// If we return a dummy binder here, we can ICE later in borrowck when it encounters
|
||||
// `ReLateParam` regions (e.g. in a local type annotation) which weren't registered via the
|
||||
// signature binder. See #135845.
|
||||
let bound_vars = tcx.late_bound_vars(hir_id);
|
||||
let scope = def_id.to_def_id();
|
||||
|
||||
let fn_sig = tcx.mk_fn_sig(
|
||||
fn_sig.inputs().iter().copied(),
|
||||
recovered_ret_ty.unwrap_or_else(|| Ty::new_error(tcx, guar)),
|
||||
fn_sig.c_variadic,
|
||||
fn_sig.safety,
|
||||
fn_sig.abi,
|
||||
))
|
||||
);
|
||||
|
||||
late_param_regions_to_bound(tcx, scope, bound_vars, fn_sig)
|
||||
}
|
||||
|
||||
pub fn suggest_impl_trait<'tcx>(
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
//@ known-bug: #135845
|
||||
struct S<'a, T: ?Sized>(&'a T);
|
||||
|
||||
fn b<'a>() -> S<'static, _> {
|
||||
S::<'a>(&0)
|
||||
}
|
||||
11
tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.rs
Normal file
11
tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// Regression test for #135845.
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
fn b<'a>() -> _ {
|
||||
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121]
|
||||
let _: PhantomData<&'a ()> = PhantomData;
|
||||
0
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
15
tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.stderr
Normal file
15
tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.stderr
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
|
||||
--> $DIR/recover-infer-ret-ty-issue-135845.rs:5:15
|
||||
|
|
||||
LL | fn b<'a>() -> _ {
|
||||
| ^ not allowed in type signatures
|
||||
|
|
||||
help: replace with the correct return type
|
||||
|
|
||||
LL - fn b<'a>() -> _ {
|
||||
LL + fn b<'a>() -> i32 {
|
||||
|
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0121`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue