about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-08-04 21:31:55 +0200
committerGitHub <noreply@github.com>2023-08-04 21:31:55 +0200
commit5054e41b642fb6da0094034e56ae65d98e8bb884 (patch)
tree589f4a1b23b3ddd57f448203494035489c6c09e0
parent03181e0547c1e15a2c0431337b2d5ee00fd0374c (diff)
parentcde8f06503d06d254aa4191438588ba9b2a36b77 (diff)
downloadrust-5054e41b642fb6da0094034e56ae65d98e8bb884.tar.gz
rust-5054e41b642fb6da0094034e56ae65d98e8bb884.zip
Rollup merge of #113945 - chenyukang:yukang-fix-113447-slice-2, r=cjgillot
Fix wrong span for trait selection failure error reporting

Fixes #113447
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs8
-rw-r--r--tests/ui/dst/issue-113447.fixed25
-rw-r--r--tests/ui/dst/issue-113447.rs25
-rw-r--r--tests/ui/dst/issue-113447.stderr25
5 files changed, 88 insertions, 3 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index eae13eb6302..4d85e2b6089 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -2987,6 +2987,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         unsatisfied_const: bool,
     ) {
         let body_def_id = obligation.cause.body_id;
+        let span = if let ObligationCauseCode::BinOp { rhs_span: Some(rhs_span), .. } =
+            obligation.cause.code()
+        {
+            *rhs_span
+        } else {
+            span
+        };
+
         // Try to report a help message
         if is_fn_trait
             && let Ok((implemented_kind, params)) = self.type_implements_fn_trait(
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 46c31c77613..bde72c691dc 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -3953,9 +3953,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         candidate_impls: &[ImplCandidate<'tcx>],
         span: Span,
     ) {
-        // We can only suggest the slice coersion for function arguments since the suggestion
-        // would make no sense in turbofish or call
-        let ObligationCauseCode::FunctionArgumentObligation { .. } = obligation.cause.code() else {
+        // We can only suggest the slice coersion for function and binary operation arguments,
+        // since the suggestion would make no sense in turbofish or call
+        let (ObligationCauseCode::BinOp { .. }
+        | ObligationCauseCode::FunctionArgumentObligation { .. }) = obligation.cause.code()
+        else {
             return;
         };
 
diff --git a/tests/ui/dst/issue-113447.fixed b/tests/ui/dst/issue-113447.fixed
new file mode 100644
index 00000000000..536f680f697
--- /dev/null
+++ b/tests/ui/dst/issue-113447.fixed
@@ -0,0 +1,25 @@
+// run-rustfix
+
+pub struct Bytes;
+
+impl Bytes {
+    pub fn as_slice(&self) -> &[u8] {
+        todo!()
+    }
+}
+
+impl PartialEq<[u8]> for Bytes {
+    fn eq(&self, other: &[u8]) -> bool {
+        self.as_slice() == other
+    }
+}
+
+impl PartialEq<Bytes> for &[u8] {
+    fn eq(&self, other: &Bytes) -> bool {
+        *other == **self
+    }
+}
+
+fn main() {
+    let _ = &[0u8] == &[0xAA][..]; //~ ERROR can't compare `&[u8; 1]` with `[{integer}; 1]`
+}
diff --git a/tests/ui/dst/issue-113447.rs b/tests/ui/dst/issue-113447.rs
new file mode 100644
index 00000000000..c10a4f2ff8e
--- /dev/null
+++ b/tests/ui/dst/issue-113447.rs
@@ -0,0 +1,25 @@
+// run-rustfix
+
+pub struct Bytes;
+
+impl Bytes {
+    pub fn as_slice(&self) -> &[u8] {
+        todo!()
+    }
+}
+
+impl PartialEq<[u8]> for Bytes {
+    fn eq(&self, other: &[u8]) -> bool {
+        self.as_slice() == other
+    }
+}
+
+impl PartialEq<Bytes> for &[u8] {
+    fn eq(&self, other: &Bytes) -> bool {
+        *other == **self
+    }
+}
+
+fn main() {
+    let _ = &[0u8] == [0xAA]; //~ ERROR can't compare `&[u8; 1]` with `[{integer}; 1]`
+}
diff --git a/tests/ui/dst/issue-113447.stderr b/tests/ui/dst/issue-113447.stderr
new file mode 100644
index 00000000000..240553a675b
--- /dev/null
+++ b/tests/ui/dst/issue-113447.stderr
@@ -0,0 +1,25 @@
+error[E0277]: can't compare `&[u8; 1]` with `[{integer}; 1]`
+  --> $DIR/issue-113447.rs:24:20
+   |
+LL |     let _ = &[0u8] == [0xAA];
+   |                    ^^ no implementation for `&[u8; 1] == [{integer}; 1]`
+   |
+   = help: the trait `PartialEq<[{integer}; 1]>` is not implemented for `&[u8; 1]`
+   = help: the following other types implement trait `PartialEq<Rhs>`:
+             <[A; N] as PartialEq<[B; N]>>
+             <[A; N] as PartialEq<[B]>>
+             <[A; N] as PartialEq<&[B]>>
+             <[A; N] as PartialEq<&mut [B]>>
+             <[T] as PartialEq<Vec<U, A>>>
+             <[A] as PartialEq<[B]>>
+             <[B] as PartialEq<[A; N]>>
+             <&[u8] as PartialEq<Bytes>>
+           and 4 others
+help: convert the array to a `&[u8]` slice instead
+   |
+LL |     let _ = &[0u8] == &[0xAA][..];
+   |                       +      ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.