Skip to content

Commit

Permalink
Auto merge of #59798 - rchaser53:issue-59488, r=estebank
Browse files Browse the repository at this point in the history
Improvement for comparision against fn

I try to add error message.
related: #59488
  • Loading branch information
bors committed Apr 14, 2019
2 parents ee621f4 + d01ac0d commit 464473a
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 3 deletions.
76 changes: 73 additions & 3 deletions src/librustc_typeck/check/op.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/fn/fn-compare-mismatch.stderr
Expand Up @@ -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
Expand Down
26 changes: 26 additions & 0 deletions 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]
}
81 changes: 81 additions & 0 deletions 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`.

0 comments on commit 464473a

Please sign in to comment.