]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/traits/error_reporting.rs
review comments and fix rebase
[rust.git] / src / librustc / traits / error_reporting.rs
index f511862b37b84e2fb5f297276b250a9b727c66cd..ea29cc0d93f538a51c8f38375e24fde6a6bb4783 100644 (file)
@@ -33,7 +33,7 @@
 use crate::ty::SubtypePredicate;
 use crate::util::nodemap::{FxHashMap, FxHashSet};
 
-use errors::{Applicability, DiagnosticBuilder, pluralise, Style};
+use errors::{Applicability, DiagnosticBuilder, pluralize, Style};
 use std::fmt;
 use syntax::ast;
 use syntax::symbol::{sym, kw};
@@ -771,6 +771,17 @@ pub fn report_selection_error(
                                 )
                             };
 
+                        if self.suggest_add_reference_to_arg(
+                            &obligation,
+                            &mut err,
+                            &trait_ref,
+                            points_at_arg,
+                            have_alt_message,
+                        ) {
+                            self.note_obligation_cause(&mut err, obligation);
+                            err.emit();
+                            return;
+                        }
                         if let Some(ref s) = label {
                             // If it has a custom `#[rustc_on_unimplemented]`
                             // error message, let's display it as the label!
@@ -787,16 +798,6 @@ pub fn report_selection_error(
                         self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err);
                         self.suggest_fn_call(&obligation, &mut err, &trait_ref, points_at_arg);
                         self.suggest_remove_reference(&obligation, &mut err, &trait_ref);
-                        if self.suggest_add_reference_to_arg(
-                            &obligation,
-                            &mut err,
-                            &trait_ref,
-                            points_at_arg,
-                        ) {
-                            self.note_obligation_cause(&mut err, obligation);
-                            err.emit();
-                            return;
-                        }
                         self.suggest_semicolon_removal(&obligation, &mut err, span, &trait_ref);
 
                         // Try to report a help message
@@ -1318,6 +1319,7 @@ fn suggest_add_reference_to_arg(
         err: &mut DiagnosticBuilder<'tcx>,
         trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
         points_at_arg: bool,
+        has_custom_message: bool,
     ) -> bool {
         if !points_at_arg {
             return false;
@@ -1339,31 +1341,37 @@ fn suggest_add_reference_to_arg(
                 param_env,
                 new_trait_ref.to_predicate(),
             );
-            if self.predicate_may_hold(&new_obligation) {
+            if self.predicate_must_hold_modulo_regions(&new_obligation) {
                 if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
                     // We have a very specific type of error, where just borrowing this argument
                     // might solve the problem. In cases like this, the important part is the
                     // original type obligation, not the last one that failed, which is arbitrary.
                     // Because of this, we modify the error to refer to the original obligation and
                     // return early in the caller.
-                    err.message = vec![(
-                        format!(
-                            "the trait bound `{}: {}` is not satisfied",
-                            found,
-                            obligation.parent_trait_ref.skip_binder(),
-                        ),
-                        Style::NoStyle,
-                    )];
+                    let msg = format!(
+                        "the trait bound `{}: {}` is not satisfied",
+                        found,
+                        obligation.parent_trait_ref.skip_binder(),
+                    );
+                    if has_custom_message {
+                        err.note(&msg);
+                    } else {
+                        err.message = vec![(msg, Style::NoStyle)];
+                    }
                     if snippet.starts_with('&') {
                         // This is already a literal borrow and the obligation is failing
                         // somewhere else in the obligation chain. Do not suggest non-sense.
                         return false;
                     }
+                    err.span_label(span, &format!(
+                        "expected an implementor of trait `{}`",
+                        obligation.parent_trait_ref.skip_binder(),
+                    ));
                     err.span_suggestion(
                         span,
                         "consider borrowing here",
                         format!("&{}", snippet),
-                        Applicability::MachineApplicable,
+                        Applicability::MaybeIncorrect,
                     );
                     return true;
                 }