diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 525acfdaa81..b8222820cf7 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -1508,6 +1508,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // FIXME(compiler-errors): We can actually do this if the checked_ty is // `steps` layers of boxes, not just one, but this is easier and most likely. || (checked_ty.is_box() && steps == 1) + // We can always deref a binop that takes its arguments by ref. + || matches!( + self.tcx.hir().get_parent(expr.hir_id), + hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Binary(op, ..), .. }) + if !op.node.is_by_value() + ) { let deref_kind = if checked_ty.is_box() { "unboxing the value" diff --git a/tests/ui/inference/deref-suggestion.rs b/tests/ui/inference/deref-suggestion.rs index 0d8e7289dc8..dc39cc9dbff 100644 --- a/tests/ui/inference/deref-suggestion.rs +++ b/tests/ui/inference/deref-suggestion.rs @@ -72,4 +72,13 @@ fn main() { } else { &0 }; + + #[derive(PartialEq, Eq)] + struct Foo; + let foo = Foo; + let bar = &Foo; + + if foo == bar { + //~^ ERROR mismatched types + } } diff --git a/tests/ui/inference/deref-suggestion.stderr b/tests/ui/inference/deref-suggestion.stderr index 1626032ae99..6f5aacacfc1 100644 --- a/tests/ui/inference/deref-suggestion.stderr +++ b/tests/ui/inference/deref-suggestion.stderr @@ -175,6 +175,19 @@ LL | || }; | |_____`if` and `else` have incompatible types | expected `i32`, found `&{integer}` -error: aborting due to 13 previous errors +error[E0308]: mismatched types + --> $DIR/deref-suggestion.rs:81:15 + | +LL | if foo == bar { + | --- ^^^ expected `Foo`, found `&Foo` + | | + | expected because this is `Foo` + | +help: consider dereferencing the borrow + | +LL | if foo == *bar { + | + + +error: aborting due to 14 previous errors For more information about this error, try `rustc --explain E0308`.