Skip to content

Commit fafc3d2

Browse files
committed
Handle exclusive refs in suggestion to copy/clone
1 parent 683b265 commit fafc3d2

File tree

4 files changed

+61
-3
lines changed

4 files changed

+61
-3
lines changed

Diff for: compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11101110
{
11111111
let expr_inner_ty = args.type_at(0);
11121112
let expected_inner_ty = expected_args.type_at(0);
1113-
if let &ty::Ref(_, ty, hir::Mutability::Not) = expr_inner_ty.kind()
1113+
if let &ty::Ref(_, ty, mutability) = expr_inner_ty.kind()
11141114
&& self.can_eq(self.param_env, ty, expected_inner_ty)
11151115
{
11161116
let def_path = self.tcx.def_path_str(adt_def.did());
@@ -1119,7 +1119,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11191119
errors::OptionResultRefMismatch::Copied {
11201120
span, def_path
11211121
}
1122-
} else if let Some(expected_ty_expr) = expected_ty_expr {
1122+
} else if let Some(expected_ty_expr) = expected_ty_expr
1123+
// FIXME: suggest changes to both expressions to convert both to
1124+
// Option/Result<&T>
1125+
&& mutability.is_not()
1126+
{
11231127
errors::OptionResultRefMismatch::AsRef {
11241128
span: expected_ty_expr.span.shrink_to_hi(), expected_ty, expr_ty, def_path
11251129
}

Diff for: tests/ui/suggestions/copied-and-cloned.fixed

+14
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,18 @@ fn main() {
2828
//~^ ERROR mismatched types
2929
//~| HELP use `Option::as_ref` to convert `Option<String>` to `Option<&String>`
3030

31+
32+
let mut s = ();
33+
let x = Some(s);
34+
let y = Some(&mut s);
35+
println!("{}", x == y.copied());
36+
//~^ ERROR mismatched types
37+
//~| HELP use `Option::copied` to copy the value inside the `Option`
38+
39+
let mut s = String::new();
40+
let x = Some(s.clone());
41+
let y = Some(&mut s);
42+
println!("{}", x == y.cloned());
43+
//~^ ERROR mismatched types
44+
//~| HELP use `Option::cloned` to clone the value inside the `Option`
3145
}

Diff for: tests/ui/suggestions/copied-and-cloned.rs

+14
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,18 @@ fn main() {
2828
//~^ ERROR mismatched types
2929
//~| HELP use `Option::as_ref` to convert `Option<String>` to `Option<&String>`
3030

31+
32+
let mut s = ();
33+
let x = Some(s);
34+
let y = Some(&mut s);
35+
println!("{}", x == y);
36+
//~^ ERROR mismatched types
37+
//~| HELP use `Option::copied` to copy the value inside the `Option`
38+
39+
let mut s = String::new();
40+
let x = Some(s.clone());
41+
let y = Some(&mut s);
42+
println!("{}", x == y);
43+
//~^ ERROR mismatched types
44+
//~| HELP use `Option::cloned` to clone the value inside the `Option`
3145
}

Diff for: tests/ui/suggestions/copied-and-cloned.stderr

+27-1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,32 @@ help: use `Option::as_ref` to convert `Option<String>` to `Option<&String>`
9191
LL | println!("{}", x.as_ref() == y);
9292
| +++++++++
9393

94-
error: aborting due to 5 previous errors
94+
error[E0308]: mismatched types
95+
--> $DIR/copied-and-cloned.rs:35:25
96+
|
97+
LL | println!("{}", x == y);
98+
| ^ expected `Option<()>`, found `Option<&mut ()>`
99+
|
100+
= note: expected enum `Option<()>`
101+
found enum `Option<&mut ()>`
102+
help: use `Option::copied` to copy the value inside the `Option`
103+
|
104+
LL | println!("{}", x == y.copied());
105+
| +++++++++
106+
107+
error[E0308]: mismatched types
108+
--> $DIR/copied-and-cloned.rs:42:25
109+
|
110+
LL | println!("{}", x == y);
111+
| ^ expected `Option<String>`, found `Option<&mut String>`
112+
|
113+
= note: expected enum `Option<String>`
114+
found enum `Option<&mut String>`
115+
help: use `Option::cloned` to clone the value inside the `Option`
116+
|
117+
LL | println!("{}", x == y.cloned());
118+
| +++++++++
119+
120+
error: aborting due to 7 previous errors
95121

96122
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)