diff options
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 82 | ||||
| -rw-r--r-- | src/test/ui/block-result/consider-removing-last-semi.stderr | 4 | ||||
| -rw-r--r-- | src/test/ui/block-result/issue-11714.stderr | 2 | ||||
| -rw-r--r-- | src/test/ui/block-result/issue-13428.stderr | 4 | ||||
| -rw-r--r-- | src/test/ui/break-while-condition.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/coercion/coercion-missing-tail-expected-type.stderr | 4 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-10536.stderr | 8 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-32323.stderr | 2 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-43162.stderr | 2 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-44023.stderr | 2 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-6458-4.stderr | 2 | ||||
| -rw-r--r-- | src/test/ui/liveness/liveness-closure-require-ret.stderr | 6 | ||||
| -rw-r--r-- | src/test/ui/liveness/liveness-forgot-ret.stderr | 7 | ||||
| -rw-r--r-- | src/test/ui/liveness/liveness-issue-2163.stderr | 11 | ||||
| -rw-r--r-- | src/test/ui/liveness/liveness-missing-ret2.stderr | 2 | ||||
| -rw-r--r-- | src/test/ui/liveness/liveness-return-last-stmt-semi.stderr | 8 | ||||
| -rw-r--r-- | src/test/ui/missing/missing-return.stderr | 2 |
17 files changed, 87 insertions, 72 deletions
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 381abcb977b..9492b1a2341 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4796,20 +4796,26 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // `consider_hint_about_removing_semicolon` will point at the last expression // if it were a relevant part of the error. This improves usability in editors // that highlight errors inline. - let (sp, fn_span) = if let Some((decl, ident)) = self.get_parent_fn_decl(blk.id) { - (decl.output.span(), Some(ident.span)) - } else { - (blk.span, None) - }; + let mut sp = blk.span; + let mut fn_span = None; + if let Some((decl, ident)) = self.get_parent_fn_decl(blk.id) { + let ret_sp = decl.output.span(); + if let Some(block_sp) = self.parent_item_span(blk.id) { + // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the + // output would otherwise be incorrect and even misleading. Make sure + // the span we're aiming at correspond to a `fn` body. + if block_sp == blk.span { + sp = ret_sp; + fn_span = Some(ident.span); + } + } + } coerce.coerce_forced_unit(self, &self.misc(sp), &mut |err| { if let Some(expected_ty) = expected.only_has_type(self) { self.consider_hint_about_removing_semicolon(blk, expected_ty, err); } if let Some(fn_span) = fn_span { - err.span_label( - fn_span, - "this function's body doesn't return the expected type", - ); + err.span_label(fn_span, "this function's body doesn't return"); } }, false); } @@ -4834,6 +4840,25 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty } + fn parent_item_span(&self, id: ast::NodeId) -> Option<Span> { + let node = self.tcx.hir().get(self.tcx.hir().get_parent(id)); + match node { + Node::Item(&hir::Item { + node: hir::ItemKind::Fn(_, _, _, body_id), .. + }) | + Node::ImplItem(&hir::ImplItem { + node: hir::ImplItemKind::Method(_, body_id), .. + }) => { + let body = self.tcx.hir().body(body_id); + if let ExprKind::Block(block, _) = &body.value.node { + return Some(block.span); + } + } + _ => {} + } + None + } + /// Given a function block's `NodeId`, return its `FnDecl` , `None` otherwise. fn get_parent_fn_decl(&self, blk_id: ast::NodeId) -> Option<(hir::FnDecl, ast::Ident)> { 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> { /// Given a function `Node`, return its `FnDecl` , `None` otherwise. fn get_node_fn_decl(&self, node: Node) -> Option<(hir::FnDecl, ast::Ident, bool)> { - if let Node::Item(&hir::Item { - ident, node: hir::ItemKind::Fn(ref decl, ..), .. - }) = node { - decl.clone().and_then(|decl| { + match node { + Node::Item(&hir::Item { + ident, node: hir::ItemKind::Fn(ref decl, ..), .. + }) => decl.clone().and_then(|decl| { // This is less than ideal, it will not suggest a return type span on any // method called `main`, regardless of whether it is actually the entry point, // but it will still present it as the reason for the expected type. Some((decl, ident, ident.name != Symbol::intern("main"))) - }) - } else if let Node::TraitItem(&hir::TraitItem { - ident, node: hir::TraitItemKind::Method(hir::MethodSig { - ref decl, .. - }, ..), .. - }) = node { - decl.clone().and_then(|decl| { - Some((decl, ident, true)) - }) - } else if let Node::ImplItem(&hir::ImplItem { - ident, node: hir::ImplItemKind::Method(hir::MethodSig { - ref decl, .. - }, ..), .. - }) = node { - decl.clone().and_then(|decl| { - Some((decl, ident, false)) - }) - } else { - None + }), + Node::TraitItem(&hir::TraitItem { + ident, node: hir::TraitItemKind::Method(hir::MethodSig { + ref decl, .. + }, ..), .. + }) => decl.clone().and_then(|decl| Some((decl, ident, true))), + Node::ImplItem(&hir::ImplItem { + ident, node: hir::ImplItemKind::Method(hir::MethodSig { + ref decl, .. + }, ..), .. + }) => decl.clone().and_then(|decl| Some((decl, ident, false))), + _ => None, } } diff --git a/src/test/ui/block-result/consider-removing-last-semi.stderr b/src/test/ui/block-result/consider-removing-last-semi.stderr index 79e7a536cdc..1bf17db21ac 100644 --- a/src/test/ui/block-result/consider-removing-last-semi.stderr +++ b/src/test/ui/block-result/consider-removing-last-semi.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn f() -> String { //~ ERROR mismatched types | - ^^^^^^ expected struct `std::string::String`, found () | | - | this function's body doesn't return the expected type + | this function's body doesn't return LL | 0u8; LL | "bla".to_string(); | - help: consider removing this semicolon @@ -18,7 +18,7 @@ error[E0308]: mismatched types LL | fn g() -> String { //~ ERROR mismatched types | - ^^^^^^ expected struct `std::string::String`, found () | | - | this function's body doesn't return the expected type + | this function's body doesn't return LL | "this won't work".to_string(); LL | "removeme".to_string(); | - help: consider removing this semicolon diff --git a/src/test/ui/block-result/issue-11714.stderr b/src/test/ui/block-result/issue-11714.stderr index 82253911316..2c13b287669 100644 --- a/src/test/ui/block-result/issue-11714.stderr +++ b/src/test/ui/block-result/issue-11714.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn blah() -> i32 { //~ ERROR mismatched types | ---- ^^^ expected i32, found () | | - | this function's body doesn't return the expected type + | this function's body doesn't return ... LL | ; | - help: consider removing this semicolon diff --git a/src/test/ui/block-result/issue-13428.stderr b/src/test/ui/block-result/issue-13428.stderr index 8b8eb825377..91e926eb5a7 100644 --- a/src/test/ui/block-result/issue-13428.stderr +++ b/src/test/ui/block-result/issue-13428.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn foo() -> String { //~ ERROR mismatched types | --- ^^^^^^ expected struct `std::string::String`, found () | | - | this function's body doesn't return the expected type + | this function's body doesn't return ... LL | ; | - help: consider removing this semicolon @@ -18,7 +18,7 @@ error[E0308]: mismatched types LL | fn bar() -> String { //~ ERROR mismatched types | --- ^^^^^^ expected struct `std::string::String`, found () | | - | this function's body doesn't return the expected type + | this function's body doesn't return LL | "foobar".to_string() LL | ; | - help: consider removing this semicolon diff --git a/src/test/ui/break-while-condition.stderr b/src/test/ui/break-while-condition.stderr index 6709747b137..3e81753a410 100644 --- a/src/test/ui/break-while-condition.stderr +++ b/src/test/ui/break-while-condition.stderr @@ -1,10 +1,11 @@ error[E0308]: mismatched types - --> $DIR/break-while-condition.rs:3:11 + --> $DIR/break-while-condition.rs:9:20 | -LL | fn main() { - | ---- ^ expected !, found () - | | - | this function's body doesn't return the expected type +LL | let _: ! = { //~ ERROR mismatched types + | ____________________^ +LL | | 'a: while break 'a {}; +LL | | }; + | |_________^ expected !, found () | = note: expected type `!` found type `()` diff --git a/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr b/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr index 9ace5b8ad3a..c8ec2f0545e 100644 --- a/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr +++ b/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn plus_one(x: i32) -> i32 { //~ ERROR mismatched types | -------- ^^^ expected i32, found () | | - | this function's body doesn't return the expected type + | this function's body doesn't return LL | x + 1; | - help: consider removing this semicolon | @@ -17,7 +17,7 @@ error[E0308]: mismatched types LL | fn foo() -> Result<u8, u64> { //~ ERROR mismatched types | --- ^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found () | | - | this function's body doesn't return the expected type + | this function's body doesn't return LL | Ok(1); | - help: consider removing this semicolon | diff --git a/src/test/ui/issues/issue-10536.stderr b/src/test/ui/issues/issue-10536.stderr index 02008470e63..d5caf777cd4 100644 --- a/src/test/ui/issues/issue-10536.stderr +++ b/src/test/ui/issues/issue-10536.stderr @@ -17,12 +17,10 @@ LL | assert!({one! two()}); | ^^^ error[E0308]: mismatched types - --> $DIR/issue-10536.rs:11:15 + --> $DIR/issue-10536.rs:14:13 | -LL | pub fn main() { - | ---- ^ expected bool, found () - | | - | this function's body doesn't return the expected type +LL | assert!({one! two()}); + | ^^^^^^^^^^^^ expected bool, found () | = note: expected type `bool` found type `()` diff --git a/src/test/ui/issues/issue-32323.stderr b/src/test/ui/issues/issue-32323.stderr index bef3596103c..0339fdc55b9 100644 --- a/src/test/ui/issues/issue-32323.stderr +++ b/src/test/ui/issues/issue-32323.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | pub fn f<'a, T: Tr<'a>>() -> <T as Tr<'a>>::Out {} | - ^^^^^^^^^^^^^^^^^^ expected associated type, found () | | - | this function's body doesn't return the expected type + | this function's body doesn't return | = note: expected type `<T as Tr<'a>>::Out` found type `()` diff --git a/src/test/ui/issues/issue-43162.stderr b/src/test/ui/issues/issue-43162.stderr index 4d2b3549f8e..3fc5317830e 100644 --- a/src/test/ui/issues/issue-43162.stderr +++ b/src/test/ui/issues/issue-43162.stderr @@ -16,7 +16,7 @@ error[E0308]: mismatched types LL | fn foo() -> bool { | --- ^^^^ expected bool, found () | | - | this function's body doesn't return the expected type + | this function's body doesn't return LL | //~^ ERROR E0308 LL | break true; //~ ERROR E0268 | - help: consider removing this semicolon diff --git a/src/test/ui/issues/issue-44023.stderr b/src/test/ui/issues/issue-44023.stderr index 944098a644d..f1962a86ee0 100644 --- a/src/test/ui/issues/issue-44023.stderr +++ b/src/test/ui/issues/issue-44023.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn საჭმელად_გემრიელი_სადილი ( ) -> isize { //~ ERROR mismatched types | ------------------------ ^^^^^ expected isize, found () | | - | this function's body doesn't return the expected type + | this function's body doesn't return | = note: expected type `isize` found type `()` diff --git a/src/test/ui/issues/issue-6458-4.stderr b/src/test/ui/issues/issue-6458-4.stderr index f4cdceac172..c087292e978 100644 --- a/src/test/ui/issues/issue-6458-4.stderr +++ b/src/test/ui/issues/issue-6458-4.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn foo(b: bool) -> Result<bool,String> { //~ ERROR mismatched types | --- ^^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found () | | - | this function's body doesn't return the expected type + | this function's body doesn't return LL | Err("bar".to_string()); | - help: consider removing this semicolon | diff --git a/src/test/ui/liveness/liveness-closure-require-ret.stderr b/src/test/ui/liveness/liveness-closure-require-ret.stderr index d7992704c50..3133efdedd7 100644 --- a/src/test/ui/liveness/liveness-closure-require-ret.stderr +++ b/src/test/ui/liveness/liveness-closure-require-ret.stderr @@ -1,10 +1,8 @@ error[E0308]: mismatched types - --> $DIR/liveness-closure-require-ret.rs:2:11 + --> $DIR/liveness-closure-require-ret.rs:2:37 | LL | fn main() { println!("{}", force(|| {})); } //~ ERROR mismatched types - | ---- ^ expected isize, found () - | | - | this function's body doesn't return the expected type + | ^^ expected isize, found () | = note: expected type `isize` found type `()` diff --git a/src/test/ui/liveness/liveness-forgot-ret.stderr b/src/test/ui/liveness/liveness-forgot-ret.stderr index 578890f5e62..bbcbbdbe8dd 100644 --- a/src/test/ui/liveness/liveness-forgot-ret.stderr +++ b/src/test/ui/liveness/liveness-forgot-ret.stderr @@ -2,10 +2,9 @@ error[E0308]: mismatched types --> $DIR/liveness-forgot-ret.rs:3:19 | LL | fn f(a: isize) -> isize { if god_exists(a) { return 5; }; } - | - ^^^^^ - expected because of this statement - | | | - | | expected isize, found () - | this function's body doesn't return the expected type + | - ^^^^^ expected isize, found () - expected because of this statement + | | + | this function's body doesn't return | = note: expected type `isize` found type `()` diff --git a/src/test/ui/liveness/liveness-issue-2163.stderr b/src/test/ui/liveness/liveness-issue-2163.stderr index a8a56842076..e91994d9a22 100644 --- a/src/test/ui/liveness/liveness-issue-2163.stderr +++ b/src/test/ui/liveness/liveness-issue-2163.stderr @@ -1,10 +1,11 @@ error[E0308]: mismatched types - --> $DIR/liveness-issue-2163.rs:3:11 + --> $DIR/liveness-issue-2163.rs:5:30 | -LL | fn main() { - | ---- ^ expected bool, found () - | | - | this function's body doesn't return the expected type +LL | a.iter().all(|_| -> bool { + | ______________________________^ +LL | | //~^ ERROR mismatched types +LL | | }); + | |_____^ expected bool, found () | = note: expected type `bool` found type `()` diff --git a/src/test/ui/liveness/liveness-missing-ret2.stderr b/src/test/ui/liveness/liveness-missing-ret2.stderr index 201b3ee6861..58d0249ee3b 100644 --- a/src/test/ui/liveness/liveness-missing-ret2.stderr +++ b/src/test/ui/liveness/liveness-missing-ret2.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn f() -> isize { //~ ERROR mismatched types | - ^^^^^ expected isize, found () | | - | this function's body doesn't return the expected type + | this function's body doesn't return | = note: expected type `isize` found type `()` diff --git a/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr b/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr index 2ee77f30a66..c6d166d8b31 100644 --- a/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr +++ b/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr @@ -5,7 +5,7 @@ LL | macro_rules! test { () => { fn foo() -> i32 { 1; } } } | --- ^^^ - help: consider removing this semicolon | | | | | expected i32, found () - | this function's body doesn't return the expected type + | this function's body doesn't return ... LL | test!(); | -------- in this macro invocation @@ -19,7 +19,7 @@ error[E0308]: mismatched types LL | fn no_return() -> i32 {} //~ ERROR mismatched types | --------- ^^^ expected i32, found () | | - | this function's body doesn't return the expected type + | this function's body doesn't return | = note: expected type `i32` found type `()` @@ -30,7 +30,7 @@ error[E0308]: mismatched types LL | fn bar(x: u32) -> u32 { //~ ERROR mismatched types | --- ^^^ expected u32, found () | | - | this function's body doesn't return the expected type + | this function's body doesn't return LL | x * 2; | - help: consider removing this semicolon | @@ -43,7 +43,7 @@ error[E0308]: mismatched types LL | fn baz(x: u64) -> u32 { //~ ERROR mismatched types | --- ^^^ expected u32, found () | | - | this function's body doesn't return the expected type + | this function's body doesn't return | = note: expected type `u32` found type `()` diff --git a/src/test/ui/missing/missing-return.stderr b/src/test/ui/missing/missing-return.stderr index 9e6ffd97312..42466e2fc65 100644 --- a/src/test/ui/missing/missing-return.stderr +++ b/src/test/ui/missing/missing-return.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn f() -> isize { } | - ^^^^^ expected isize, found () | | - | this function's body doesn't return the expected type + | this function's body doesn't return | = note: expected type `isize` found type `()` |
