]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
Reduce verbosity for `?` on non-`Try` expressions
[rust.git] / compiler / rustc_trait_selection / src / traits / error_reporting / suggestions.rs
index d0b61b2430862ee21a24f3704b40ff9672e8c60f..9893e5143fca675c92cbf3f7367cefab708d2afb 100644 (file)
@@ -21,7 +21,7 @@
 use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node};
 use rustc_middle::ty::{
     self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree,
-    Infer, InferTy, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
+    Infer, InferTy, ToPredicate, Ty, TyCtxt, TypeFoldable,
 };
 use rustc_middle::ty::{TypeAndMut, TypeckResults};
 use rustc_session::Limit;
@@ -89,6 +89,12 @@ fn suggest_remove_reference(
         trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
     );
 
+    fn suggest_remove_await(
+        &self,
+        obligation: &PredicateObligation<'tcx>,
+        err: &mut DiagnosticBuilder<'_>,
+    );
+
     fn suggest_change_mut(
         &self,
         obligation: &PredicateObligation<'tcx>,
@@ -873,6 +879,27 @@ fn suggest_remove_reference(
         }
     }
 
+    fn suggest_remove_await(
+        &self,
+        obligation: &PredicateObligation<'tcx>,
+        err: &mut DiagnosticBuilder<'_>,
+    ) {
+        let span = obligation.cause.span;
+
+        if let ObligationCauseCode::AwaitableExpr = obligation.cause.code {
+            // FIXME: use `obligation.predicate.kind()...trait_ref.self_ty()` to see if we have `()`
+            // and if not maybe suggest doing something else? If we kept the expression around we
+            // could also check if it is an fn call (very likely) and suggest changing *that*, if
+            // it is from the local crate.
+            err.span_suggestion_verbose(
+                span,
+                "do not `.await` the expression",
+                String::new(),
+                Applicability::MachineApplicable,
+            );
+        }
+    }
+
     /// Check if the trait bound is implemented for a different mutability and note it in the
     /// final error.
     fn suggest_change_mut(
@@ -1935,6 +1962,9 @@ fn note_obligation_cause_code<T>(
             | ObligationCauseCode::ReturnType
             | ObligationCauseCode::ReturnValue(_)
             | ObligationCauseCode::BlockTailExpression(_)
+            | ObligationCauseCode::AwaitableExpr
+            | ObligationCauseCode::ForLoopIterator
+            | ObligationCauseCode::QuestionMark
             | ObligationCauseCode::LetElse => {}
             ObligationCauseCode::SliceOrArrayElem => {
                 err.note("slice and array elements must have `Sized` type");
@@ -2186,6 +2216,16 @@ fn note_obligation_cause_code<T>(
                             seen_requirements,
                         )
                     });
+                } else {
+                    ensure_sufficient_stack(|| {
+                        self.note_obligation_cause_code(
+                            err,
+                            &parent_predicate,
+                            &cause_code.peel_derives(),
+                            obligated_types,
+                            seen_requirements,
+                        )
+                    });
                 }
             }
             ObligationCauseCode::ImplDerivedObligation(ref data) => {