use diagnostic-mutating style for note_type_err
too
that is much cleaner than the `type_err!` style I used earlier.
This commit is contained in:
parent
1e4f6d5683
commit
93a96835b0
@ -521,25 +521,25 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn report_and_explain_type_error_with_code(&self,
|
||||
origin: TypeOrigin,
|
||||
values: Option<ValuePairs<'tcx>>,
|
||||
terr: &TypeError<'tcx>,
|
||||
message: &str,
|
||||
code: &str)
|
||||
-> DiagnosticBuilder<'tcx>
|
||||
pub fn note_type_err(&self,
|
||||
diag: &mut DiagnosticBuilder<'tcx>,
|
||||
origin: TypeOrigin,
|
||||
values: Option<ValuePairs<'tcx>>,
|
||||
terr: &TypeError<'tcx>)
|
||||
{
|
||||
let expected_found = match values {
|
||||
None => None,
|
||||
Some(values) => match self.values_str(&values) {
|
||||
Some((expected, found)) => Some((expected, found)),
|
||||
None => return self.tcx.sess.diagnostic().struct_dummy() /* derived error */
|
||||
None => {
|
||||
// Derived error. Cancel the emitter.
|
||||
self.tcx.sess.diagnostic().cancel(diag);
|
||||
return
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let span = origin.span();
|
||||
let mut err = self.tcx.sess.struct_span_err_with_code(
|
||||
span, message, code);
|
||||
|
||||
let mut is_simple_error = false;
|
||||
|
||||
@ -551,21 +551,19 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
};
|
||||
|
||||
if !is_simple_error || check_old_school() {
|
||||
err.note_expected_found(&"type", &expected, &found);
|
||||
diag.note_expected_found(&"type", &expected, &found);
|
||||
}
|
||||
}
|
||||
|
||||
if !is_simple_error && check_old_school() {
|
||||
err.span_note(span, &format!("{}", terr));
|
||||
diag.span_note(span, &format!("{}", terr));
|
||||
} else {
|
||||
err.span_label(span, &terr);
|
||||
diag.span_label(span, &terr);
|
||||
}
|
||||
|
||||
self.note_error_origin(&mut err, &origin);
|
||||
self.check_and_note_conflicting_crates(&mut err, terr, span);
|
||||
self.tcx.note_and_explain_type_err(&mut err, terr, span);
|
||||
|
||||
err
|
||||
self.note_error_origin(diag, &origin);
|
||||
self.check_and_note_conflicting_crates(diag, terr, span);
|
||||
self.tcx.note_and_explain_type_err(diag, terr, span);
|
||||
}
|
||||
|
||||
pub fn report_and_explain_type_error(&self,
|
||||
@ -574,8 +572,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
-> DiagnosticBuilder<'tcx>
|
||||
{
|
||||
// FIXME: do we want to use a different error code for each origin?
|
||||
let failure_str = trace.origin.as_failure_str();
|
||||
type_err!(self, trace.origin, Some(trace.values), terr, E0308, "{}", failure_str)
|
||||
let mut diag = struct_span_err!(
|
||||
self.tcx.sess, trace.origin.span(), E0308,
|
||||
"{}", trace.origin.as_failure_str()
|
||||
);
|
||||
self.note_type_err(&mut diag, trace.origin, Some(trace.values), terr);
|
||||
diag
|
||||
}
|
||||
|
||||
/// Returns a string of the form "expected `{}`, found `{}`".
|
||||
|
@ -59,16 +59,3 @@ macro_rules! span_bug {
|
||||
$crate::session::span_bug_fmt(file!(), line!(), $span, format_args!($($message)*))
|
||||
})
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! type_err {
|
||||
($infcx:expr, $origin: expr, $values: expr, $terr: expr, $code:ident, $($message:tt)*) => ({
|
||||
__diagnostic_used!($code);
|
||||
$infcx.report_and_explain_type_error_with_code(
|
||||
$origin,
|
||||
$values,
|
||||
&$terr,
|
||||
&format!($($message)*),
|
||||
stringify!($code))
|
||||
})
|
||||
}
|
||||
|
@ -157,14 +157,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
let mut diag = type_err!(
|
||||
self,
|
||||
origin,
|
||||
values,
|
||||
err,
|
||||
E0271,
|
||||
"type mismatch resolving `{}`",
|
||||
predicate);
|
||||
let mut diag = struct_span_err!(
|
||||
self.tcx.sess, origin.span(), E0271,
|
||||
"type mismatch resolving `{}`", predicate
|
||||
);
|
||||
self.note_type_err(&mut diag, origin, values, err);
|
||||
self.note_obligation_cause(&mut diag, obligation);
|
||||
diag.emit();
|
||||
});
|
||||
|
@ -325,13 +325,19 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
debug!("sub_types failed: impl ty {:?}, trait ty {:?}",
|
||||
impl_fty,
|
||||
trait_fty);
|
||||
let values = Some(infer::ValuePairs::Types(ExpectedFound {
|
||||
expected: trait_fty,
|
||||
found: impl_fty
|
||||
}));
|
||||
type_err!(infcx, origin, values, terr, E0053,
|
||||
"method `{}` has an incompatible type for trait",
|
||||
trait_m.name).emit();
|
||||
|
||||
let mut diag = struct_span_err!(
|
||||
tcx.sess, origin.span(), E0053,
|
||||
"method `{}` has an incompatible type for trait", trait_m.name
|
||||
);
|
||||
infcx.note_type_err(
|
||||
&mut diag, origin,
|
||||
Some(infer::ValuePairs::Types(ExpectedFound {
|
||||
expected: trait_fty,
|
||||
found: impl_fty
|
||||
})), &terr
|
||||
);
|
||||
diag.emit();
|
||||
return
|
||||
}
|
||||
|
||||
@ -476,13 +482,19 @@ pub fn compare_const_impl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
debug!("checking associated const for compatibility: impl ty {:?}, trait ty {:?}",
|
||||
impl_ty,
|
||||
trait_ty);
|
||||
let values = Some(infer::ValuePairs::Types(ExpectedFound {
|
||||
expected: trait_ty,
|
||||
found: impl_ty
|
||||
}));
|
||||
type_err!(infcx, origin, values, terr, E0326,
|
||||
"implemented const `{}` has an incompatible type for \
|
||||
trait", trait_c.name).emit();
|
||||
let mut diag = struct_span_err!(
|
||||
tcx.sess, origin.span(), E0326,
|
||||
"implemented const `{}` has an incompatible type for trait",
|
||||
trait_c.name
|
||||
);
|
||||
infcx.note_type_err(
|
||||
&mut diag, origin,
|
||||
Some(infer::ValuePairs::Types(ExpectedFound {
|
||||
expected: trait_ty,
|
||||
found: impl_ty
|
||||
})), &terr
|
||||
);
|
||||
diag.emit();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user