about summary refs log tree commit diff
path: root/compiler/rustc_hir_analysis/src/check/mod.rs
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-06-13 20:41:15 +0000
committerMichael Goulet <michael@errs.io>2023-06-13 20:41:15 +0000
commitdbee24d94992df4c1888ebc2095d251fac22c05f (patch)
tree0f9caa7ad214715c9137a8c64e76ec61ca97b17a /compiler/rustc_hir_analysis/src/check/mod.rs
parent2ca8d358e55bc56755b597ea96b557232ef8bc86 (diff)
downloadrust-dbee24d94992df4c1888ebc2095d251fac22c05f.tar.gz
rust-dbee24d94992df4c1888ebc2095d251fac22c05f.zip
Suggest correct signature on missing fn returning RPITIT/AFIT
Diffstat (limited to 'compiler/rustc_hir_analysis/src/check/mod.rs')
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs31
1 files changed, 29 insertions, 2 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index c9e74896ac0..d8e9e5a0152 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -403,7 +403,32 @@ fn fn_sig_suggestion<'tcx>(
         .flatten()
         .collect::<Vec<String>>()
         .join(", ");
-    let output = sig.output();
+    let mut output = sig.output();
+
+    let asyncness = if tcx.asyncness(assoc.def_id).is_async() {
+        output = if let ty::Alias(_, alias_ty) = *output.kind() {
+            tcx.explicit_item_bounds(alias_ty.def_id)
+                .subst_iter_copied(tcx, alias_ty.substs)
+                .find_map(|(bound, _)| {
+                    bound.to_opt_poly_projection_pred()?.no_bound_vars()?.term.ty()
+                })
+                .unwrap_or_else(|| {
+                    span_bug!(
+                        ident.span,
+                        "expected async fn to have `impl Future` output, but it returns {output}"
+                    )
+                })
+        } else {
+            span_bug!(
+                ident.span,
+                "expected async fn to have `impl Future` output, but it returns {output}"
+            )
+        };
+        "async "
+    } else {
+        ""
+    };
+
     let output = if !output.is_unit() { format!(" -> {output}") } else { String::new() };
 
     let unsafety = sig.unsafety.prefix_str();
@@ -414,7 +439,9 @@ fn fn_sig_suggestion<'tcx>(
     // lifetimes between the `impl` and the `trait`, but this should be good enough to
     // fill in a significant portion of the missing code, and other subsequent
     // suggestions can help the user fix the code.
-    format!("{unsafety}fn {ident}{generics}({args}){output}{where_clauses} {{ todo!() }}")
+    format!(
+        "{unsafety}{asyncness}fn {ident}{generics}({args}){output}{where_clauses} {{ todo!() }}"
+    )
 }
 
 pub fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> {