Skip to content

Commit cd97276

Browse files
authored
Unrolled build for #152323
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 #135845, replaces a dummy binder with a concrete one not to ICE, as mentioned in #147631 (comment). Fixes #135845 r? @lcnr @jackh726
2 parents a423f68 + b0f2ac8 commit cd97276

File tree

4 files changed

+101
-8
lines changed

4 files changed

+101
-8
lines changed

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,6 +1063,70 @@ fn lower_fn_sig_recovering_infer_ret_ty<'tcx>(
10631063
)
10641064
}
10651065

1066+
/// Convert `ReLateParam`s in `value` back into `ReBound`s and bind it with `bound_vars`.
1067+
fn late_param_regions_to_bound<'tcx, T>(
1068+
tcx: TyCtxt<'tcx>,
1069+
scope: DefId,
1070+
bound_vars: &'tcx ty::List<ty::BoundVariableKind<'tcx>>,
1071+
value: T,
1072+
) -> ty::Binder<'tcx, T>
1073+
where
1074+
T: ty::TypeFoldable<TyCtxt<'tcx>>,
1075+
{
1076+
let value = fold_regions(tcx, value, |r, debruijn| match r.kind() {
1077+
ty::ReLateParam(lp) => {
1078+
// Should be in scope, otherwise inconsistency happens somewhere.
1079+
assert_eq!(lp.scope, scope);
1080+
1081+
let br = match lp.kind {
1082+
// These variants preserve the bound var index.
1083+
kind @ (ty::LateParamRegionKind::Anon(idx)
1084+
| ty::LateParamRegionKind::NamedAnon(idx, _)) => {
1085+
let idx = idx as usize;
1086+
let var = ty::BoundVar::from_usize(idx);
1087+
1088+
let Some(ty::BoundVariableKind::Region(kind)) = bound_vars.get(idx).copied()
1089+
else {
1090+
bug!("unexpected late-bound region {kind:?} for bound vars {bound_vars:?}");
1091+
};
1092+
1093+
ty::BoundRegion { var, kind }
1094+
}
1095+
1096+
// For named regions, look up the corresponding bound var.
1097+
ty::LateParamRegionKind::Named(def_id) => bound_vars
1098+
.iter()
1099+
.enumerate()
1100+
.find_map(|(idx, bv)| match bv {
1101+
ty::BoundVariableKind::Region(kind @ ty::BoundRegionKind::Named(did))
1102+
if did == def_id =>
1103+
{
1104+
Some(ty::BoundRegion { var: ty::BoundVar::from_usize(idx), kind })
1105+
}
1106+
_ => None,
1107+
})
1108+
.unwrap(),
1109+
1110+
ty::LateParamRegionKind::ClosureEnv => bound_vars
1111+
.iter()
1112+
.enumerate()
1113+
.find_map(|(idx, bv)| match bv {
1114+
ty::BoundVariableKind::Region(kind @ ty::BoundRegionKind::ClosureEnv) => {
1115+
Some(ty::BoundRegion { var: ty::BoundVar::from_usize(idx), kind })
1116+
}
1117+
_ => None,
1118+
})
1119+
.unwrap(),
1120+
};
1121+
1122+
ty::Region::new_bound(tcx, debruijn, br)
1123+
}
1124+
_ => r,
1125+
});
1126+
1127+
ty::Binder::bind_with_vars(value, bound_vars)
1128+
}
1129+
10661130
fn recover_infer_ret_ty<'tcx>(
10671131
icx: &ItemCtxt<'tcx>,
10681132
infer_ret_ty: &'tcx hir::Ty<'tcx>,
@@ -1138,13 +1202,22 @@ fn recover_infer_ret_ty<'tcx>(
11381202
);
11391203
}
11401204
let guar = diag.emit();
1141-
ty::Binder::dummy(tcx.mk_fn_sig(
1205+
1206+
// If we return a dummy binder here, we can ICE later in borrowck when it encounters
1207+
// `ReLateParam` regions (e.g. in a local type annotation) which weren't registered via the
1208+
// signature binder. See #135845.
1209+
let bound_vars = tcx.late_bound_vars(hir_id);
1210+
let scope = def_id.to_def_id();
1211+
1212+
let fn_sig = tcx.mk_fn_sig(
11421213
fn_sig.inputs().iter().copied(),
11431214
recovered_ret_ty.unwrap_or_else(|| Ty::new_error(tcx, guar)),
11441215
fn_sig.c_variadic,
11451216
fn_sig.safety,
11461217
fn_sig.abi,
1147-
))
1218+
);
1219+
1220+
late_param_regions_to_bound(tcx, scope, bound_vars, fn_sig)
11481221
}
11491222

11501223
pub fn suggest_impl_trait<'tcx>(

tests/crashes/135845.rs

Lines changed: 0 additions & 6 deletions
This file was deleted.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Regression test for #135845.
2+
3+
use std::marker::PhantomData;
4+
5+
fn b<'a>() -> _ {
6+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121]
7+
let _: PhantomData<&'a ()> = PhantomData;
8+
0
9+
}
10+
11+
fn main() {}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
2+
--> $DIR/recover-infer-ret-ty-issue-135845.rs:5:15
3+
|
4+
LL | fn b<'a>() -> _ {
5+
| ^ not allowed in type signatures
6+
|
7+
help: replace with the correct return type
8+
|
9+
LL - fn b<'a>() -> _ {
10+
LL + fn b<'a>() -> i32 {
11+
|
12+
13+
error: aborting due to 1 previous error
14+
15+
For more information about this error, try `rustc --explain E0121`.

0 commit comments

Comments
 (0)