about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-04-24 20:11:51 -0700
committerMichael Goulet <michael@errs.io>2022-04-26 18:50:46 -0700
commitae42f22ba055337f802b02b8c07e999bd52ec01d (patch)
tree6e99217688add43dbc75c9e1833de129cd6c24f6
parenta7197189cd0e3a86d1b661d1dceb8bdff021d0b8 (diff)
downloadrust-ae42f22ba055337f802b02b8c07e999bd52ec01d.tar.gz
rust-ae42f22ba055337f802b02b8c07e999bd52ec01d.zip
make `fn() -> _ {}` suggestion MachineApplicable
-rw-r--r--compiler/rustc_typeck/src/collect.rs37
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-77179.stderr5
2 files changed, 20 insertions, 22 deletions
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index be77bdb0bf5..37bcbf37426 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -41,7 +41,7 @@ use rustc_middle::ty::subst::InternalSubsts;
 use rustc_middle::ty::util::Discr;
 use rustc_middle::ty::util::IntTypeExt;
 use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, Ty, TyCtxt};
-use rustc_middle::ty::{ReprOptions, ToPredicate, TypeFoldable};
+use rustc_middle::ty::{ReprOptions, ToPredicate};
 use rustc_session::lint;
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
@@ -2004,28 +2004,29 @@ fn infer_return_ty_for_fn_sig<'tcx>(
             visitor.visit_ty(ty);
             let mut diag = bad_placeholder(tcx, visitor.0, "return type");
             let ret_ty = fn_sig.skip_binder().output();
-            if !ret_ty.references_error() {
-                if !ret_ty.is_closure() {
-                    let ret_ty_str = match ret_ty.kind() {
-                        // Suggest a function pointer return type instead of a unique function definition
-                        // (e.g. `fn() -> i32` instead of `fn() -> i32 { f }`, the latter of which is invalid
-                        // syntax)
-                        ty::FnDef(..) => ret_ty.fn_sig(tcx).to_string(),
-                        _ => ret_ty.to_string(),
-                    };
+            if ret_ty.is_suggestable() {
+                diag.span_suggestion(
+                    ty.span,
+                    "replace with the correct return type",
+                    ret_ty.to_string(),
+                    Applicability::MachineApplicable,
+                );
+            } else if matches!(ret_ty.kind(), ty::FnDef(..)) {
+                let fn_sig = ret_ty.fn_sig(tcx);
+                if fn_sig.skip_binder().inputs_and_output.iter().all(|t| t.is_suggestable()) {
                     diag.span_suggestion(
                         ty.span,
                         "replace with the correct return type",
-                        ret_ty_str,
-                        Applicability::MaybeIncorrect,
+                        fn_sig.to_string(),
+                        Applicability::MachineApplicable,
                     );
-                } else {
-                    // We're dealing with a closure, so we should suggest using `impl Fn` or trait bounds
-                    // to prevent the user from getting a papercut while trying to use the unique closure
-                    // syntax (e.g. `[closure@src/lib.rs:2:5: 2:9]`).
-                    diag.help("consider using an `Fn`, `FnMut`, or `FnOnce` trait bound");
-                    diag.note("for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html");
                 }
+            } else if ret_ty.is_closure() {
+                // We're dealing with a closure, so we should suggest using `impl Fn` or trait bounds
+                // to prevent the user from getting a papercut while trying to use the unique closure
+                // syntax (e.g. `[closure@src/lib.rs:2:5: 2:9]`).
+                diag.help("consider using an `Fn`, `FnMut`, or `FnOnce` trait bound");
+                diag.note("for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html");
             }
             diag.emit();
 
diff --git a/src/test/ui/type-alias-impl-trait/issue-77179.stderr b/src/test/ui/type-alias-impl-trait/issue-77179.stderr
index 053546e4b92..f9a1eaca384 100644
--- a/src/test/ui/type-alias-impl-trait/issue-77179.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-77179.stderr
@@ -2,10 +2,7 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
   --> $DIR/issue-77179.rs:7:22
    |
 LL | fn test() -> Pointer<_> {
-   |              --------^-
-   |              |       |
-   |              |       not allowed in type signatures
-   |              help: replace with the correct return type: `Pointer<i32>`
+   |                      ^ not allowed in type signatures
 
 error: aborting due to previous error