about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2023-01-23 11:52:07 +0530
committerGitHub <noreply@github.com>2023-01-23 11:52:07 +0530
commit66d6a0b5da24b41185d060e3e7f9155a22f78872 (patch)
tree88f5bfb4f55251ab353c65ed74111e46fe952b4a
parente4ed082579da3a5710903fef0a9232565424ea8a (diff)
parent2aa5555ad3911536e2d0d363633f1a4cb67b1c49 (diff)
downloadrust-66d6a0b5da24b41185d060e3e7f9155a22f78872.tar.gz
rust-66d6a0b5da24b41185d060e3e7f9155a22f78872.zip
Rollup merge of #107203 - chenyukang:yukang/fix-106496-remove-deref, r=compiler-errors
Suggest remove deref for type mismatch

Fixes #106496
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs16
-rw-r--r--tests/ui/generic-associated-types/issue-88360.fixed20
-rw-r--r--tests/ui/generic-associated-types/issue-88360.rs2
-rw-r--r--tests/ui/generic-associated-types/issue-88360.stderr12
-rw-r--r--tests/ui/suggestions/suggest-remove-deref.fixed28
-rw-r--r--tests/ui/suggestions/suggest-remove-deref.rs28
-rw-r--r--tests/ui/suggestions/suggest-remove-deref.stderr43
7 files changed, 144 insertions, 5 deletions
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 665dc8b6a2f..bd1626dff79 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -1233,6 +1233,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             sugg_sp = receiver.span;
                         }
                     }
+
+                    if let hir::ExprKind::Unary(hir::UnOp::Deref, ref inner) = expr.kind
+                        && let Some(1) = self.deref_steps(expected, checked_ty) {
+                        // We have `*&T`, check if what was expected was `&T`.
+                        // If so, we may want to suggest removing a `*`.
+                        sugg_sp = sugg_sp.with_hi(inner.span.lo());
+                        return Some((
+                            sugg_sp,
+                            "consider removing deref here".to_string(),
+                            "".to_string(),
+                            Applicability::MachineApplicable,
+                            true,
+                            false,
+                        ));
+                    }
+
                     if let Ok(src) = sm.span_to_snippet(sugg_sp) {
                         let needs_parens = match expr.kind {
                             // parenthesize if needed (Issue #46756)
diff --git a/tests/ui/generic-associated-types/issue-88360.fixed b/tests/ui/generic-associated-types/issue-88360.fixed
new file mode 100644
index 00000000000..3dea8bf7ac8
--- /dev/null
+++ b/tests/ui/generic-associated-types/issue-88360.fixed
@@ -0,0 +1,20 @@
+// run-rustfix
+
+trait GatTrait {
+    type Gat<'a> where Self: 'a;
+
+    fn test(&self) -> Self::Gat<'_>;
+}
+
+trait SuperTrait<T>
+where
+    Self: 'static,
+    for<'a> Self: GatTrait<Gat<'a> = &'a T>,
+{
+    fn copy(&self) -> Self::Gat<'_> where T: Copy {
+        self.test()
+        //~^ mismatched types
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/generic-associated-types/issue-88360.rs b/tests/ui/generic-associated-types/issue-88360.rs
index c02690618d0..4d4c7ea3180 100644
--- a/tests/ui/generic-associated-types/issue-88360.rs
+++ b/tests/ui/generic-associated-types/issue-88360.rs
@@ -1,3 +1,5 @@
+// run-rustfix
+
 trait GatTrait {
     type Gat<'a> where Self: 'a;
 
diff --git a/tests/ui/generic-associated-types/issue-88360.stderr b/tests/ui/generic-associated-types/issue-88360.stderr
index cd3750344dd..520aeff1894 100644
--- a/tests/ui/generic-associated-types/issue-88360.stderr
+++ b/tests/ui/generic-associated-types/issue-88360.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-88360.rs:13:9
+  --> $DIR/issue-88360.rs:15:9
    |
 LL | trait SuperTrait<T>
    |                  - this type parameter
@@ -7,13 +7,15 @@ LL | trait SuperTrait<T>
 LL |     fn copy(&self) -> Self::Gat<'_> where T: Copy {
    |                       ------------- expected `&T` because of return type
 LL |         *self.test()
-   |         ^^^^^^^^^^^^
-   |         |
-   |         expected `&T`, found type parameter `T`
-   |         help: consider borrowing here: `&*self.test()`
+   |         ^^^^^^^^^^^^ expected `&T`, found type parameter `T`
    |
    = note:   expected reference `&T`
            found type parameter `T`
+help: consider removing deref here
+   |
+LL -         *self.test()
+LL +         self.test()
+   |
 
 error: aborting due to previous error
 
diff --git a/tests/ui/suggestions/suggest-remove-deref.fixed b/tests/ui/suggestions/suggest-remove-deref.fixed
new file mode 100644
index 00000000000..4dc12da03dd
--- /dev/null
+++ b/tests/ui/suggestions/suggest-remove-deref.fixed
@@ -0,0 +1,28 @@
+// run-rustfix
+
+//issue #106496
+
+struct S;
+
+trait X {}
+impl X for S {}
+
+fn foo<T: X>(_: &T) {}
+fn test_foo() {
+    let hello = &S;
+    foo(hello);
+    //~^ ERROR mismatched types
+}
+
+fn bar(_: &String) {}
+fn test_bar() {
+    let v = String::from("hello");
+    let s = &v;
+    bar(s);
+    //~^ ERROR mismatched types
+}
+
+fn main() {
+    test_foo();
+    test_bar();
+}
diff --git a/tests/ui/suggestions/suggest-remove-deref.rs b/tests/ui/suggestions/suggest-remove-deref.rs
new file mode 100644
index 00000000000..c2d385cbdc3
--- /dev/null
+++ b/tests/ui/suggestions/suggest-remove-deref.rs
@@ -0,0 +1,28 @@
+// run-rustfix
+
+//issue #106496
+
+struct S;
+
+trait X {}
+impl X for S {}
+
+fn foo<T: X>(_: &T) {}
+fn test_foo() {
+    let hello = &S;
+    foo(*hello);
+    //~^ ERROR mismatched types
+}
+
+fn bar(_: &String) {}
+fn test_bar() {
+    let v = String::from("hello");
+    let s = &v;
+    bar(*s);
+    //~^ ERROR mismatched types
+}
+
+fn main() {
+    test_foo();
+    test_bar();
+}
diff --git a/tests/ui/suggestions/suggest-remove-deref.stderr b/tests/ui/suggestions/suggest-remove-deref.stderr
new file mode 100644
index 00000000000..f5d810e36f0
--- /dev/null
+++ b/tests/ui/suggestions/suggest-remove-deref.stderr
@@ -0,0 +1,43 @@
+error[E0308]: mismatched types
+  --> $DIR/suggest-remove-deref.rs:13:9
+   |
+LL |     foo(*hello);
+   |     --- ^^^^^^ expected reference, found struct `S`
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected reference `&_`
+                 found struct `S`
+note: function defined here
+  --> $DIR/suggest-remove-deref.rs:10:4
+   |
+LL | fn foo<T: X>(_: &T) {}
+   |    ^^^       -----
+help: consider removing deref here
+   |
+LL -     foo(*hello);
+LL +     foo(hello);
+   |
+
+error[E0308]: mismatched types
+  --> $DIR/suggest-remove-deref.rs:21:9
+   |
+LL |     bar(*s);
+   |     --- ^^ expected `&String`, found struct `String`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/suggest-remove-deref.rs:17:4
+   |
+LL | fn bar(_: &String) {}
+   |    ^^^ ----------
+help: consider removing deref here
+   |
+LL -     bar(*s);
+LL +     bar(s);
+   |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.