]> 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 2e87d6fdd3dc20e787ac0a3a4405b4c5e4272ade..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>,
@@ -804,7 +810,7 @@ fn suggest_add_reference_to_arg(
         } else if let ObligationCauseCode::BindingObligation(_, _)
         | ObligationCauseCode::ItemObligation(_) = &*code
         {
-            try_borrowing(*poly_trait_ref, &never_suggest_borrow[..])
+            try_borrowing(*poly_trait_ref, &never_suggest_borrow)
         } else {
             false
         }
@@ -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(
@@ -1132,7 +1159,7 @@ fn suggest_impl_trait(
             <https://doc.rust-lang.org/book/ch17-02-trait-objects.html\
             #using-trait-objects-that-allow-for-values-of-different-types>";
         let has_dyn = snippet.split_whitespace().next().map_or(false, |s| s == "dyn");
-        let trait_obj = if has_dyn { &snippet[4..] } else { &snippet[..] };
+        let trait_obj = if has_dyn { &snippet[4..] } else { &snippet };
         if only_never_return {
             // No return paths, probably using `panic!()` or similar.
             // Suggest `-> T`, `-> impl Trait`, and if `Trait` is object safe, `-> Box<dyn Trait>`.
@@ -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) => {