Skip to content

Commit 5af3dec

Browse files
committed
Suggest return type
1 parent 147649d commit 5af3dec

File tree

7 files changed

+67
-8
lines changed

7 files changed

+67
-8
lines changed

compiler/rustc_typeck/src/check/compare_method.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,33 @@ fn compare_predicate_entailment<'tcx>(
329329
);
330330
}
331331
TypeError::ArgumentMutability(i) | TypeError::ArgumentSorts(_, i) => {
332-
if let Some(trait_ty) = trait_sig.inputs().get(*i) {
332+
if trait_sig.inputs().len() == *i {
333+
// Suggestion to change output type. We do not suggest in `async` functions
334+
// to avoid complex logic or incorrect output.
335+
let impl_m_hir_id =
336+
tcx.hir().local_def_id_to_hir_id(impl_m.def_id.expect_local());
337+
match tcx.hir().expect_impl_item(impl_m_hir_id).kind {
338+
ImplItemKind::Fn(ref sig, _)
339+
if sig.header.asyncness == hir::IsAsync::NotAsync =>
340+
{
341+
let (span, sugg) = match sig.decl.output {
342+
hir::FnRetTy::DefaultReturn(sp) => {
343+
(sp, format!(" -> {} ", trait_sig.output()))
344+
}
345+
hir::FnRetTy::Return(hir_ty) => {
346+
(hir_ty.span, trait_sig.output().to_string())
347+
}
348+
};
349+
diag.span_suggestion(
350+
span,
351+
"change the output type to match the trait",
352+
sugg,
353+
Applicability::MachineApplicable,
354+
);
355+
}
356+
_ => {}
357+
};
358+
} else if let Some(trait_ty) = trait_sig.inputs().get(*i) {
333359
diag.span_suggestion(
334360
impl_err_span,
335361
"change the parameter type to match the trait",

src/test/ui/associated-types/defaults-specialization.stderr

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ LL | fn make() -> Self::Ty {
1515
| -------- type in trait
1616
...
1717
LL | fn make() -> u8 { 0 }
18-
| ^^ expected associated type, found `u8`
18+
| ^^
19+
| |
20+
| expected associated type, found `u8`
21+
| help: change the output type to match the trait: `<A<T> as Tr>::Ty`
1922
|
2023
= note: expected fn pointer `fn() -> <A<T> as Tr>::Ty`
2124
found fn pointer `fn() -> u8`
@@ -30,7 +33,10 @@ LL | default type Ty = bool;
3033
| ----------------------- expected this associated type
3134
LL |
3235
LL | fn make() -> bool { true }
33-
| ^^^^ expected associated type, found `bool`
36+
| ^^^^
37+
| |
38+
| expected associated type, found `bool`
39+
| help: change the output type to match the trait: `<B<T> as Tr>::Ty`
3440
|
3541
= note: expected fn pointer `fn() -> <B<T> as Tr>::Ty`
3642
found fn pointer `fn() -> bool`

src/test/ui/compare-method/bad-self-type.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,12 @@ impl Future for MyFuture {
1515

1616
trait T {
1717
fn foo(self);
18+
fn bar(self) -> Option<()>;
1819
}
1920

2021
impl T for MyFuture {
2122
fn foo(self: Box<Self>) {}
2223
//~^ ERROR method `foo` has an incompatible type for trait
24+
fn bar(self) {}
25+
//~^ ERROR method `bar` has an incompatible type for trait
2326
}

src/test/ui/compare-method/bad-self-type.stderr

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ LL | fn poll(self, _: &mut Context<'_>) -> Poll<()> {
1111
found fn pointer `fn(MyFuture, &mut Context<'_>) -> Poll<_>`
1212

1313
error[E0053]: method `foo` has an incompatible type for trait
14-
--> $DIR/bad-self-type.rs:21:18
14+
--> $DIR/bad-self-type.rs:22:18
1515
|
1616
LL | fn foo(self);
1717
| ---- type in trait
@@ -25,6 +25,21 @@ LL | fn foo(self: Box<Self>) {}
2525
= note: expected fn pointer `fn(MyFuture)`
2626
found fn pointer `fn(Box<MyFuture>)`
2727

28-
error: aborting due to 2 previous errors
28+
error[E0053]: method `bar` has an incompatible type for trait
29+
--> $DIR/bad-self-type.rs:24:18
30+
|
31+
LL | fn bar(self) -> Option<()>;
32+
| ---------- type in trait
33+
...
34+
LL | fn bar(self) {}
35+
| ^
36+
| |
37+
| expected enum `Option`, found `()`
38+
| help: change the output type to match the trait: `-> Option<()>`
39+
|
40+
= note: expected fn pointer `fn(MyFuture) -> Option<()>`
41+
found fn pointer `fn(MyFuture)`
42+
43+
error: aborting due to 3 previous errors
2944

3045
For more information about this error, try `rustc --explain E0053`.

src/test/ui/issues/issue-21332.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ error[E0053]: method `next` has an incompatible type for trait
22
--> $DIR/issue-21332.rs:5:27
33
|
44
LL | fn next(&mut self) -> Result<i32, i32> { Ok(7) }
5-
| ^^^^^^^^^^^^^^^^ expected enum `Option`, found enum `Result`
5+
| ^^^^^^^^^^^^^^^^
6+
| |
7+
| expected enum `Option`, found enum `Result`
8+
| help: change the output type to match the trait: `Option<i32>`
69
|
710
= note: expected fn pointer `fn(&mut S) -> Option<i32>`
811
found fn pointer `fn(&mut S) -> Result<i32, i32>`

src/test/ui/issues/issue-35869.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ LL | fn qux() -> u8;
5050
| -- type in trait
5151
...
5252
LL | fn qux() -> u16 { 5u16 }
53-
| ^^^ expected `u8`, found `u16`
53+
| ^^^
54+
| |
55+
| expected `u8`, found `u16`
56+
| help: change the output type to match the trait: `u8`
5457
|
5558
= note: expected fn pointer `fn() -> u8`
5659
found fn pointer `fn() -> u16`

src/test/ui/wrong-mul-method-signature.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ error[E0053]: method `mul` has an incompatible type for trait
2626
--> $DIR/wrong-mul-method-signature.rs:52:29
2727
|
2828
LL | fn mul(self, s: f64) -> f64 {
29-
| ^^^ expected `i32`, found `f64`
29+
| ^^^
30+
| |
31+
| expected `i32`, found `f64`
32+
| help: change the output type to match the trait: `i32`
3033
|
3134
= note: expected fn pointer `fn(Vec3, _) -> i32`
3235
found fn pointer `fn(Vec3, _) -> f64`

0 commit comments

Comments
 (0)