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};
&mut err,
&trait_ref,
points_at_arg,
+ have_alt_message,
) {
self.note_obligation_cause(&mut err, obligation);
err.emit();
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.
span,
"consider borrowing here",
format!("&{}", snippet),
- Applicability::MachineApplicable,
+ Applicability::MaybeIncorrect,
);
return true;
}