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};
)
};
+ 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!
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
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;
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;
}