about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-04-14 05:58:13 +0000
committerbors <bors@rust-lang.org>2019-04-14 05:58:13 +0000
commit464473ab3b4bedb89fa6841ab2ceea83cb8d75fe (patch)
treefcfa85db3a93064bb08d1a0690c2a26cbd7e1f2d /src
parentee621f42329069c296b4c2066b3743cc4ff0f369 (diff)
parentd01ac0d61e31ffdff0a85a76de6f4449935b5a6b (diff)
downloadrust-464473ab3b4bedb89fa6841ab2ceea83cb8d75fe.tar.gz
rust-464473ab3b4bedb89fa6841ab2ceea83cb8d75fe.zip
Auto merge of #59798 - rchaser53:issue-59488, r=estebank
Improvement for comparision against fn

I try to add error message.
related: https://github.com/rust-lang/rust/issues/59488
Diffstat (limited to 'src')
-rw-r--r--src/librustc_typeck/check/op.rs76
-rw-r--r--src/test/ui/fn/fn-compare-mismatch.stderr8
-rw-r--r--src/test/ui/issues/issue-59488.rs26
-rw-r--r--src/test/ui/issues/issue-59488.stderr81
4 files changed, 188 insertions, 3 deletions
diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
index d6932094ddd..d2fe099e433 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/src/librustc_typeck/check/op.rs
@@ -3,7 +3,7 @@
 use super::{FnCtxt, Needs};
 use super::method::MethodCallee;
 use rustc::ty::{self, Ty, TypeFoldable};
-use rustc::ty::TyKind::{Ref, Adt, Str, Uint, Never, Tuple, Char, Array};
+use rustc::ty::TyKind::{Ref, Adt, FnDef, Str, Uint, Never, Tuple, Char, Array};
 use rustc::ty::adjustment::{Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
 use rustc::infer::type_variable::TypeVariableOrigin;
 use errors::{self,Applicability};
@@ -333,8 +333,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                 lhs_ty);
 
                             if !lhs_expr.span.eq(&rhs_expr.span) {
-                                err.span_label(lhs_expr.span, lhs_ty.to_string());
-                                err.span_label(rhs_expr.span, rhs_ty.to_string());
+                                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;
@@ -415,6 +429,62 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         (lhs_ty, rhs_ty, return_ty)
     }
 
+    fn add_type_neq_err_label(
+        &self,
+        err: &mut errors::DiagnosticBuilder<'_>,
+        span: Span,
+        ty: Ty<'tcx>,
+        other_ty: Ty<'tcx>,
+        op: hir::BinOp,
+        is_assign: IsAssign,
+    ) {
+        err.span_label(span, ty.to_string());
+        if let FnDef(def_id, _) = ty.sty {
+            let source_map = self.tcx.sess.source_map();
+            let hir_id = &self.tcx.hir().as_local_hir_id(def_id).unwrap();
+            let fn_sig = {
+                match self.tcx.typeck_tables_of(def_id).liberated_fn_sigs().get(*hir_id) {
+                    Some(f) => f.clone(),
+                    None => {
+                        bug!("No fn-sig entry for def_id={:?}", def_id);
+                    }
+                }
+            };
+
+            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, 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()),
+                    Applicability::MaybeIncorrect)
+                };
+
+                err.span_suggestion(
+                    span,
+                    "you might have forgotten to call this function",
+                    variable_snippet,
+                    applicability,
+                );
+            }
+        }
+    }
+
     fn check_str_addition(
         &self,
         expr: &'gcx hir::Expr,
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
new file mode 100644
index 00000000000..27cf16a821f
--- /dev/null
+++ b/src/test/ui/issues/issue-59488.rs
@@ -0,0 +1,26 @@
+// ignore-tidy-linelength
+
+fn foo() -> i32 {
+    42
+}
+
+fn bar(a: i64) -> i64 {
+    43
+}
+
+fn main() {
+    foo > 12;
+    //~^ ERROR 12:9: 12:10: binary operation `>` cannot be applied to type `fn() -> i32 {foo}` [E0369]
+    //~| ERROR 12:11: 12:13: mismatched types [E0308]
+
+    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
new file mode 100644
index 00000000000..b49f5e35f42
--- /dev/null
+++ b/src/test/ui/issues/issue-59488.stderr
@@ -0,0 +1,81 @@
+error[E0369]: binary operation `>` cannot be applied to type `fn() -> i32 {foo}`
+  --> $DIR/issue-59488.rs:12:9
+   |
+LL |     foo > 12;
+   |     --- ^ -- {integer}
+   |     |
+   |     fn() -> i32 {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}`
+
+error[E0308]: mismatched types
+  --> $DIR/issue-59488.rs:12:11
+   |
+LL |     foo > 12;
+   |           ^^ expected fn item, found integer
+   |
+   = note: expected type `fn() -> i32 {foo}`
+              found type `i32`
+
+error[E0369]: binary operation `>` cannot be applied to type `fn(i64) -> i64 {bar}`
+  --> $DIR/issue-59488.rs:16:9
+   |
+LL |     bar > 13;
+   |     --- ^ -- {integer}
+   |     |
+   |     fn(i64) -> i64 {bar}
+   |     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}`
+
+error[E0308]: mismatched types
+  --> $DIR/issue-59488.rs:16:11
+   |
+LL |     bar > 13;
+   |           ^^ expected fn item, found integer
+   |
+   = note: expected type `fn(i64) -> i64 {bar}`
+              found type `i64`
+
+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`.