Skip to content

Commit 464473a

Browse files
committedApr 14, 2019
Auto merge of #59798 - rchaser53:issue-59488, r=estebank
Improvement for comparision against fn I try to add error message. related: #59488
2 parents ee621f4 + d01ac0d commit 464473a

File tree

4 files changed

+188
-3
lines changed

4 files changed

+188
-3
lines changed
 

‎src/librustc_typeck/check/op.rs

+73-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use super::{FnCtxt, Needs};
44
use super::method::MethodCallee;
55
use rustc::ty::{self, Ty, TypeFoldable};
6-
use rustc::ty::TyKind::{Ref, Adt, Str, Uint, Never, Tuple, Char, Array};
6+
use rustc::ty::TyKind::{Ref, Adt, FnDef, Str, Uint, Never, Tuple, Char, Array};
77
use rustc::ty::adjustment::{Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
88
use rustc::infer::type_variable::TypeVariableOrigin;
99
use errors::{self,Applicability};
@@ -333,8 +333,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
333333
lhs_ty);
334334

335335
if !lhs_expr.span.eq(&rhs_expr.span) {
336-
err.span_label(lhs_expr.span, lhs_ty.to_string());
337-
err.span_label(rhs_expr.span, rhs_ty.to_string());
336+
self.add_type_neq_err_label(
337+
&mut err,
338+
lhs_expr.span,
339+
lhs_ty,
340+
rhs_ty,
341+
op,
342+
is_assign
343+
);
344+
self.add_type_neq_err_label(
345+
&mut err,
346+
rhs_expr.span,
347+
rhs_ty,
348+
lhs_ty,
349+
op,
350+
is_assign
351+
);
338352
}
339353

340354
let mut suggested_deref = false;
@@ -415,6 +429,62 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
415429
(lhs_ty, rhs_ty, return_ty)
416430
}
417431

432+
fn add_type_neq_err_label(
433+
&self,
434+
err: &mut errors::DiagnosticBuilder<'_>,
435+
span: Span,
436+
ty: Ty<'tcx>,
437+
other_ty: Ty<'tcx>,
438+
op: hir::BinOp,
439+
is_assign: IsAssign,
440+
) {
441+
err.span_label(span, ty.to_string());
442+
if let FnDef(def_id, _) = ty.sty {
443+
let source_map = self.tcx.sess.source_map();
444+
let hir_id = &self.tcx.hir().as_local_hir_id(def_id).unwrap();
445+
let fn_sig = {
446+
match self.tcx.typeck_tables_of(def_id).liberated_fn_sigs().get(*hir_id) {
447+
Some(f) => f.clone(),
448+
None => {
449+
bug!("No fn-sig entry for def_id={:?}", def_id);
450+
}
451+
}
452+
};
453+
454+
let other_ty = if let FnDef(def_id, _) = other_ty.sty {
455+
let hir_id = &self.tcx.hir().as_local_hir_id(def_id).unwrap();
456+
match self.tcx.typeck_tables_of(def_id).liberated_fn_sigs().get(*hir_id) {
457+
Some(f) => f.clone().output(),
458+
None => {
459+
bug!("No fn-sig entry for def_id={:?}", def_id);
460+
}
461+
}
462+
} else {
463+
other_ty
464+
};
465+
466+
if self.lookup_op_method(fn_sig.output(),
467+
&[other_ty],
468+
Op::Binary(op, is_assign))
469+
.is_ok() {
470+
let (variable_snippet, applicability) = if fn_sig.inputs().len() > 0 {
471+
(format!("{}( /* arguments */ )", source_map.span_to_snippet(span).unwrap()),
472+
Applicability::HasPlaceholders)
473+
} else {
474+
(format!("{}()", source_map.span_to_snippet(span).unwrap()),
475+
Applicability::MaybeIncorrect)
476+
};
477+
478+
err.span_suggestion(
479+
span,
480+
"you might have forgotten to call this function",
481+
variable_snippet,
482+
applicability,
483+
);
484+
}
485+
}
486+
}
487+
418488
fn check_str_addition(
419489
&self,
420490
expr: &'gcx hir::Expr,

‎src/test/ui/fn/fn-compare-mismatch.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ LL | let x = f == g;
77
| fn() {main::f}
88
|
99
= note: an implementation of `std::cmp::PartialEq` might be missing for `fn() {main::f}`
10+
help: you might have forgotten to call this function
11+
|
12+
LL | let x = f() == g;
13+
| ^^^
14+
help: you might have forgotten to call this function
15+
|
16+
LL | let x = f == g();
17+
| ^^^
1018

1119
error[E0308]: mismatched types
1220
--> $DIR/fn-compare-mismatch.rs:4:18

‎src/test/ui/issues/issue-59488.rs

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// ignore-tidy-linelength
2+
3+
fn foo() -> i32 {
4+
42
5+
}
6+
7+
fn bar(a: i64) -> i64 {
8+
43
9+
}
10+
11+
fn main() {
12+
foo > 12;
13+
//~^ ERROR 12:9: 12:10: binary operation `>` cannot be applied to type `fn() -> i32 {foo}` [E0369]
14+
//~| ERROR 12:11: 12:13: mismatched types [E0308]
15+
16+
bar > 13;
17+
//~^ ERROR 16:9: 16:10: binary operation `>` cannot be applied to type `fn(i64) -> i64 {bar}` [E0369]
18+
//~| ERROR 16:11: 16:13: mismatched types [E0308]
19+
20+
foo > foo;
21+
//~^ ERROR 20:9: 20:10: binary operation `>` cannot be applied to type `fn() -> i32 {foo}` [E0369]
22+
23+
foo > bar;
24+
//~^ ERROR 23:9: 23:10: binary operation `>` cannot be applied to type `fn() -> i32 {foo}` [E0369]
25+
//~| ERROR 23:11: 23:14: mismatched types [E0308]
26+
}

‎src/test/ui/issues/issue-59488.stderr

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
error[E0369]: binary operation `>` cannot be applied to type `fn() -> i32 {foo}`
2+
--> $DIR/issue-59488.rs:12:9
3+
|
4+
LL | foo > 12;
5+
| --- ^ -- {integer}
6+
| |
7+
| fn() -> i32 {foo}
8+
| help: you might have forgotten to call this function: `foo()`
9+
|
10+
= note: an implementation of `std::cmp::PartialOrd` might be missing for `fn() -> i32 {foo}`
11+
12+
error[E0308]: mismatched types
13+
--> $DIR/issue-59488.rs:12:11
14+
|
15+
LL | foo > 12;
16+
| ^^ expected fn item, found integer
17+
|
18+
= note: expected type `fn() -> i32 {foo}`
19+
found type `i32`
20+
21+
error[E0369]: binary operation `>` cannot be applied to type `fn(i64) -> i64 {bar}`
22+
--> $DIR/issue-59488.rs:16:9
23+
|
24+
LL | bar > 13;
25+
| --- ^ -- {integer}
26+
| |
27+
| fn(i64) -> i64 {bar}
28+
| help: you might have forgotten to call this function: `bar( /* arguments */ )`
29+
|
30+
= note: an implementation of `std::cmp::PartialOrd` might be missing for `fn(i64) -> i64 {bar}`
31+
32+
error[E0308]: mismatched types
33+
--> $DIR/issue-59488.rs:16:11
34+
|
35+
LL | bar > 13;
36+
| ^^ expected fn item, found integer
37+
|
38+
= note: expected type `fn(i64) -> i64 {bar}`
39+
found type `i64`
40+
41+
error[E0369]: binary operation `>` cannot be applied to type `fn() -> i32 {foo}`
42+
--> $DIR/issue-59488.rs:20:9
43+
|
44+
LL | foo > foo;
45+
| --- ^ --- fn() -> i32 {foo}
46+
| |
47+
| fn() -> i32 {foo}
48+
|
49+
= note: an implementation of `std::cmp::PartialOrd` might be missing for `fn() -> i32 {foo}`
50+
help: you might have forgotten to call this function
51+
|
52+
LL | foo() > foo;
53+
| ^^^^^
54+
help: you might have forgotten to call this function
55+
|
56+
LL | foo > foo();
57+
| ^^^^^
58+
59+
error[E0369]: binary operation `>` cannot be applied to type `fn() -> i32 {foo}`
60+
--> $DIR/issue-59488.rs:23:9
61+
|
62+
LL | foo > bar;
63+
| --- ^ --- fn(i64) -> i64 {bar}
64+
| |
65+
| fn() -> i32 {foo}
66+
|
67+
= note: an implementation of `std::cmp::PartialOrd` might be missing for `fn() -> i32 {foo}`
68+
69+
error[E0308]: mismatched types
70+
--> $DIR/issue-59488.rs:23:11
71+
|
72+
LL | foo > bar;
73+
| ^^^ expected fn item, found a different fn item
74+
|
75+
= note: expected type `fn() -> i32 {foo}`
76+
found type `fn(i64) -> i64 {bar}`
77+
78+
error: aborting due to 7 previous errors
79+
80+
Some errors occurred: E0308, E0369.
81+
For more information about an error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)