about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-04-23 20:06:33 +0200
committerGitHub <noreply@github.com>2023-04-23 20:06:33 +0200
commit12858d9a6154e92c6f739c00a80f021515e9b7bb (patch)
treeca9688068315f9546f20f7a3a5d27c25584e60c7
parent96acbd8e287b9e03d2255334e0747253dace83b1 (diff)
parentc8874e24458e7ba88fad7969562a45c951d002a8 (diff)
downloadrust-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.rs31
-rw-r--r--tests/ui/typeck/bad-recursive-type-sig-infer.rs11
-rw-r--r--tests/ui/typeck/bad-recursive-type-sig-infer.stderr15
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`.