Fix ICE in borrowck when recovering fn_sig for -> _
This commit is contained in:
parent
47611e1604
commit
7d7b381660
4 changed files with 80 additions and 8 deletions
|
|
@ -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>(
|
||||
|
|
|
|||
|
|
@ -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