Don't infer fn return type to return itself

This commit is contained in:
Michael Goulet 2023-04-22 19:29:30 +00:00
parent 4396ceca05
commit c8874e2445
3 changed files with 46 additions and 11 deletions

View File

@ -1146,8 +1146,14 @@ fn infer_return_ty_for_fn_sig<'tcx>(
let mut visitor = HirPlaceholderCollector::default();
visitor.visit_ty(ty);
let mut diag = bad_placeholder(tcx, visitor.0, "return type");
let ret_ty = fn_sig.output();
// Don't leak types into signatures unless they're nameable!
// For example, if a function returns itself, we don't want that
// recursive function definition to leak out into the fn sig.
let mut should_recover = false;
if let Some(ret_ty) = ret_ty.make_suggestable(tcx, false) {
diag.span_suggestion(
ty.span,
@ -1155,15 +1161,7 @@ fn infer_return_ty_for_fn_sig<'tcx>(
ret_ty,
Applicability::MachineApplicable,
);
} else if matches!(ret_ty.kind(), ty::FnDef(..))
&& let Some(fn_sig) = ret_ty.fn_sig(tcx).make_suggestable(tcx, false)
{
diag.span_suggestion(
ty.span,
"replace with the correct return type",
fn_sig,
Applicability::MachineApplicable,
);
should_recover = true;
} else if let Some(sugg) = suggest_impl_trait(tcx, ret_ty, ty.span, def_id) {
diag.span_suggestion(
ty.span,
@ -1181,9 +1179,20 @@ fn infer_return_ty_for_fn_sig<'tcx>(
https://doc.rust-lang.org/book/ch13-01-closures.html",
);
}
diag.emit();
ty::Binder::dummy(fn_sig)
let guar = diag.emit();
if should_recover {
ty::Binder::dummy(fn_sig)
} else {
ty::Binder::dummy(tcx.mk_fn_sig(
fn_sig.inputs().iter().copied(),
tcx.ty_error(guar),
fn_sig.c_variadic,
fn_sig.unsafety,
fn_sig.abi,
))
}
}
None => icx.astconv().ty_of_fn(
hir_id,

View File

@ -0,0 +1,11 @@
fn a() -> _ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
&a
}
fn b() -> _ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
&a
}
fn main() {}

View File

@ -0,0 +1,15 @@
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/bad-recursive-type-sig-infer.rs:1:11
|
LL | fn a() -> _ {
| ^ not allowed in type signatures
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
--> $DIR/bad-recursive-type-sig-infer.rs:6:11
|
LL | fn b() -> _ {
| ^ not allowed in type signatures
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0121`.