Skip to content

Commit e73c148

Browse files
committed
Suggest swapping the equality in user-written code
Signed-off-by: xizheyin <[email protected]>
1 parent b0812d9 commit e73c148

File tree

4 files changed

+27
-19
lines changed

4 files changed

+27
-19
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3539,15 +3539,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
35393539
.must_apply_modulo_regions()
35403540
{
35413541
let sm = self.tcx.sess.source_map();
3542-
if let Ok(rhs_snippet) = sm.span_to_snippet(rhs_expr.span)
3543-
&& let Ok(lhs_snippet) = sm.span_to_snippet(lhs_expr.span)
3542+
// If the span of rhs_expr or lhs_expr is in an external macro,
3543+
// we should find the user-written code span. See issue #139050
3544+
if let Some(rhs_span) = rhs_expr.span.find_ancestor_not_from_extern_macro(sm)
3545+
&& let Some(lhs_span) = lhs_expr.span.find_ancestor_not_from_extern_macro(sm)
3546+
&& let Ok(rhs_snippet) = sm.span_to_snippet(rhs_span)
3547+
&& let Ok(lhs_snippet) = sm.span_to_snippet(lhs_span)
35443548
{
35453549
err.note(format!("`{rhs_ty}` implements `PartialEq<{lhs_ty}>`"));
3546-
err.multipart_suggestion(
3547-
"consider swapping the equality",
3548-
vec![(lhs_expr.span, rhs_snippet), (rhs_expr.span, lhs_snippet)],
3549-
Applicability::MaybeIncorrect,
3550-
);
3550+
if rhs_span != lhs_span {
3551+
err.multipart_suggestion(
3552+
"consider swapping the equality",
3553+
vec![(lhs_span, rhs_snippet), (rhs_span, lhs_snippet)],
3554+
Applicability::MaybeIncorrect,
3555+
);
3556+
} else {
3557+
// rhs_span and lhs_span are the same because it from extern macro.
3558+
// we should suggest to swap two arguments of the equality
3559+
err.span_help(rhs_span, "consider swapping two arguments of the equality");
3560+
}
35513561
}
35523562
}
35533563
}

tests/ui/typeck/auxiliary/extern-macro-issue-139050.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#[macro_export]
2-
macro_rules! eq {
2+
macro_rules! eq {
33
(assert $a:expr, $b:expr) => {
44
match (&$a, &$b) {
55
(left_val, right_val) => {
@@ -12,4 +12,4 @@ macro_rules! eq {
1212
}
1313
}
1414
};
15-
}
15+
}

tests/ui/typeck/sugg-swap-equality-in-macro-issue-139050.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ extern crate ext;
88

99
use std::fmt::Debug;
1010

11-
macro_rules! eq_local {
11+
macro_rules! eq_local {
1212
(assert $a:expr, $b:expr) => {
1313
match (&$a, &$b) {
1414
(left_val, right_val) => {
@@ -28,7 +28,6 @@ where
2828
Item: Eq + Debug, //~ ERROR cannot find type `Item` in this scope [E0412]
2929
{
3030
ext::eq!(assert iter.next(), Some(value)); //~ ERROR mismatched types [E0308]
31-
eq_local!(assert iter.next(), Some(value));
31+
eq_local!(assert iter.next(), Some(value));
3232
}
3333
fn main() {}
34-

tests/ui/typeck/sugg-swap-equality-in-macro-issue-139050.stderr

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,20 @@ LL | ext::eq!(assert iter.next(), Some(value));
1313
= note: expected enum `Option<_>`
1414
found enum `Option<&_>`
1515
= note: `Option<&<I as Iterator>::Item>` implements `PartialEq<Option<<I as Iterator>::Item>>`
16-
= note: this error originates in the macro `ext::eq` (in Nightly builds, run with -Z macro-backtrace for more info)
17-
help: consider swapping the equality
18-
--> $DIR/auxiliary/extern-macro-issue-139050.rs:6:22
19-
|
20-
LL - if !(*left_val == *right_val) {
21-
LL + if !(*right_val == *left_val) {
16+
help: consider swapping two arguments of the equality
17+
--> $DIR/sugg-swap-equality-in-macro-issue-139050.rs:30:5
2218
|
19+
LL | ext::eq!(assert iter.next(), Some(value));
20+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
21+
= note: this error originates in the macro `ext::eq` (in Nightly builds, run with -Z macro-backtrace for more info)
2322

2423
error[E0308]: mismatched types
2524
--> $DIR/sugg-swap-equality-in-macro-issue-139050.rs:15:35
2625
|
2726
LL | if !(*left_val == *right_val) {
2827
| ^^^^^^^^^^ expected `Option<<I as Iterator>::Item>`, found `Option<&<I as Iterator>::Item>`
2928
...
30-
LL | eq_local!(assert iter.next(), Some(value));
29+
LL | eq_local!(assert iter.next(), Some(value));
3130
| ------------------------------------------ in this macro invocation
3231
|
3332
= note: expected enum `Option<_>`

0 commit comments

Comments
 (0)