diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index 2daa4fd27ce..d2fe099e433 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -333,18 +333,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { lhs_ty); if !lhs_expr.span.eq(&rhs_expr.span) { - self.add_type_neq_err_label(&mut err, - lhs_expr.span, - lhs_ty, - rhs_ty, - op, - is_assign); - self.add_type_neq_err_label(&mut err, - rhs_expr.span, - rhs_ty, - lhs_ty, - op, - is_assign); + self.add_type_neq_err_label( + &mut err, + lhs_expr.span, + lhs_ty, + rhs_ty, + op, + is_assign + ); + self.add_type_neq_err_label( + &mut err, + rhs_expr.span, + rhs_ty, + lhs_ty, + op, + is_assign + ); } let mut suggested_deref = false; @@ -447,21 +451,35 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } }; + let other_ty = if let FnDef(def_id, _) = other_ty.sty { + let hir_id = &self.tcx.hir().as_local_hir_id(def_id).unwrap(); + match self.tcx.typeck_tables_of(def_id).liberated_fn_sigs().get(*hir_id) { + Some(f) => f.clone().output(), + None => { + bug!("No fn-sig entry for def_id={:?}", def_id); + } + } + } else { + other_ty + }; + if self.lookup_op_method(fn_sig.output(), &[other_ty], Op::Binary(op, is_assign)) .is_ok() { - let variable_snippet = if fn_sig.inputs().len() > 0 { - format!("{}( /* arguments */ )", source_map.span_to_snippet(span).unwrap()) + let (variable_snippet, applicability) = if fn_sig.inputs().len() > 0 { + (format!("{}( /* arguments */ )", source_map.span_to_snippet(span).unwrap()), + Applicability::HasPlaceholders) } else { - format!("{}()", source_map.span_to_snippet(span).unwrap()) + (format!("{}()", source_map.span_to_snippet(span).unwrap()), + Applicability::MaybeIncorrect) }; err.span_suggestion( span, - "did you forget", + "you might have forgotten to call this function", variable_snippet, - Applicability::MachineApplicable, + applicability, ); } } diff --git a/src/test/ui/fn/fn-compare-mismatch.stderr b/src/test/ui/fn/fn-compare-mismatch.stderr index 07b93d9aae7..74fb00f8ac3 100644 --- a/src/test/ui/fn/fn-compare-mismatch.stderr +++ b/src/test/ui/fn/fn-compare-mismatch.stderr @@ -7,6 +7,14 @@ LL | let x = f == g; | fn() {main::f} | = note: an implementation of `std::cmp::PartialEq` might be missing for `fn() {main::f}` +help: you might have forgotten to call this function + | +LL | let x = f() == g; + | ^^^ +help: you might have forgotten to call this function + | +LL | let x = f == g(); + | ^^^ error[E0308]: mismatched types --> $DIR/fn-compare-mismatch.rs:4:18 diff --git a/src/test/ui/issues/issue-59488.rs b/src/test/ui/issues/issue-59488.rs index ab501a2c8ec..27cf16a821f 100644 --- a/src/test/ui/issues/issue-59488.rs +++ b/src/test/ui/issues/issue-59488.rs @@ -16,4 +16,11 @@ fn main() { bar > 13; //~^ ERROR 16:9: 16:10: binary operation `>` cannot be applied to type `fn(i64) -> i64 {bar}` [E0369] //~| ERROR 16:11: 16:13: mismatched types [E0308] + + foo > foo; + //~^ ERROR 20:9: 20:10: binary operation `>` cannot be applied to type `fn() -> i32 {foo}` [E0369] + + foo > bar; + //~^ ERROR 23:9: 23:10: binary operation `>` cannot be applied to type `fn() -> i32 {foo}` [E0369] + //~| ERROR 23:11: 23:14: mismatched types [E0308] } diff --git a/src/test/ui/issues/issue-59488.stderr b/src/test/ui/issues/issue-59488.stderr index 2eaf4220a42..b49f5e35f42 100644 --- a/src/test/ui/issues/issue-59488.stderr +++ b/src/test/ui/issues/issue-59488.stderr @@ -5,7 +5,7 @@ LL | foo > 12; | --- ^ -- {integer} | | | fn() -> i32 {foo} - | help: did you forget: `foo()` + | help: you might have forgotten to call this function: `foo()` | = note: an implementation of `std::cmp::PartialOrd` might be missing for `fn() -> i32 {foo}` @@ -25,7 +25,7 @@ LL | bar > 13; | --- ^ -- {integer} | | | fn(i64) -> i64 {bar} - | help: did you forget: `bar( /* arguments */ )` + | help: you might have forgotten to call this function: `bar( /* arguments */ )` | = note: an implementation of `std::cmp::PartialOrd` might be missing for `fn(i64) -> i64 {bar}` @@ -38,7 +38,44 @@ LL | bar > 13; = note: expected type `fn(i64) -> i64 {bar}` found type `i64` -error: aborting due to 4 previous errors +error[E0369]: binary operation `>` cannot be applied to type `fn() -> i32 {foo}` + --> $DIR/issue-59488.rs:20:9 + | +LL | foo > foo; + | --- ^ --- fn() -> i32 {foo} + | | + | fn() -> i32 {foo} + | + = note: an implementation of `std::cmp::PartialOrd` might be missing for `fn() -> i32 {foo}` +help: you might have forgotten to call this function + | +LL | foo() > foo; + | ^^^^^ +help: you might have forgotten to call this function + | +LL | foo > foo(); + | ^^^^^ + +error[E0369]: binary operation `>` cannot be applied to type `fn() -> i32 {foo}` + --> $DIR/issue-59488.rs:23:9 + | +LL | foo > bar; + | --- ^ --- fn(i64) -> i64 {bar} + | | + | fn() -> i32 {foo} + | + = note: an implementation of `std::cmp::PartialOrd` might be missing for `fn() -> i32 {foo}` + +error[E0308]: mismatched types + --> $DIR/issue-59488.rs:23:11 + | +LL | foo > bar; + | ^^^ expected fn item, found a different fn item + | + = note: expected type `fn() -> i32 {foo}` + found type `fn(i64) -> i64 {bar}` + +error: aborting due to 7 previous errors Some errors occurred: E0308, E0369. For more information about an error, try `rustc --explain E0308`.