Skip to content

Commit 5d086c3

Browse files
committed
Tweak E0308 error for clarity
1 parent f62f540 commit 5d086c3

17 files changed

+87
-72
lines changed

src/librustc_typeck/check/mod.rs

+50-32
Original file line numberDiff line numberDiff line change
@@ -4796,20 +4796,26 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
47964796
// `consider_hint_about_removing_semicolon` will point at the last expression
47974797
// if it were a relevant part of the error. This improves usability in editors
47984798
// that highlight errors inline.
4799-
let (sp, fn_span) = if let Some((decl, ident)) = self.get_parent_fn_decl(blk.id) {
4800-
(decl.output.span(), Some(ident.span))
4801-
} else {
4802-
(blk.span, None)
4803-
};
4799+
let mut sp = blk.span;
4800+
let mut fn_span = None;
4801+
if let Some((decl, ident)) = self.get_parent_fn_decl(blk.id) {
4802+
let ret_sp = decl.output.span();
4803+
if let Some(block_sp) = self.parent_item_span(blk.id) {
4804+
// HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
4805+
// output would otherwise be incorrect and even misleading. Make sure
4806+
// the span we're aiming at correspond to a `fn` body.
4807+
if block_sp == blk.span {
4808+
sp = ret_sp;
4809+
fn_span = Some(ident.span);
4810+
}
4811+
}
4812+
}
48044813
coerce.coerce_forced_unit(self, &self.misc(sp), &mut |err| {
48054814
if let Some(expected_ty) = expected.only_has_type(self) {
48064815
self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
48074816
}
48084817
if let Some(fn_span) = fn_span {
4809-
err.span_label(
4810-
fn_span,
4811-
"this function's body doesn't return the expected type",
4812-
);
4818+
err.span_label(fn_span, "this function's body doesn't return");
48134819
}
48144820
}, false);
48154821
}
@@ -4834,6 +4840,25 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
48344840
ty
48354841
}
48364842

4843+
fn parent_item_span(&self, id: ast::NodeId) -> Option<Span> {
4844+
let node = self.tcx.hir().get(self.tcx.hir().get_parent(id));
4845+
match node {
4846+
Node::Item(&hir::Item {
4847+
node: hir::ItemKind::Fn(_, _, _, body_id), ..
4848+
}) |
4849+
Node::ImplItem(&hir::ImplItem {
4850+
node: hir::ImplItemKind::Method(_, body_id), ..
4851+
}) => {
4852+
let body = self.tcx.hir().body(body_id);
4853+
if let ExprKind::Block(block, _) = &body.value.node {
4854+
return Some(block.span);
4855+
}
4856+
}
4857+
_ => {}
4858+
}
4859+
None
4860+
}
4861+
48374862
/// Given a function block's `NodeId`, return its `FnDecl` , `None` otherwise.
48384863
fn get_parent_fn_decl(&self, blk_id: ast::NodeId) -> Option<(hir::FnDecl, ast::Ident)> {
48394864
let parent = self.tcx.hir().get(self.tcx.hir().get_parent(blk_id));
@@ -4842,33 +4867,26 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
48424867

48434868
/// Given a function `Node`, return its `FnDecl` , `None` otherwise.
48444869
fn get_node_fn_decl(&self, node: Node) -> Option<(hir::FnDecl, ast::Ident, bool)> {
4845-
if let Node::Item(&hir::Item {
4846-
ident, node: hir::ItemKind::Fn(ref decl, ..), ..
4847-
}) = node {
4848-
decl.clone().and_then(|decl| {
4870+
match node {
4871+
Node::Item(&hir::Item {
4872+
ident, node: hir::ItemKind::Fn(ref decl, ..), ..
4873+
}) => decl.clone().and_then(|decl| {
48494874
// This is less than ideal, it will not suggest a return type span on any
48504875
// method called `main`, regardless of whether it is actually the entry point,
48514876
// but it will still present it as the reason for the expected type.
48524877
Some((decl, ident, ident.name != Symbol::intern("main")))
4853-
})
4854-
} else if let Node::TraitItem(&hir::TraitItem {
4855-
ident, node: hir::TraitItemKind::Method(hir::MethodSig {
4856-
ref decl, ..
4857-
}, ..), ..
4858-
}) = node {
4859-
decl.clone().and_then(|decl| {
4860-
Some((decl, ident, true))
4861-
})
4862-
} else if let Node::ImplItem(&hir::ImplItem {
4863-
ident, node: hir::ImplItemKind::Method(hir::MethodSig {
4864-
ref decl, ..
4865-
}, ..), ..
4866-
}) = node {
4867-
decl.clone().and_then(|decl| {
4868-
Some((decl, ident, false))
4869-
})
4870-
} else {
4871-
None
4878+
}),
4879+
Node::TraitItem(&hir::TraitItem {
4880+
ident, node: hir::TraitItemKind::Method(hir::MethodSig {
4881+
ref decl, ..
4882+
}, ..), ..
4883+
}) => decl.clone().and_then(|decl| Some((decl, ident, true))),
4884+
Node::ImplItem(&hir::ImplItem {
4885+
ident, node: hir::ImplItemKind::Method(hir::MethodSig {
4886+
ref decl, ..
4887+
}, ..), ..
4888+
}) => decl.clone().and_then(|decl| Some((decl, ident, false))),
4889+
_ => None,
48724890
}
48734891
}
48744892

src/test/ui/block-result/consider-removing-last-semi.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0308]: mismatched types
44
LL | fn f() -> String { //~ ERROR mismatched types
55
| - ^^^^^^ expected struct `std::string::String`, found ()
66
| |
7-
| this function's body doesn't return the expected type
7+
| this function's body doesn't return
88
LL | 0u8;
99
LL | "bla".to_string();
1010
| - help: consider removing this semicolon
@@ -18,7 +18,7 @@ error[E0308]: mismatched types
1818
LL | fn g() -> String { //~ ERROR mismatched types
1919
| - ^^^^^^ expected struct `std::string::String`, found ()
2020
| |
21-
| this function's body doesn't return the expected type
21+
| this function's body doesn't return
2222
LL | "this won't work".to_string();
2323
LL | "removeme".to_string();
2424
| - help: consider removing this semicolon

src/test/ui/block-result/issue-11714.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0308]: mismatched types
44
LL | fn blah() -> i32 { //~ ERROR mismatched types
55
| ---- ^^^ expected i32, found ()
66
| |
7-
| this function's body doesn't return the expected type
7+
| this function's body doesn't return
88
...
99
LL | ;
1010
| - help: consider removing this semicolon

src/test/ui/block-result/issue-13428.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0308]: mismatched types
44
LL | fn foo() -> String { //~ ERROR mismatched types
55
| --- ^^^^^^ expected struct `std::string::String`, found ()
66
| |
7-
| this function's body doesn't return the expected type
7+
| this function's body doesn't return
88
...
99
LL | ;
1010
| - help: consider removing this semicolon
@@ -18,7 +18,7 @@ error[E0308]: mismatched types
1818
LL | fn bar() -> String { //~ ERROR mismatched types
1919
| --- ^^^^^^ expected struct `std::string::String`, found ()
2020
| |
21-
| this function's body doesn't return the expected type
21+
| this function's body doesn't return
2222
LL | "foobar".to_string()
2323
LL | ;
2424
| - help: consider removing this semicolon

src/test/ui/break-while-condition.stderr

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
error[E0308]: mismatched types
2-
--> $DIR/break-while-condition.rs:3:11
2+
--> $DIR/break-while-condition.rs:9:20
33
|
4-
LL | fn main() {
5-
| ---- ^ expected !, found ()
6-
| |
7-
| this function's body doesn't return the expected type
4+
LL | let _: ! = { //~ ERROR mismatched types
5+
| ____________________^
6+
LL | | 'a: while break 'a {};
7+
LL | | };
8+
| |_________^ expected !, found ()
89
|
910
= note: expected type `!`
1011
found type `()`

src/test/ui/coercion/coercion-missing-tail-expected-type.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0308]: mismatched types
44
LL | fn plus_one(x: i32) -> i32 { //~ ERROR mismatched types
55
| -------- ^^^ expected i32, found ()
66
| |
7-
| this function's body doesn't return the expected type
7+
| this function's body doesn't return
88
LL | x + 1;
99
| - help: consider removing this semicolon
1010
|
@@ -17,7 +17,7 @@ error[E0308]: mismatched types
1717
LL | fn foo() -> Result<u8, u64> { //~ ERROR mismatched types
1818
| --- ^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
1919
| |
20-
| this function's body doesn't return the expected type
20+
| this function's body doesn't return
2121
LL | Ok(1);
2222
| - help: consider removing this semicolon
2323
|

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

+3-5
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,10 @@ LL | assert!({one! two()});
1717
| ^^^
1818

1919
error[E0308]: mismatched types
20-
--> $DIR/issue-10536.rs:11:15
20+
--> $DIR/issue-10536.rs:14:13
2121
|
22-
LL | pub fn main() {
23-
| ---- ^ expected bool, found ()
24-
| |
25-
| this function's body doesn't return the expected type
22+
LL | assert!({one! two()});
23+
| ^^^^^^^^^^^^ expected bool, found ()
2624
|
2725
= note: expected type `bool`
2826
found type `()`

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0308]: mismatched types
44
LL | pub fn f<'a, T: Tr<'a>>() -> <T as Tr<'a>>::Out {}
55
| - ^^^^^^^^^^^^^^^^^^ expected associated type, found ()
66
| |
7-
| this function's body doesn't return the expected type
7+
| this function's body doesn't return
88
|
99
= note: expected type `<T as Tr<'a>>::Out`
1010
found type `()`

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ error[E0308]: mismatched types
1616
LL | fn foo() -> bool {
1717
| --- ^^^^ expected bool, found ()
1818
| |
19-
| this function's body doesn't return the expected type
19+
| this function's body doesn't return
2020
LL | //~^ ERROR E0308
2121
LL | break true; //~ ERROR E0268
2222
| - help: consider removing this semicolon

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0308]: mismatched types
44
LL | fn საჭმელად_გემრიელი_სადილი ( ) -> isize { //~ ERROR mismatched types
55
| ------------------------ ^^^^^ expected isize, found ()
66
| |
7-
| this function's body doesn't return the expected type
7+
| this function's body doesn't return
88
|
99
= note: expected type `isize`
1010
found type `()`

src/test/ui/issues/issue-6458-4.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0308]: mismatched types
44
LL | fn foo(b: bool) -> Result<bool,String> { //~ ERROR mismatched types
55
| --- ^^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
66
| |
7-
| this function's body doesn't return the expected type
7+
| this function's body doesn't return
88
LL | Err("bar".to_string());
99
| - help: consider removing this semicolon
1010
|

src/test/ui/liveness/liveness-closure-require-ret.stderr

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
error[E0308]: mismatched types
2-
--> $DIR/liveness-closure-require-ret.rs:2:11
2+
--> $DIR/liveness-closure-require-ret.rs:2:37
33
|
44
LL | fn main() { println!("{}", force(|| {})); } //~ ERROR mismatched types
5-
| ---- ^ expected isize, found ()
6-
| |
7-
| this function's body doesn't return the expected type
5+
| ^^ expected isize, found ()
86
|
97
= note: expected type `isize`
108
found type `()`

src/test/ui/liveness/liveness-forgot-ret.stderr

+3-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ error[E0308]: mismatched types
22
--> $DIR/liveness-forgot-ret.rs:3:19
33
|
44
LL | fn f(a: isize) -> isize { if god_exists(a) { return 5; }; }
5-
| - ^^^^^ - expected because of this statement
6-
| | |
7-
| | expected isize, found ()
8-
| this function's body doesn't return the expected type
5+
| - ^^^^^ expected isize, found () - expected because of this statement
6+
| |
7+
| this function's body doesn't return
98
|
109
= note: expected type `isize`
1110
found type `()`

src/test/ui/liveness/liveness-issue-2163.stderr

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
error[E0308]: mismatched types
2-
--> $DIR/liveness-issue-2163.rs:3:11
2+
--> $DIR/liveness-issue-2163.rs:5:30
33
|
4-
LL | fn main() {
5-
| ---- ^ expected bool, found ()
6-
| |
7-
| this function's body doesn't return the expected type
4+
LL | a.iter().all(|_| -> bool {
5+
| ______________________________^
6+
LL | | //~^ ERROR mismatched types
7+
LL | | });
8+
| |_____^ expected bool, found ()
89
|
910
= note: expected type `bool`
1011
found type `()`

src/test/ui/liveness/liveness-missing-ret2.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0308]: mismatched types
44
LL | fn f() -> isize { //~ ERROR mismatched types
55
| - ^^^^^ expected isize, found ()
66
| |
7-
| this function's body doesn't return the expected type
7+
| this function's body doesn't return
88
|
99
= note: expected type `isize`
1010
found type `()`

src/test/ui/liveness/liveness-return-last-stmt-semi.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | macro_rules! test { () => { fn foo() -> i32 { 1; } } }
55
| --- ^^^ - help: consider removing this semicolon
66
| | |
77
| | expected i32, found ()
8-
| this function's body doesn't return the expected type
8+
| this function's body doesn't return
99
...
1010
LL | test!();
1111
| -------- in this macro invocation
@@ -19,7 +19,7 @@ error[E0308]: mismatched types
1919
LL | fn no_return() -> i32 {} //~ ERROR mismatched types
2020
| --------- ^^^ expected i32, found ()
2121
| |
22-
| this function's body doesn't return the expected type
22+
| this function's body doesn't return
2323
|
2424
= note: expected type `i32`
2525
found type `()`
@@ -30,7 +30,7 @@ error[E0308]: mismatched types
3030
LL | fn bar(x: u32) -> u32 { //~ ERROR mismatched types
3131
| --- ^^^ expected u32, found ()
3232
| |
33-
| this function's body doesn't return the expected type
33+
| this function's body doesn't return
3434
LL | x * 2;
3535
| - help: consider removing this semicolon
3636
|
@@ -43,7 +43,7 @@ error[E0308]: mismatched types
4343
LL | fn baz(x: u64) -> u32 { //~ ERROR mismatched types
4444
| --- ^^^ expected u32, found ()
4545
| |
46-
| this function's body doesn't return the expected type
46+
| this function's body doesn't return
4747
|
4848
= note: expected type `u32`
4949
found type `()`

src/test/ui/missing/missing-return.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0308]: mismatched types
44
LL | fn f() -> isize { }
55
| - ^^^^^ expected isize, found ()
66
| |
7-
| this function's body doesn't return the expected type
7+
| this function's body doesn't return
88
|
99
= note: expected type `isize`
1010
found type `()`

0 commit comments

Comments
 (0)