Skip to content

Commit 12858d9

Browse files
authored
Rollup merge of rust-lang#110700 - compiler-errors:fn-ret-fn, r=oli-obk
Don't infer fn return type to return itself Fixes rust-lang#110687
2 parents 96acbd8 + c8874e2 commit 12858d9

File tree

3 files changed

+46
-11
lines changed

3 files changed

+46
-11
lines changed

compiler/rustc_hir_analysis/src/collect.rs

+20-11
Original file line numberDiff line numberDiff line change
@@ -1146,24 +1146,22 @@ fn infer_return_ty_for_fn_sig<'tcx>(
11461146

11471147
let mut visitor = HirPlaceholderCollector::default();
11481148
visitor.visit_ty(ty);
1149+
11491150
let mut diag = bad_placeholder(tcx, visitor.0, "return type");
11501151
let ret_ty = fn_sig.output();
1152+
// Don't leak types into signatures unless they're nameable!
1153+
// For example, if a function returns itself, we don't want that
1154+
// recursive function definition to leak out into the fn sig.
1155+
let mut should_recover = false;
1156+
11511157
if let Some(ret_ty) = ret_ty.make_suggestable(tcx, false) {
11521158
diag.span_suggestion(
11531159
ty.span,
11541160
"replace with the correct return type",
11551161
ret_ty,
11561162
Applicability::MachineApplicable,
11571163
);
1158-
} else if matches!(ret_ty.kind(), ty::FnDef(..))
1159-
&& let Some(fn_sig) = ret_ty.fn_sig(tcx).make_suggestable(tcx, false)
1160-
{
1161-
diag.span_suggestion(
1162-
ty.span,
1163-
"replace with the correct return type",
1164-
fn_sig,
1165-
Applicability::MachineApplicable,
1166-
);
1164+
should_recover = true;
11671165
} else if let Some(sugg) = suggest_impl_trait(tcx, ret_ty, ty.span, def_id) {
11681166
diag.span_suggestion(
11691167
ty.span,
@@ -1181,9 +1179,20 @@ fn infer_return_ty_for_fn_sig<'tcx>(
11811179
https://doc.rust-lang.org/book/ch13-01-closures.html",
11821180
);
11831181
}
1184-
diag.emit();
11851182

1186-
ty::Binder::dummy(fn_sig)
1183+
let guar = diag.emit();
1184+
1185+
if should_recover {
1186+
ty::Binder::dummy(fn_sig)
1187+
} else {
1188+
ty::Binder::dummy(tcx.mk_fn_sig(
1189+
fn_sig.inputs().iter().copied(),
1190+
tcx.ty_error(guar),
1191+
fn_sig.c_variadic,
1192+
fn_sig.unsafety,
1193+
fn_sig.abi,
1194+
))
1195+
}
11871196
}
11881197
None => icx.astconv().ty_of_fn(
11891198
hir_id,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
fn a() -> _ {
2+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
3+
&a
4+
}
5+
6+
fn b() -> _ {
7+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
8+
&a
9+
}
10+
11+
fn main() {}
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/bad-recursive-type-sig-infer.rs:1:11
3+
|
4+
LL | fn a() -> _ {
5+
| ^ not allowed in type signatures
6+
7+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
8+
--> $DIR/bad-recursive-type-sig-infer.rs:6:11
9+
|
10+
LL | fn b() -> _ {
11+
| ^ not allowed in type signatures
12+
13+
error: aborting due to 2 previous errors
14+
15+
For more information about this error, try `rustc --explain E0121`.

0 commit comments

Comments
 (0)