Skip to content

Commit

Permalink
Rollup merge of rust-lang#110700 - compiler-errors:fn-ret-fn, r=oli-obk
Browse files Browse the repository at this point in the history
Don't infer fn return type to return itself

Fixes rust-lang#110687
  • Loading branch information
compiler-errors committed Apr 22, 2023
2 parents ad3d9bf + c8874e2 commit eb33b1d
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 11 deletions.
31 changes: 20 additions & 11 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1146,24 +1146,22 @@ 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,
"replace with the correct return type",
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,
Expand All @@ -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,
Expand Down
11 changes: 11 additions & 0 deletions tests/ui/typeck/bad-recursive-type-sig-infer.rs
Original file line number Diff line number Diff line change
@@ -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() {}
15 changes: 15 additions & 0 deletions tests/ui/typeck/bad-recursive-type-sig-infer.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit eb33b1d

Please sign in to comment.