diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-04-23 20:06:33 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-23 20:06:33 +0200 |
| commit | 12858d9a6154e92c6f739c00a80f021515e9b7bb (patch) | |
| tree | ca9688068315f9546f20f7a3a5d27c25584e60c7 | |
| parent | 96acbd8e287b9e03d2255334e0747253dace83b1 (diff) | |
| parent | c8874e24458e7ba88fad7969562a45c951d002a8 (diff) | |
| download | rust-12858d9a6154e92c6f739c00a80f021515e9b7bb.tar.gz rust-12858d9a6154e92c6f739c00a80f021515e9b7bb.zip | |
Rollup merge of #110700 - compiler-errors:fn-ret-fn, r=oli-obk
Don't infer fn return type to return itself Fixes #110687
| -rw-r--r-- | compiler/rustc_hir_analysis/src/collect.rs | 31 | ||||
| -rw-r--r-- | tests/ui/typeck/bad-recursive-type-sig-infer.rs | 11 | ||||
| -rw-r--r-- | tests/ui/typeck/bad-recursive-type-sig-infer.stderr | 15 |
3 files changed, 46 insertions, 11 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 36e294e8aa2..9fe0c07814e 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -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, diff --git a/tests/ui/typeck/bad-recursive-type-sig-infer.rs b/tests/ui/typeck/bad-recursive-type-sig-infer.rs new file mode 100644 index 00000000000..9812d8c3811 --- /dev/null +++ b/tests/ui/typeck/bad-recursive-type-sig-infer.rs @@ -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() {} diff --git a/tests/ui/typeck/bad-recursive-type-sig-infer.stderr b/tests/ui/typeck/bad-recursive-type-sig-infer.stderr new file mode 100644 index 00000000000..e145da5623a --- /dev/null +++ b/tests/ui/typeck/bad-recursive-type-sig-infer.stderr @@ -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`. |
