about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-12-14 10:31:07 +0100
committerGitHub <noreply@github.com>2022-12-14 10:31:07 +0100
commit939880ab7275a779e2a970caa4ca0fa1b7c25b37 (patch)
treece4227c7d2786f2caf9528ddda258b7dc28af159
parente5fde968dbbb87e5721ff5da91a49cab88b90b91 (diff)
parent19fa5b381c98016f643a9e59c7159c67bae1dd8c (diff)
downloadrust-939880ab7275a779e2a970caa4ca0fa1b7c25b37.tar.gz
rust-939880ab7275a779e2a970caa4ca0fa1b7c25b37.zip
Rollup merge of #105595 - TaKO8Ki:suggest-dereferencing-receiver-argument, r=compiler-errors
Suggest dereferencing receiver arguments properly

Fixes #105429
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs34
-rw-r--r--src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.fixed14
-rw-r--r--src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.rs14
-rw-r--r--src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.stderr15
4 files changed, 71 insertions, 6 deletions
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 e17c3777485..55a05df763f 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -696,7 +696,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         trait_pred: ty::PolyTraitPredicate<'tcx>,
     ) -> bool {
         // It only make sense when suggesting dereferences for arguments
-        let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code()
+        let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, call_hir_id, .. } = obligation.cause.code()
             else { return false; };
         let Some(typeck_results) = &self.typeck_results
             else { return false; };
@@ -775,12 +775,33 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         real_trait_pred_and_base_ty,
                     );
                     if self.predicate_may_hold(&obligation) {
-                        err.span_suggestion_verbose(
-                            span.shrink_to_lo(),
-                            "consider dereferencing here",
-                            "*",
-                            Applicability::MachineApplicable,
+                        let call_node = self.tcx.hir().get(*call_hir_id);
+                        let msg = "consider dereferencing here";
+                        let is_receiver = matches!(
+                            call_node,
+                            Node::Expr(hir::Expr {
+                                kind: hir::ExprKind::MethodCall(_, receiver_expr, ..),
+                                ..
+                            })
+                            if receiver_expr.hir_id == *arg_hir_id
                         );
+                        if is_receiver {
+                            err.multipart_suggestion_verbose(
+                                msg,
+                                vec![
+                                    (span.shrink_to_lo(), "(*".to_string()),
+                                    (span.shrink_to_hi(), ")".to_string()),
+                                ],
+                                Applicability::MachineApplicable,
+                            )
+                        } else {
+                            err.span_suggestion_verbose(
+                                span.shrink_to_lo(),
+                                msg,
+                                '*',
+                                Applicability::MachineApplicable,
+                            )
+                        };
                         return true;
                     }
                 }
@@ -2854,6 +2875,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 arg_hir_id,
                 call_hir_id,
                 ref parent_code,
+                ..
             } => {
                 self.function_argument_obligation(
                     arg_hir_id,
diff --git a/src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.fixed b/src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.fixed
new file mode 100644
index 00000000000..ea3d1bf853a
--- /dev/null
+++ b/src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.fixed
@@ -0,0 +1,14 @@
+// run-rustfix
+
+struct TargetStruct;
+
+impl From<usize> for TargetStruct {
+    fn from(_unchecked: usize) -> Self {
+        TargetStruct
+    }
+}
+
+fn main() {
+    let a = &3;
+    let _b: TargetStruct = (*a).into(); //~ ERROR the trait bound `TargetStruct: From<&{integer}>` is not satisfied
+}
diff --git a/src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.rs b/src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.rs
new file mode 100644
index 00000000000..9eda68027b2
--- /dev/null
+++ b/src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.rs
@@ -0,0 +1,14 @@
+// run-rustfix
+
+struct TargetStruct;
+
+impl From<usize> for TargetStruct {
+    fn from(_unchecked: usize) -> Self {
+        TargetStruct
+    }
+}
+
+fn main() {
+    let a = &3;
+    let _b: TargetStruct = a.into(); //~ ERROR the trait bound `TargetStruct: From<&{integer}>` is not satisfied
+}
diff --git a/src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.stderr b/src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.stderr
new file mode 100644
index 00000000000..ede31a2c7bc
--- /dev/null
+++ b/src/test/ui/traits/suggest-deferences/suggest-dereferencing-receiver-argument.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `TargetStruct: From<&{integer}>` is not satisfied
+  --> $DIR/suggest-dereferencing-receiver-argument.rs:13:30
+   |
+LL |     let _b: TargetStruct = a.into();
+   |                              ^^^^ the trait `From<&{integer}>` is not implemented for `TargetStruct`
+   |
+   = note: required for `&{integer}` to implement `Into<TargetStruct>`
+help: consider dereferencing here
+   |
+LL |     let _b: TargetStruct = (*a).into();
+   |                            ++ +
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.