Skip to content

Commit da18bd1

Browse files
authored
Rollup merge of rust-lang#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
2 parents 84a7b23 + cd3204d commit da18bd1

File tree

3 files changed

+30
-23
lines changed

3 files changed

+30
-23
lines changed

compiler/rustc_typeck/src/check/fn_ctxt/checks.rs

+18-8
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
481481
self.set_tainted_by_errors();
482482
let tcx = self.tcx;
483483

484+
// Get the argument span in the context of the call span so that
485+
// suggestions and labels are (more) correct when an arg is a
486+
// macro invocation.
487+
let normalize_span = |span: Span| -> Span {
488+
let normalized_span = span.find_ancestor_inside(error_span).unwrap_or(span);
489+
// Sometimes macros mess up the spans, so do not normalize the
490+
// arg span to equal the error span, because that's less useful
491+
// than pointing out the arg expr in the wrong context.
492+
if normalized_span.source_equal(error_span) { span } else { normalized_span }
493+
};
494+
484495
// Precompute the provided types and spans, since that's all we typically need for below
485496
let provided_arg_tys: IndexVec<ProvidedIdx, (Ty<'tcx>, Span)> = provided_args
486497
.iter()
@@ -490,7 +501,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
490501
.borrow()
491502
.expr_ty_adjusted_opt(*expr)
492503
.unwrap_or_else(|| tcx.ty_error());
493-
(self.resolve_vars_if_possible(ty), expr.span)
504+
(self.resolve_vars_if_possible(ty), normalize_span(expr.span))
494505
})
495506
.collect();
496507
let callee_expr = match &call_expr.peel_blocks().kind {
@@ -600,19 +611,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
600611
// Take some care with spans, so we don't suggest wrapping a macro's
601612
// innards in parenthesis, for example.
602613
if satisfied
603-
&& let Some(lo) =
604-
provided_args[mismatch_idx.into()].span.find_ancestor_inside(error_span)
605-
&& let Some(hi) = provided_args[(mismatch_idx + tys.len() - 1).into()]
606-
.span
607-
.find_ancestor_inside(error_span)
614+
&& let Some((_, lo)) =
615+
provided_arg_tys.get(ProvidedIdx::from_usize(mismatch_idx))
616+
&& let Some((_, hi)) =
617+
provided_arg_tys.get(ProvidedIdx::from_usize(mismatch_idx + tys.len() - 1))
608618
{
609619
let mut err;
610620
if tys.len() == 1 {
611621
// A tuple wrap suggestion actually occurs within,
612622
// so don't do anything special here.
613623
err = self.report_and_explain_type_error(
614624
TypeTrace::types(
615-
&self.misc(lo),
625+
&self.misc(*lo),
616626
true,
617627
formal_and_expected_inputs[mismatch_idx.into()].1,
618628
provided_arg_tys[mismatch_idx.into()].0,
@@ -1052,7 +1062,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10521062
let suggestion_text = if let Some(provided_idx) = provided_idx
10531063
&& let (_, provided_span) = provided_arg_tys[*provided_idx]
10541064
&& let Ok(arg_text) =
1055-
source_map.span_to_snippet(provided_span.source_callsite())
1065+
source_map.span_to_snippet(provided_span)
10561066
{
10571067
arg_text
10581068
} else {

src/test/ui/inference/deref-suggestion.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
macro_rules! borrow {
2-
($x:expr) => { &$x } //~ ERROR mismatched types
2+
($x:expr) => { &$x }
33
}
44

55
fn foo(_: String) {}
@@ -32,6 +32,7 @@ fn main() {
3232
foo(&mut "aaa".to_owned());
3333
//~^ ERROR mismatched types
3434
foo3(borrow!(0));
35+
//~^ ERROR mismatched types
3536
foo4(&0);
3637
assert_eq!(3i32, &3i32);
3738
//~^ ERROR mismatched types

src/test/ui/inference/deref-suggestion.stderr

+10-14
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,10 @@ LL + foo("aaa".to_owned());
7070
|
7171

7272
error[E0308]: mismatched types
73-
--> $DIR/deref-suggestion.rs:2:20
73+
--> $DIR/deref-suggestion.rs:34:10
7474
|
75-
LL | ($x:expr) => { &$x }
76-
| ^^^ expected `u32`, found `&{integer}`
77-
...
7875
LL | foo3(borrow!(0));
79-
| ---- ---------- in this macro invocation
76+
| ---- ^^^^^^^^^^ expected `u32`, found `&{integer}`
8077
| |
8178
| arguments to this function are incorrect
8279
|
@@ -85,18 +82,17 @@ note: function defined here
8582
|
8683
LL | fn foo3(_: u32) {}
8784
| ^^^^ ------
88-
= note: this error originates in the macro `borrow` (in Nightly builds, run with -Z macro-backtrace for more info)
8985

9086
error[E0308]: mismatched types
91-
--> $DIR/deref-suggestion.rs:36:5
87+
--> $DIR/deref-suggestion.rs:37:5
9288
|
9389
LL | assert_eq!(3i32, &3i32);
9490
| ^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `&i32`
9591
|
9692
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
9793

9894
error[E0308]: mismatched types
99-
--> $DIR/deref-suggestion.rs:39:17
95+
--> $DIR/deref-suggestion.rs:40:17
10096
|
10197
LL | let s = S { u };
10298
| ^
@@ -105,7 +101,7 @@ LL | let s = S { u };
105101
| help: consider borrowing here: `u: &u`
106102

107103
error[E0308]: mismatched types
108-
--> $DIR/deref-suggestion.rs:41:20
104+
--> $DIR/deref-suggestion.rs:42:20
109105
|
110106
LL | let s = S { u: u };
111107
| ^
@@ -114,7 +110,7 @@ LL | let s = S { u: u };
114110
| help: consider borrowing here: `&u`
115111

116112
error[E0308]: mismatched types
117-
--> $DIR/deref-suggestion.rs:44:17
113+
--> $DIR/deref-suggestion.rs:45:17
118114
|
119115
LL | let r = R { i };
120116
| ^ expected `u32`, found `&{integer}`
@@ -125,7 +121,7 @@ LL | let r = R { i: *i };
125121
| ++++
126122

127123
error[E0308]: mismatched types
128-
--> $DIR/deref-suggestion.rs:46:20
124+
--> $DIR/deref-suggestion.rs:47:20
129125
|
130126
LL | let r = R { i: i };
131127
| ^ expected `u32`, found `&{integer}`
@@ -136,7 +132,7 @@ LL | let r = R { i: *i };
136132
| +
137133

138134
error[E0308]: mismatched types
139-
--> $DIR/deref-suggestion.rs:55:9
135+
--> $DIR/deref-suggestion.rs:56:9
140136
|
141137
LL | b
142138
| ^ expected `i32`, found `&{integer}`
@@ -147,7 +143,7 @@ LL | *b
147143
| +
148144

149145
error[E0308]: mismatched types
150-
--> $DIR/deref-suggestion.rs:63:9
146+
--> $DIR/deref-suggestion.rs:64:9
151147
|
152148
LL | b
153149
| ^ expected `i32`, found `&{integer}`
@@ -158,7 +154,7 @@ LL | *b
158154
| +
159155

160156
error[E0308]: `if` and `else` have incompatible types
161-
--> $DIR/deref-suggestion.rs:68:12
157+
--> $DIR/deref-suggestion.rs:69:12
162158
|
163159
LL | let val = if true {
164160
| _______________-

0 commit comments

Comments
 (0)