Fix ICE in borrowck when recovering fn_sig for -> _

This commit is contained in:
Yuki Okushi 2026-02-08 16:42:28 +09:00
parent 47611e1604
commit 7d7b381660
4 changed files with 80 additions and 8 deletions

View file

@ -1138,13 +1138,65 @@ 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,
))
);
let fn_sig = fold_regions(tcx, fn_sig, |r, _| match r.kind() {
ty::ReLateParam(lp) if lp.scope == scope => {
let br = match lp.kind {
ty::LateParamRegionKind::Anon(idx) | ty::LateParamRegionKind::NamedAnon(idx, _) => {
let idx = idx as usize;
match bound_vars.get(idx).copied() {
Some(ty::BoundVariableKind::Region(br_kind)) => Some(ty::BoundRegion {
var: ty::BoundVar::from_usize(idx),
kind: br_kind,
}),
_ => None,
}
}
ty::LateParamRegionKind::Named(def_id) => {
bound_vars.iter().enumerate().find_map(|(idx, bv)| match bv {
ty::BoundVariableKind::Region(
br_kind @ ty::BoundRegionKind::Named(did),
) if did == def_id => Some(ty::BoundRegion {
var: ty::BoundVar::from_usize(idx),
kind: br_kind,
}),
_ => None,
})
}
ty::LateParamRegionKind::ClosureEnv => {
bound_vars.iter().enumerate().find_map(|(idx, bv)| match bv {
ty::BoundVariableKind::Region(
br_kind @ ty::BoundRegionKind::ClosureEnv,
) => Some(ty::BoundRegion {
var: ty::BoundVar::from_usize(idx),
kind: br_kind,
}),
_ => None,
})
}
};
br.map(|br| ty::Region::new_bound(tcx, ty::INNERMOST, br))
.unwrap_or_else(|| ty::Region::new_error(tcx, guar))
}
_ => r,
});
ty::Binder::bind_with_vars(fn_sig, bound_vars)
}
pub fn suggest_impl_trait<'tcx>(

View file

@ -1,6 +0,0 @@
//@ known-bug: #135845
struct S<'a, T: ?Sized>(&'a T);
fn b<'a>() -> S<'static, _> {
S::<'a>(&0)
}

View 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() {}

View 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`.