Rollup merge of #99526 - compiler-errors:normalize-arg-spans, r=oli-obk

Normalize the arg spans to be within the call span

Makes more sense to point out the arg's span, and not the expression inside the macro
This commit is contained in:
Matthias Krüger 2022-07-21 18:42:06 +02:00 committed by GitHub
commit da18bd18ca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 23 deletions

View file

@ -481,6 +481,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.set_tainted_by_errors();
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
let provided_arg_tys: IndexVec<ProvidedIdx, (Ty<'tcx>, Span)> = provided_args
.iter()
@ -490,7 +501,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.borrow()
.expr_ty_adjusted_opt(*expr)
.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();
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
// innards in parenthesis, for example.
if satisfied
&& let Some(lo) =
provided_args[mismatch_idx.into()].span.find_ancestor_inside(error_span)
&& let Some(hi) = provided_args[(mismatch_idx + tys.len() - 1).into()]
.span
.find_ancestor_inside(error_span)
&& let Some((_, lo)) =
provided_arg_tys.get(ProvidedIdx::from_usize(mismatch_idx))
&& let Some((_, hi)) =
provided_arg_tys.get(ProvidedIdx::from_usize(mismatch_idx + tys.len() - 1))
{
let mut err;
if tys.len() == 1 {
@ -612,7 +622,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// so don't do anything special here.
err = self.report_and_explain_type_error(
TypeTrace::types(
&self.misc(lo),
&self.misc(*lo),
true,
formal_and_expected_inputs[mismatch_idx.into()].1,
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 (_, provided_span) = provided_arg_tys[*provided_idx]
&& let Ok(arg_text) =
source_map.span_to_snippet(provided_span.source_callsite())
source_map.span_to_snippet(provided_span)
{
arg_text
} else {

View file

@ -1,5 +1,5 @@
macro_rules! borrow {
($x:expr) => { &$x } //~ ERROR mismatched types
($x:expr) => { &$x }
}
fn foo(_: String) {}
@ -32,6 +32,7 @@ fn main() {
foo(&mut "aaa".to_owned());
//~^ ERROR mismatched types
foo3(borrow!(0));
//~^ ERROR mismatched types
foo4(&0);
assert_eq!(3i32, &3i32);
//~^ ERROR mismatched types

View file

@ -70,13 +70,10 @@ LL + foo("aaa".to_owned());
|
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));
| ---- ---------- in this macro invocation
| ---- ^^^^^^^^^^ expected `u32`, found `&{integer}`
| |
| arguments to this function are incorrect
|
@ -85,10 +82,9 @@ note: function defined here
|
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
--> $DIR/deref-suggestion.rs:36:5
--> $DIR/deref-suggestion.rs:37:5
|
LL | assert_eq!(3i32, &3i32);
| ^^^^^^^^^^^^^^^^^^^^^^^ 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)
error[E0308]: mismatched types
--> $DIR/deref-suggestion.rs:39:17
--> $DIR/deref-suggestion.rs:40:17
|
LL | let s = S { u };
| ^
@ -105,7 +101,7 @@ LL | let s = S { u };
| help: consider borrowing here: `u: &u`
error[E0308]: mismatched types
--> $DIR/deref-suggestion.rs:41:20
--> $DIR/deref-suggestion.rs:42:20
|
LL | let s = S { u: u };
| ^
@ -114,7 +110,7 @@ LL | let s = S { u: u };
| help: consider borrowing here: `&u`
error[E0308]: mismatched types
--> $DIR/deref-suggestion.rs:44:17
--> $DIR/deref-suggestion.rs:45:17
|
LL | let r = R { i };
| ^ expected `u32`, found `&{integer}`
@ -125,7 +121,7 @@ LL | let r = R { i: *i };
| ++++
error[E0308]: mismatched types
--> $DIR/deref-suggestion.rs:46:20
--> $DIR/deref-suggestion.rs:47:20
|
LL | let r = R { i: i };
| ^ expected `u32`, found `&{integer}`
@ -136,7 +132,7 @@ LL | let r = R { i: *i };
| +
error[E0308]: mismatched types
--> $DIR/deref-suggestion.rs:55:9
--> $DIR/deref-suggestion.rs:56:9
|
LL | b
| ^ expected `i32`, found `&{integer}`
@ -147,7 +143,7 @@ LL | *b
| +
error[E0308]: mismatched types
--> $DIR/deref-suggestion.rs:63:9
--> $DIR/deref-suggestion.rs:64:9
|
LL | b
| ^ expected `i32`, found `&{integer}`
@ -158,7 +154,7 @@ LL | *b
| +
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 {
| _______________-