about summary refs log tree commit diff
diff options
context:
space:
mode:
authorclubby789 <jamie@hill-daniel.co.uk>2023-07-27 23:10:53 +0000
committerclubby789 <jamie@hill-daniel.co.uk>2023-07-27 23:13:26 +0000
commitfafc3d2d0e3b9d3d1933459d93b9577819577e48 (patch)
treeefebb632ba565f61502dee4ec075eb14255c9c1d
parent683b2656bfef8d6ef317427cd9eb027f120ecc30 (diff)
downloadrust-fafc3d2d0e3b9d3d1933459d93b9577819577e48.tar.gz
rust-fafc3d2d0e3b9d3d1933459d93b9577819577e48.zip
Handle exclusive refs in suggestion to copy/clone
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs8
-rw-r--r--tests/ui/suggestions/copied-and-cloned.fixed14
-rw-r--r--tests/ui/suggestions/copied-and-cloned.rs14
-rw-r--r--tests/ui/suggestions/copied-and-cloned.stderr28
4 files changed, 61 insertions, 3 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index ff715a1999d..fe962f6c1c0 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -1110,7 +1110,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         {
             let expr_inner_ty = args.type_at(0);
             let expected_inner_ty = expected_args.type_at(0);
-            if let &ty::Ref(_, ty, hir::Mutability::Not) = expr_inner_ty.kind()
+            if let &ty::Ref(_, ty, mutability) = expr_inner_ty.kind()
                     && self.can_eq(self.param_env, ty, expected_inner_ty)
                 {
                     let def_path = self.tcx.def_path_str(adt_def.did());
@@ -1119,7 +1119,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         errors::OptionResultRefMismatch::Copied {
                             span, def_path
                         }
-                    } else if let Some(expected_ty_expr) = expected_ty_expr {
+                    } else if let Some(expected_ty_expr) = expected_ty_expr
+                            // FIXME: suggest changes to both expressions to convert both to
+                            // Option/Result<&T>
+                            && mutability.is_not()
+                        {
                         errors::OptionResultRefMismatch::AsRef {
                             span: expected_ty_expr.span.shrink_to_hi(), expected_ty, expr_ty, def_path
                         }
diff --git a/tests/ui/suggestions/copied-and-cloned.fixed b/tests/ui/suggestions/copied-and-cloned.fixed
index dec89c60388..77159d5075a 100644
--- a/tests/ui/suggestions/copied-and-cloned.fixed
+++ b/tests/ui/suggestions/copied-and-cloned.fixed
@@ -28,4 +28,18 @@ fn main() {
     //~^ ERROR mismatched types
     //~| HELP use `Option::as_ref` to convert `Option<String>` to `Option<&String>`
 
+
+    let mut s = ();
+    let x = Some(s);
+    let y = Some(&mut s);
+    println!("{}", x == y.copied());
+    //~^ ERROR mismatched types
+    //~| HELP use `Option::copied` to copy the value inside the `Option`
+
+    let mut s = String::new();
+    let x = Some(s.clone());
+    let y = Some(&mut s);
+    println!("{}", x == y.cloned());
+    //~^ ERROR mismatched types
+    //~| HELP use `Option::cloned` to clone the value inside the `Option`
 }
diff --git a/tests/ui/suggestions/copied-and-cloned.rs b/tests/ui/suggestions/copied-and-cloned.rs
index 99485a2b525..c506494ee14 100644
--- a/tests/ui/suggestions/copied-and-cloned.rs
+++ b/tests/ui/suggestions/copied-and-cloned.rs
@@ -28,4 +28,18 @@ fn main() {
     //~^ ERROR mismatched types
     //~| HELP use `Option::as_ref` to convert `Option<String>` to `Option<&String>`
 
+
+    let mut s = ();
+    let x = Some(s);
+    let y = Some(&mut s);
+    println!("{}", x == y);
+    //~^ ERROR mismatched types
+    //~| HELP use `Option::copied` to copy the value inside the `Option`
+
+    let mut s = String::new();
+    let x = Some(s.clone());
+    let y = Some(&mut s);
+    println!("{}", x == y);
+    //~^ ERROR mismatched types
+    //~| HELP use `Option::cloned` to clone the value inside the `Option`
 }
diff --git a/tests/ui/suggestions/copied-and-cloned.stderr b/tests/ui/suggestions/copied-and-cloned.stderr
index 6384c9b55da..f8712d0a39e 100644
--- a/tests/ui/suggestions/copied-and-cloned.stderr
+++ b/tests/ui/suggestions/copied-and-cloned.stderr
@@ -91,6 +91,32 @@ help: use `Option::as_ref` to convert `Option<String>` to `Option<&String>`
 LL |     println!("{}", x.as_ref() == y);
    |                     +++++++++
 
-error: aborting due to 5 previous errors
+error[E0308]: mismatched types
+  --> $DIR/copied-and-cloned.rs:35:25
+   |
+LL |     println!("{}", x == y);
+   |                         ^ expected `Option<()>`, found `Option<&mut ()>`
+   |
+   = note: expected enum `Option<()>`
+              found enum `Option<&mut ()>`
+help: use `Option::copied` to copy the value inside the `Option`
+   |
+LL |     println!("{}", x == y.copied());
+   |                          +++++++++
+
+error[E0308]: mismatched types
+  --> $DIR/copied-and-cloned.rs:42:25
+   |
+LL |     println!("{}", x == y);
+   |                         ^ expected `Option<String>`, found `Option<&mut String>`
+   |
+   = note: expected enum `Option<String>`
+              found enum `Option<&mut String>`
+help: use `Option::cloned` to clone the value inside the `Option`
+   |
+LL |     println!("{}", x == y.cloned());
+   |                          +++++++++
+
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0308`.