Normalize the arg spans to be within the call span
This commit is contained in:
parent
14dbfebfa2
commit
cd3204d1a2
3 changed files with 30 additions and 23 deletions
|
@ -481,6 +481,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
self.set_tainted_by_errors();
|
self.set_tainted_by_errors();
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
|
|
||||||
|
// Get the argument span in the context of the call span so that
|
||||||
|
// suggestions and labels are (more) correct when an arg is a
|
||||||
|
// macro invocation.
|
||||||
|
let normalize_span = |span: Span| -> Span {
|
||||||
|
let normalized_span = span.find_ancestor_inside(error_span).unwrap_or(span);
|
||||||
|
// Sometimes macros mess up the spans, so do not normalize the
|
||||||
|
// arg span to equal the error span, because that's less useful
|
||||||
|
// than pointing out the arg expr in the wrong context.
|
||||||
|
if normalized_span.source_equal(error_span) { span } else { normalized_span }
|
||||||
|
};
|
||||||
|
|
||||||
// Precompute the provided types and spans, since that's all we typically need for below
|
// Precompute the provided types and spans, since that's all we typically need for below
|
||||||
let provided_arg_tys: IndexVec<ProvidedIdx, (Ty<'tcx>, Span)> = provided_args
|
let provided_arg_tys: IndexVec<ProvidedIdx, (Ty<'tcx>, Span)> = provided_args
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -490,7 +501,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
.borrow()
|
.borrow()
|
||||||
.expr_ty_adjusted_opt(*expr)
|
.expr_ty_adjusted_opt(*expr)
|
||||||
.unwrap_or_else(|| tcx.ty_error());
|
.unwrap_or_else(|| tcx.ty_error());
|
||||||
(self.resolve_vars_if_possible(ty), expr.span)
|
(self.resolve_vars_if_possible(ty), normalize_span(expr.span))
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let callee_expr = match &call_expr.peel_blocks().kind {
|
let callee_expr = match &call_expr.peel_blocks().kind {
|
||||||
|
@ -600,11 +611,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// Take some care with spans, so we don't suggest wrapping a macro's
|
// Take some care with spans, so we don't suggest wrapping a macro's
|
||||||
// innards in parenthesis, for example.
|
// innards in parenthesis, for example.
|
||||||
if satisfied
|
if satisfied
|
||||||
&& let Some(lo) =
|
&& let Some((_, lo)) =
|
||||||
provided_args[mismatch_idx.into()].span.find_ancestor_inside(error_span)
|
provided_arg_tys.get(ProvidedIdx::from_usize(mismatch_idx))
|
||||||
&& let Some(hi) = provided_args[(mismatch_idx + tys.len() - 1).into()]
|
&& let Some((_, hi)) =
|
||||||
.span
|
provided_arg_tys.get(ProvidedIdx::from_usize(mismatch_idx + tys.len() - 1))
|
||||||
.find_ancestor_inside(error_span)
|
|
||||||
{
|
{
|
||||||
let mut err;
|
let mut err;
|
||||||
if tys.len() == 1 {
|
if tys.len() == 1 {
|
||||||
|
@ -612,7 +622,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// so don't do anything special here.
|
// so don't do anything special here.
|
||||||
err = self.report_and_explain_type_error(
|
err = self.report_and_explain_type_error(
|
||||||
TypeTrace::types(
|
TypeTrace::types(
|
||||||
&self.misc(lo),
|
&self.misc(*lo),
|
||||||
true,
|
true,
|
||||||
formal_and_expected_inputs[mismatch_idx.into()].1,
|
formal_and_expected_inputs[mismatch_idx.into()].1,
|
||||||
provided_arg_tys[mismatch_idx.into()].0,
|
provided_arg_tys[mismatch_idx.into()].0,
|
||||||
|
@ -1052,7 +1062,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let suggestion_text = if let Some(provided_idx) = provided_idx
|
let suggestion_text = if let Some(provided_idx) = provided_idx
|
||||||
&& let (_, provided_span) = provided_arg_tys[*provided_idx]
|
&& let (_, provided_span) = provided_arg_tys[*provided_idx]
|
||||||
&& let Ok(arg_text) =
|
&& let Ok(arg_text) =
|
||||||
source_map.span_to_snippet(provided_span.source_callsite())
|
source_map.span_to_snippet(provided_span)
|
||||||
{
|
{
|
||||||
arg_text
|
arg_text
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
macro_rules! borrow {
|
macro_rules! borrow {
|
||||||
($x:expr) => { &$x } //~ ERROR mismatched types
|
($x:expr) => { &$x }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo(_: String) {}
|
fn foo(_: String) {}
|
||||||
|
@ -32,6 +32,7 @@ fn main() {
|
||||||
foo(&mut "aaa".to_owned());
|
foo(&mut "aaa".to_owned());
|
||||||
//~^ ERROR mismatched types
|
//~^ ERROR mismatched types
|
||||||
foo3(borrow!(0));
|
foo3(borrow!(0));
|
||||||
|
//~^ ERROR mismatched types
|
||||||
foo4(&0);
|
foo4(&0);
|
||||||
assert_eq!(3i32, &3i32);
|
assert_eq!(3i32, &3i32);
|
||||||
//~^ ERROR mismatched types
|
//~^ ERROR mismatched types
|
||||||
|
|
|
@ -70,13 +70,10 @@ LL + foo("aaa".to_owned());
|
||||||
|
|
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/deref-suggestion.rs:2:20
|
--> $DIR/deref-suggestion.rs:34:10
|
||||||
|
|
|
|
||||||
LL | ($x:expr) => { &$x }
|
|
||||||
| ^^^ expected `u32`, found `&{integer}`
|
|
||||||
...
|
|
||||||
LL | foo3(borrow!(0));
|
LL | foo3(borrow!(0));
|
||||||
| ---- ---------- in this macro invocation
|
| ---- ^^^^^^^^^^ expected `u32`, found `&{integer}`
|
||||||
| |
|
| |
|
||||||
| arguments to this function are incorrect
|
| arguments to this function are incorrect
|
||||||
|
|
|
|
||||||
|
@ -85,10 +82,9 @@ note: function defined here
|
||||||
|
|
|
|
||||||
LL | fn foo3(_: u32) {}
|
LL | fn foo3(_: u32) {}
|
||||||
| ^^^^ ------
|
| ^^^^ ------
|
||||||
= note: this error originates in the macro `borrow` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/deref-suggestion.rs:36:5
|
--> $DIR/deref-suggestion.rs:37:5
|
||||||
|
|
|
|
||||||
LL | assert_eq!(3i32, &3i32);
|
LL | assert_eq!(3i32, &3i32);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `&i32`
|
| ^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `&i32`
|
||||||
|
@ -96,7 +92,7 @@ LL | assert_eq!(3i32, &3i32);
|
||||||
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/deref-suggestion.rs:39:17
|
--> $DIR/deref-suggestion.rs:40:17
|
||||||
|
|
|
|
||||||
LL | let s = S { u };
|
LL | let s = S { u };
|
||||||
| ^
|
| ^
|
||||||
|
@ -105,7 +101,7 @@ LL | let s = S { u };
|
||||||
| help: consider borrowing here: `u: &u`
|
| help: consider borrowing here: `u: &u`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/deref-suggestion.rs:41:20
|
--> $DIR/deref-suggestion.rs:42:20
|
||||||
|
|
|
|
||||||
LL | let s = S { u: u };
|
LL | let s = S { u: u };
|
||||||
| ^
|
| ^
|
||||||
|
@ -114,7 +110,7 @@ LL | let s = S { u: u };
|
||||||
| help: consider borrowing here: `&u`
|
| help: consider borrowing here: `&u`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/deref-suggestion.rs:44:17
|
--> $DIR/deref-suggestion.rs:45:17
|
||||||
|
|
|
|
||||||
LL | let r = R { i };
|
LL | let r = R { i };
|
||||||
| ^ expected `u32`, found `&{integer}`
|
| ^ expected `u32`, found `&{integer}`
|
||||||
|
@ -125,7 +121,7 @@ LL | let r = R { i: *i };
|
||||||
| ++++
|
| ++++
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/deref-suggestion.rs:46:20
|
--> $DIR/deref-suggestion.rs:47:20
|
||||||
|
|
|
|
||||||
LL | let r = R { i: i };
|
LL | let r = R { i: i };
|
||||||
| ^ expected `u32`, found `&{integer}`
|
| ^ expected `u32`, found `&{integer}`
|
||||||
|
@ -136,7 +132,7 @@ LL | let r = R { i: *i };
|
||||||
| +
|
| +
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/deref-suggestion.rs:55:9
|
--> $DIR/deref-suggestion.rs:56:9
|
||||||
|
|
|
|
||||||
LL | b
|
LL | b
|
||||||
| ^ expected `i32`, found `&{integer}`
|
| ^ expected `i32`, found `&{integer}`
|
||||||
|
@ -147,7 +143,7 @@ LL | *b
|
||||||
| +
|
| +
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/deref-suggestion.rs:63:9
|
--> $DIR/deref-suggestion.rs:64:9
|
||||||
|
|
|
|
||||||
LL | b
|
LL | b
|
||||||
| ^ expected `i32`, found `&{integer}`
|
| ^ expected `i32`, found `&{integer}`
|
||||||
|
@ -158,7 +154,7 @@ LL | *b
|
||||||
| +
|
| +
|
||||||
|
|
||||||
error[E0308]: `if` and `else` have incompatible types
|
error[E0308]: `if` and `else` have incompatible types
|
||||||
--> $DIR/deref-suggestion.rs:68:12
|
--> $DIR/deref-suggestion.rs:69:12
|
||||||
|
|
|
|
||||||
LL | let val = if true {
|
LL | let val = if true {
|
||||||
| _______________-
|
| _______________-
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue