From 1f65dc07705e9463ffed0395894f1e7d63cec515 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 30 Dec 2018 13:55:00 -0800 Subject: [PATCH 1/4] Point at the return type span on type mismatch due to missing return Do not point at the entire block span on fn return type mismatches caused by missing return. --- src/librustc/hir/map/mod.rs | 3 +- src/librustc_typeck/check/mod.rs | 12 ++++++- .../consider-removing-last-semi.stderr | 28 +++++++-------- src/test/ui/block-result/issue-11714.stderr | 15 ++++---- src/test/ui/block-result/issue-13428.stderr | 31 +++++++---------- src/test/ui/break-while-condition.stderr | 9 ++--- ...coercion-missing-tail-expected-type.stderr | 24 ++++++------- src/test/ui/issues/issue-10536.stderr | 6 ++-- src/test/ui/issues/issue-32323.stderr | 4 +-- src/test/ui/issues/issue-43162.stderr | 14 ++++---- src/test/ui/issues/issue-44023.stderr | 8 ++--- src/test/ui/issues/issue-6458-4.stderr | 12 +++---- .../ui/liveness/liveness-forgot-ret.stderr | 4 +-- .../ui/liveness/liveness-missing-ret2.stderr | 11 ++---- .../liveness-return-last-stmt-semi.stderr | 34 ++++++++----------- src/test/ui/missing/missing-return.stderr | 4 +-- 16 files changed, 96 insertions(+), 123 deletions(-) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 188d487d64485..5bcbeeefa5030 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -667,6 +667,7 @@ impl<'hir> Map<'hir> { Node::Item(_) | Node::ForeignItem(_) | Node::TraitItem(_) | + Node::Expr(Expr { node: ExprKind::Closure(..), ..}) | Node::ImplItem(_) => true, _ => false, } @@ -675,7 +676,7 @@ impl<'hir> Map<'hir> { match *node { Node::Expr(ref expr) => { match expr.node { - ExprKind::While(..) | ExprKind::Loop(..) => true, + ExprKind::While(..) | ExprKind::Loop(..) | ExprKind::Ret(..) => true, _ => false, } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 39beb2832851b..aa13087b484ac 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4791,7 +4791,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // #41425 -- label the implicit `()` as being the // "found type" here, rather than the "expected type". if !self.diverges.get().always() { - coerce.coerce_forced_unit(self, &self.misc(blk.span), &mut |err| { + // #50009 -- Do not point at the entire fn block span, point at the return type + // span, as it is the cause of the requirement, and + // `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 = if let Some((decl, _)) = self.get_fn_decl(blk.id) { + decl.output.span() + } else { + blk.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, 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 870da00680f42..ce8c624cdad45 100644 --- a/src/test/ui/block-result/consider-removing-last-semi.stderr +++ b/src/test/ui/block-result/consider-removing-last-semi.stderr @@ -1,27 +1,23 @@ error[E0308]: mismatched types - --> $DIR/consider-removing-last-semi.rs:1:18 + --> $DIR/consider-removing-last-semi.rs:1:11 | -LL | fn f() -> String { //~ ERROR mismatched types - | __________________^ -LL | | 0u8; -LL | | "bla".to_string(); - | | - help: consider removing this semicolon -LL | | } - | |_^ expected struct `std::string::String`, found () +LL | fn f() -> String { //~ ERROR mismatched types + | ^^^^^^ expected struct `std::string::String`, found () +LL | 0u8; +LL | "bla".to_string(); + | - help: consider removing this semicolon | = note: expected type `std::string::String` found type `()` error[E0308]: mismatched types - --> $DIR/consider-removing-last-semi.rs:6:18 + --> $DIR/consider-removing-last-semi.rs:6:11 | -LL | fn g() -> String { //~ ERROR mismatched types - | __________________^ -LL | | "this won't work".to_string(); -LL | | "removeme".to_string(); - | | - help: consider removing this semicolon -LL | | } - | |_^ expected struct `std::string::String`, found () +LL | fn g() -> String { //~ ERROR mismatched types + | ^^^^^^ expected struct `std::string::String`, found () +LL | "this won't work".to_string(); +LL | "removeme".to_string(); + | - help: consider removing this semicolon | = note: expected type `std::string::String` found type `()` diff --git a/src/test/ui/block-result/issue-11714.stderr b/src/test/ui/block-result/issue-11714.stderr index 8bb37395c5cca..cc97eaf8e1ac3 100644 --- a/src/test/ui/block-result/issue-11714.stderr +++ b/src/test/ui/block-result/issue-11714.stderr @@ -1,14 +1,11 @@ error[E0308]: mismatched types - --> $DIR/issue-11714.rs:1:18 + --> $DIR/issue-11714.rs:1:14 | -LL | fn blah() -> i32 { //~ ERROR mismatched types - | __________________^ -LL | | 1 -LL | | -LL | | ; - | | - help: consider removing this semicolon -LL | | } - | |_^ expected i32, found () +LL | fn blah() -> i32 { //~ ERROR mismatched types + | ^^^ expected i32, found () +... +LL | ; + | - help: consider removing this semicolon | = note: expected type `i32` found type `()` diff --git a/src/test/ui/block-result/issue-13428.stderr b/src/test/ui/block-result/issue-13428.stderr index 516baa8e5f104..d3a2b5131371e 100644 --- a/src/test/ui/block-result/issue-13428.stderr +++ b/src/test/ui/block-result/issue-13428.stderr @@ -1,30 +1,23 @@ error[E0308]: mismatched types - --> $DIR/issue-13428.rs:3:20 + --> $DIR/issue-13428.rs:3:13 | -LL | fn foo() -> String { //~ ERROR mismatched types - | ____________________^ -LL | | format!("Hello {}", -LL | | "world") -LL | | // Put the trailing semicolon on its own line to test that the -LL | | // note message gets the offending semicolon exactly -LL | | ; - | | - help: consider removing this semicolon -LL | | } - | |_^ expected struct `std::string::String`, found () +LL | fn foo() -> String { //~ ERROR mismatched types + | ^^^^^^ expected struct `std::string::String`, found () +... +LL | ; + | - help: consider removing this semicolon | = note: expected type `std::string::String` found type `()` error[E0308]: mismatched types - --> $DIR/issue-13428.rs:11:20 + --> $DIR/issue-13428.rs:11:13 | -LL | fn bar() -> String { //~ ERROR mismatched types - | ____________________^ -LL | | "foobar".to_string() -LL | | ; - | | - help: consider removing this semicolon -LL | | } - | |_^ expected struct `std::string::String`, found () +LL | fn bar() -> String { //~ ERROR mismatched types + | ^^^^^^ expected struct `std::string::String`, found () +LL | "foobar".to_string() +LL | ; + | - help: consider removing this semicolon | = note: expected type `std::string::String` found type `()` diff --git a/src/test/ui/break-while-condition.stderr b/src/test/ui/break-while-condition.stderr index 3e81753a4105f..1c48ad630d8b7 100644 --- a/src/test/ui/break-while-condition.stderr +++ b/src/test/ui/break-while-condition.stderr @@ -1,11 +1,8 @@ error[E0308]: mismatched types - --> $DIR/break-while-condition.rs:9:20 + --> $DIR/break-while-condition.rs:3:11 | -LL | let _: ! = { //~ ERROR mismatched types - | ____________________^ -LL | | 'a: while break 'a {}; -LL | | }; - | |_________^ expected !, found () +LL | fn main() { + | ^ 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 18adf9a46cc84..27f0540e36e94 100644 --- a/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr +++ b/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr @@ -1,25 +1,21 @@ error[E0308]: mismatched types - --> $DIR/coercion-missing-tail-expected-type.rs:3:28 + --> $DIR/coercion-missing-tail-expected-type.rs:3:24 | -LL | fn plus_one(x: i32) -> i32 { //~ ERROR mismatched types - | ____________________________^ -LL | | x + 1; - | | - help: consider removing this semicolon -LL | | } - | |_^ expected i32, found () +LL | fn plus_one(x: i32) -> i32 { //~ ERROR mismatched types + | ^^^ expected i32, found () +LL | x + 1; + | - help: consider removing this semicolon | = note: expected type `i32` found type `()` error[E0308]: mismatched types - --> $DIR/coercion-missing-tail-expected-type.rs:7:29 + --> $DIR/coercion-missing-tail-expected-type.rs:7:13 | -LL | fn foo() -> Result { //~ ERROR mismatched types - | _____________________________^ -LL | | Ok(1); - | | - help: consider removing this semicolon -LL | | } - | |_^ expected enum `std::result::Result`, found () +LL | fn foo() -> Result { //~ ERROR mismatched types + | ^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found () +LL | Ok(1); + | - help: consider removing this semicolon | = note: expected type `std::result::Result` found type `()` diff --git a/src/test/ui/issues/issue-10536.stderr b/src/test/ui/issues/issue-10536.stderr index d5caf777cd45e..71f9a83316c1c 100644 --- a/src/test/ui/issues/issue-10536.stderr +++ b/src/test/ui/issues/issue-10536.stderr @@ -17,10 +17,10 @@ LL | assert!({one! two()}); | ^^^ error[E0308]: mismatched types - --> $DIR/issue-10536.rs:14:13 + --> $DIR/issue-10536.rs:11:15 | -LL | assert!({one! two()}); - | ^^^^^^^^^^^^ expected bool, found () +LL | pub fn main() { + | ^ 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 00ef2ca18098b..6729fdf726aae 100644 --- a/src/test/ui/issues/issue-32323.stderr +++ b/src/test/ui/issues/issue-32323.stderr @@ -1,8 +1,8 @@ error[E0308]: mismatched types - --> $DIR/issue-32323.rs:5:49 + --> $DIR/issue-32323.rs:5:30 | LL | pub fn f<'a, T: Tr<'a>>() -> >::Out {} - | ^^ expected associated type, found () + | ^^^^^^^^^^^^^^^^^^ expected associated type, found () | = note: expected type `>::Out` found type `()` diff --git a/src/test/ui/issues/issue-43162.stderr b/src/test/ui/issues/issue-43162.stderr index 8b02476841d2e..d679fbb72624e 100644 --- a/src/test/ui/issues/issue-43162.stderr +++ b/src/test/ui/issues/issue-43162.stderr @@ -11,15 +11,13 @@ LL | break {}; //~ ERROR E0268 | ^^^^^^^^ cannot break outside of a loop error[E0308]: mismatched types - --> $DIR/issue-43162.rs:1:18 + --> $DIR/issue-43162.rs:1:13 | -LL | fn foo() -> bool { - | __________________^ -LL | | //~^ ERROR E0308 -LL | | break true; //~ ERROR E0268 - | | - help: consider removing this semicolon -LL | | } - | |_^ expected bool, found () +LL | fn foo() -> bool { + | ^^^^ expected bool, found () +LL | //~^ ERROR E0308 +LL | break true; //~ ERROR E0268 + | - help: consider removing this semicolon | = note: expected type `bool` found type `()` diff --git a/src/test/ui/issues/issue-44023.stderr b/src/test/ui/issues/issue-44023.stderr index 21cfe07e3e6e4..55757c1eb930e 100644 --- a/src/test/ui/issues/issue-44023.stderr +++ b/src/test/ui/issues/issue-44023.stderr @@ -1,10 +1,8 @@ error[E0308]: mismatched types - --> $DIR/issue-44023.rs:5:42 + --> $DIR/issue-44023.rs:5:36 | -LL | fn საჭმელად_გემრიელი_სადილი ( ) -> isize { //~ ERROR mismatched types - | __________________________________________^ -LL | | } - | |_^ expected isize, found () +LL | fn საჭმელად_გემრიელი_სადილი ( ) -> isize { //~ ERROR mismatched types + | ^^^^^ expected isize, found () | = 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 3e621c17cdcb6..e487e15c16c62 100644 --- a/src/test/ui/issues/issue-6458-4.stderr +++ b/src/test/ui/issues/issue-6458-4.stderr @@ -1,12 +1,10 @@ error[E0308]: mismatched types - --> $DIR/issue-6458-4.rs:1:40 + --> $DIR/issue-6458-4.rs:1:20 | -LL | fn foo(b: bool) -> Result { //~ ERROR mismatched types - | ________________________________________^ -LL | | Err("bar".to_string()); - | | - help: consider removing this semicolon -LL | | } - | |_^ expected enum `std::result::Result`, found () +LL | fn foo(b: bool) -> Result { //~ ERROR mismatched types + | ^^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found () +LL | Err("bar".to_string()); + | - help: consider removing this semicolon | = note: expected type `std::result::Result` found type `()` diff --git a/src/test/ui/liveness/liveness-forgot-ret.stderr b/src/test/ui/liveness/liveness-forgot-ret.stderr index b89112259004f..8d0eeb35fc3f1 100644 --- a/src/test/ui/liveness/liveness-forgot-ret.stderr +++ b/src/test/ui/liveness/liveness-forgot-ret.stderr @@ -1,8 +1,8 @@ error[E0308]: mismatched types - --> $DIR/liveness-forgot-ret.rs:3:25 + --> $DIR/liveness-forgot-ret.rs:3:19 | LL | fn f(a: isize) -> isize { if god_exists(a) { return 5; }; } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected isize, found () + | ^^^^^ expected isize, found () - expected because of this statement | = note: expected type `isize` found type `()` diff --git a/src/test/ui/liveness/liveness-missing-ret2.stderr b/src/test/ui/liveness/liveness-missing-ret2.stderr index e5f74786bc608..956b71fcfe8f6 100644 --- a/src/test/ui/liveness/liveness-missing-ret2.stderr +++ b/src/test/ui/liveness/liveness-missing-ret2.stderr @@ -1,13 +1,8 @@ error[E0308]: mismatched types - --> $DIR/liveness-missing-ret2.rs:1:17 + --> $DIR/liveness-missing-ret2.rs:1:11 | -LL | fn f() -> isize { //~ ERROR mismatched types - | _________________^ -LL | | // Make sure typestate doesn't interpret this match expression as -LL | | // the function result -LL | | match true { true => { } _ => {} }; -LL | | } - | |_^ expected isize, found () +LL | fn f() -> isize { //~ ERROR mismatched types + | ^^^^^ expected isize, found () | = 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 3aa81a405a6b5..bb4ca303aa775 100644 --- a/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr +++ b/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr @@ -1,11 +1,10 @@ error[E0308]: mismatched types - --> $DIR/liveness-return-last-stmt-semi.rs:4:45 + --> $DIR/liveness-return-last-stmt-semi.rs:4:41 | LL | macro_rules! test { () => { fn foo() -> i32 { 1; } } } - | ^^^-^^ - | | | - | | help: consider removing this semicolon - | expected i32, found () + | ^^^ - help: consider removing this semicolon + | | + | expected i32, found () ... LL | test!(); | -------- in this macro invocation @@ -14,35 +13,30 @@ LL | test!(); found type `()` error[E0308]: mismatched types - --> $DIR/liveness-return-last-stmt-semi.rs:7:23 + --> $DIR/liveness-return-last-stmt-semi.rs:7:19 | LL | fn no_return() -> i32 {} //~ ERROR mismatched types - | ^^ expected i32, found () + | ^^^ expected i32, found () | = note: expected type `i32` found type `()` error[E0308]: mismatched types - --> $DIR/liveness-return-last-stmt-semi.rs:9:23 + --> $DIR/liveness-return-last-stmt-semi.rs:9:19 | -LL | fn bar(x: u32) -> u32 { //~ ERROR mismatched types - | _______________________^ -LL | | x * 2; - | | - help: consider removing this semicolon -LL | | } - | |_^ expected u32, found () +LL | fn bar(x: u32) -> u32 { //~ ERROR mismatched types + | ^^^ expected u32, found () +LL | x * 2; + | - help: consider removing this semicolon | = note: expected type `u32` found type `()` error[E0308]: mismatched types - --> $DIR/liveness-return-last-stmt-semi.rs:13:23 + --> $DIR/liveness-return-last-stmt-semi.rs:13:19 | -LL | fn baz(x: u64) -> u32 { //~ ERROR mismatched types - | _______________________^ -LL | | x * 2; -LL | | } - | |_^ expected u32, found () +LL | fn baz(x: u64) -> u32 { //~ ERROR mismatched types + | ^^^ expected u32, found () | = 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 6d42dafd6f163..be86325de0003 100644 --- a/src/test/ui/missing/missing-return.stderr +++ b/src/test/ui/missing/missing-return.stderr @@ -1,8 +1,8 @@ error[E0308]: mismatched types - --> $DIR/missing-return.rs:3:17 + --> $DIR/missing-return.rs:3:11 | LL | fn f() -> isize { } - | ^^^ expected isize, found () + | ^^^^^ expected isize, found () | = note: expected type `isize` found type `()` From f62f540b4e81a4e67a39f199948406684a343f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 30 Dec 2018 15:41:19 -0800 Subject: [PATCH 2/4] Point at function name span --- src/librustc_typeck/check/mod.rs | 108 ++++++++++-------- .../consider-removing-last-semi.stderr | 8 +- src/test/ui/block-result/issue-11714.stderr | 4 +- src/test/ui/block-result/issue-13428.stderr | 8 +- src/test/ui/break-while-condition.stderr | 4 +- ...coercion-missing-tail-expected-type.stderr | 8 +- src/test/ui/issues/issue-10536.stderr | 4 +- src/test/ui/issues/issue-32323.stderr | 4 +- src/test/ui/issues/issue-43162.stderr | 4 +- src/test/ui/issues/issue-44023.stderr | 4 +- src/test/ui/issues/issue-6458-4.stderr | 4 +- .../liveness-closure-require-ret.stderr | 6 +- .../ui/liveness/liveness-forgot-ret.stderr | 5 +- .../ui/liveness/liveness-issue-2163.stderr | 11 +- .../ui/liveness/liveness-missing-ret2.stderr | 4 +- .../liveness-return-last-stmt-semi.stderr | 19 ++- src/test/ui/missing/missing-return.stderr | 4 +- 17 files changed, 132 insertions(+), 77 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index aa13087b484ac..381abcb977b26 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4796,16 +4796,20 @@ 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 = if let Some((decl, _)) = self.get_fn_decl(blk.id) { - decl.output.span() + 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 + (blk.span, None) }; 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); + 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", + ); } }, false); } @@ -4830,45 +4834,53 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty } + /// 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)); + self.get_node_fn_decl(parent).map(|(fn_decl, ident , _)| (fn_decl, ident)) + } + + /// 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| { + // 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 + } + } + /// Given a `NodeId`, return the `FnDecl` of the method it is enclosed by and whether a /// suggestion can be made, `None` otherwise. pub fn get_fn_decl(&self, blk_id: ast::NodeId) -> Option<(hir::FnDecl, bool)> { // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or // `while` before reaching it, as block tail returns are not available in them. - if let Some(fn_id) = self.tcx.hir().get_return_block(blk_id) { - let parent = self.tcx.hir().get(fn_id); - - if let Node::Item(&hir::Item { - ident, node: hir::ItemKind::Fn(ref decl, ..), .. - }) = parent { - 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.name != Symbol::intern("main"))) - }) - } else if let Node::TraitItem(&hir::TraitItem { - node: hir::TraitItemKind::Method(hir::MethodSig { - ref decl, .. - }, ..), .. - }) = parent { - decl.clone().and_then(|decl| { - Some((decl, true)) - }) - } else if let Node::ImplItem(&hir::ImplItem { - node: hir::ImplItemKind::Method(hir::MethodSig { - ref decl, .. - }, ..), .. - }) = parent { - decl.clone().and_then(|decl| { - Some((decl, false)) - }) - } else { - None - } - } else { - None - } + self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| { + let parent = self.tcx.hir().get(blk_id); + self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main)) + }) } /// On implicit return expressions with mismatched types, provide the following suggestions: @@ -4876,13 +4888,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { /// - Point out the method's return type as the reason for the expected type /// - Possible missing semicolon /// - Possible missing return type if the return type is the default, and not `fn main()` - pub fn suggest_mismatched_types_on_tail(&self, - err: &mut DiagnosticBuilder<'tcx>, - expression: &'gcx hir::Expr, - expected: Ty<'tcx>, - found: Ty<'tcx>, - cause_span: Span, - blk_id: ast::NodeId) { + pub fn suggest_mismatched_types_on_tail( + &self, + err: &mut DiagnosticBuilder<'tcx>, + expression: &'gcx hir::Expr, + expected: Ty<'tcx>, + found: Ty<'tcx>, + cause_span: Span, + blk_id: ast::NodeId, + ) { self.suggest_missing_semicolon(err, expression, expected, cause_span); if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) { self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest); 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 ce8c624cdad45..79e7a536cdc83 100644 --- a/src/test/ui/block-result/consider-removing-last-semi.stderr +++ b/src/test/ui/block-result/consider-removing-last-semi.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/consider-removing-last-semi.rs:1:11 | LL | fn f() -> String { //~ ERROR mismatched types - | ^^^^^^ expected struct `std::string::String`, found () + | - ^^^^^^ expected struct `std::string::String`, found () + | | + | this function's body doesn't return the expected type LL | 0u8; LL | "bla".to_string(); | - help: consider removing this semicolon @@ -14,7 +16,9 @@ error[E0308]: mismatched types --> $DIR/consider-removing-last-semi.rs:6:11 | LL | fn g() -> String { //~ ERROR mismatched types - | ^^^^^^ expected struct `std::string::String`, found () + | - ^^^^^^ expected struct `std::string::String`, found () + | | + | this function's body doesn't return the expected type 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 cc97eaf8e1ac3..82253911316ad 100644 --- a/src/test/ui/block-result/issue-11714.stderr +++ b/src/test/ui/block-result/issue-11714.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/issue-11714.rs:1:14 | LL | fn blah() -> i32 { //~ ERROR mismatched types - | ^^^ expected i32, found () + | ---- ^^^ expected i32, found () + | | + | this function's body doesn't return the expected type ... 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 d3a2b5131371e..8b8eb825377c4 100644 --- a/src/test/ui/block-result/issue-13428.stderr +++ b/src/test/ui/block-result/issue-13428.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/issue-13428.rs:3:13 | LL | fn foo() -> String { //~ ERROR mismatched types - | ^^^^^^ expected struct `std::string::String`, found () + | --- ^^^^^^ expected struct `std::string::String`, found () + | | + | this function's body doesn't return the expected type ... LL | ; | - help: consider removing this semicolon @@ -14,7 +16,9 @@ error[E0308]: mismatched types --> $DIR/issue-13428.rs:11:13 | LL | fn bar() -> String { //~ ERROR mismatched types - | ^^^^^^ expected struct `std::string::String`, found () + | --- ^^^^^^ expected struct `std::string::String`, found () + | | + | this function's body doesn't return the expected type 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 1c48ad630d8b7..6709747b13767 100644 --- a/src/test/ui/break-while-condition.stderr +++ b/src/test/ui/break-while-condition.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/break-while-condition.rs:3:11 | LL | fn main() { - | ^ expected !, found () + | ---- ^ expected !, found () + | | + | this function's body doesn't return the expected type | = 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 27f0540e36e94..9ace5b8ad3a8d 100644 --- a/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr +++ b/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/coercion-missing-tail-expected-type.rs:3:24 | LL | fn plus_one(x: i32) -> i32 { //~ ERROR mismatched types - | ^^^ expected i32, found () + | -------- ^^^ expected i32, found () + | | + | this function's body doesn't return the expected type LL | x + 1; | - help: consider removing this semicolon | @@ -13,7 +15,9 @@ error[E0308]: mismatched types --> $DIR/coercion-missing-tail-expected-type.rs:7:13 | LL | fn foo() -> Result { //~ ERROR mismatched types - | ^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found () + | --- ^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found () + | | + | this function's body doesn't return the expected type 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 71f9a83316c1c..02008470e636f 100644 --- a/src/test/ui/issues/issue-10536.stderr +++ b/src/test/ui/issues/issue-10536.stderr @@ -20,7 +20,9 @@ error[E0308]: mismatched types --> $DIR/issue-10536.rs:11:15 | LL | pub fn main() { - | ^ expected bool, found () + | ---- ^ expected bool, found () + | | + | this function's body doesn't return the expected type | = 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 6729fdf726aae..bef3596103c2b 100644 --- a/src/test/ui/issues/issue-32323.stderr +++ b/src/test/ui/issues/issue-32323.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/issue-32323.rs:5:30 | LL | pub fn f<'a, T: Tr<'a>>() -> >::Out {} - | ^^^^^^^^^^^^^^^^^^ expected associated type, found () + | - ^^^^^^^^^^^^^^^^^^ expected associated type, found () + | | + | this function's body doesn't return the expected type | = note: expected type `>::Out` found type `()` diff --git a/src/test/ui/issues/issue-43162.stderr b/src/test/ui/issues/issue-43162.stderr index d679fbb72624e..4d2b3549f8ed4 100644 --- a/src/test/ui/issues/issue-43162.stderr +++ b/src/test/ui/issues/issue-43162.stderr @@ -14,7 +14,9 @@ error[E0308]: mismatched types --> $DIR/issue-43162.rs:1:13 | LL | fn foo() -> bool { - | ^^^^ expected bool, found () + | --- ^^^^ expected bool, found () + | | + | this function's body doesn't return the expected type 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 55757c1eb930e..944098a644df2 100644 --- a/src/test/ui/issues/issue-44023.stderr +++ b/src/test/ui/issues/issue-44023.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/issue-44023.rs:5:36 | LL | fn საჭმელად_გემრიელი_სადილი ( ) -> isize { //~ ERROR mismatched types - | ^^^^^ expected isize, found () + | ------------------------ ^^^^^ expected isize, found () + | | + | this function's body doesn't return the expected type | = 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 e487e15c16c62..f4cdceac1726a 100644 --- a/src/test/ui/issues/issue-6458-4.stderr +++ b/src/test/ui/issues/issue-6458-4.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/issue-6458-4.rs:1:20 | LL | fn foo(b: bool) -> Result { //~ ERROR mismatched types - | ^^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found () + | --- ^^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found () + | | + | this function's body doesn't return the expected type 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 3133efdedd762..d7992704c50e8 100644 --- a/src/test/ui/liveness/liveness-closure-require-ret.stderr +++ b/src/test/ui/liveness/liveness-closure-require-ret.stderr @@ -1,8 +1,10 @@ error[E0308]: mismatched types - --> $DIR/liveness-closure-require-ret.rs:2:37 + --> $DIR/liveness-closure-require-ret.rs:2:11 | LL | fn main() { println!("{}", force(|| {})); } //~ ERROR mismatched types - | ^^ expected isize, found () + | ---- ^ expected isize, found () + | | + | this function's body doesn't return the expected type | = 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 8d0eeb35fc3f1..578890f5e625f 100644 --- a/src/test/ui/liveness/liveness-forgot-ret.stderr +++ b/src/test/ui/liveness/liveness-forgot-ret.stderr @@ -2,7 +2,10 @@ error[E0308]: mismatched types --> $DIR/liveness-forgot-ret.rs:3:19 | LL | fn f(a: isize) -> isize { if god_exists(a) { return 5; }; } - | ^^^^^ expected isize, found () - expected because of this statement + | - ^^^^^ - expected because of this statement + | | | + | | expected isize, found () + | this function's body doesn't return the expected type | = 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 e91994d9a2299..a8a5684207608 100644 --- a/src/test/ui/liveness/liveness-issue-2163.stderr +++ b/src/test/ui/liveness/liveness-issue-2163.stderr @@ -1,11 +1,10 @@ error[E0308]: mismatched types - --> $DIR/liveness-issue-2163.rs:5:30 + --> $DIR/liveness-issue-2163.rs:3:11 | -LL | a.iter().all(|_| -> bool { - | ______________________________^ -LL | | //~^ ERROR mismatched types -LL | | }); - | |_____^ expected bool, found () +LL | fn main() { + | ---- ^ expected bool, found () + | | + | this function's body doesn't return the expected type | = 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 956b71fcfe8f6..201b3ee6861a1 100644 --- a/src/test/ui/liveness/liveness-missing-ret2.stderr +++ b/src/test/ui/liveness/liveness-missing-ret2.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/liveness-missing-ret2.rs:1:11 | LL | fn f() -> isize { //~ ERROR mismatched types - | ^^^^^ expected isize, found () + | - ^^^^^ expected isize, found () + | | + | this function's body doesn't return the expected type | = 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 bb4ca303aa775..2ee77f30a6608 100644 --- a/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr +++ b/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr @@ -2,9 +2,10 @@ error[E0308]: mismatched types --> $DIR/liveness-return-last-stmt-semi.rs:4:41 | LL | macro_rules! test { () => { fn foo() -> i32 { 1; } } } - | ^^^ - help: consider removing this semicolon - | | - | expected i32, found () + | --- ^^^ - help: consider removing this semicolon + | | | + | | expected i32, found () + | this function's body doesn't return the expected type ... LL | test!(); | -------- in this macro invocation @@ -16,7 +17,9 @@ error[E0308]: mismatched types --> $DIR/liveness-return-last-stmt-semi.rs:7:19 | LL | fn no_return() -> i32 {} //~ ERROR mismatched types - | ^^^ expected i32, found () + | --------- ^^^ expected i32, found () + | | + | this function's body doesn't return the expected type | = note: expected type `i32` found type `()` @@ -25,7 +28,9 @@ error[E0308]: mismatched types --> $DIR/liveness-return-last-stmt-semi.rs:9:19 | LL | fn bar(x: u32) -> u32 { //~ ERROR mismatched types - | ^^^ expected u32, found () + | --- ^^^ expected u32, found () + | | + | this function's body doesn't return the expected type LL | x * 2; | - help: consider removing this semicolon | @@ -36,7 +41,9 @@ error[E0308]: mismatched types --> $DIR/liveness-return-last-stmt-semi.rs:13:19 | LL | fn baz(x: u64) -> u32 { //~ ERROR mismatched types - | ^^^ expected u32, found () + | --- ^^^ expected u32, found () + | | + | this function's body doesn't return the expected type | = 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 be86325de0003..9e6ffd97312f0 100644 --- a/src/test/ui/missing/missing-return.stderr +++ b/src/test/ui/missing/missing-return.stderr @@ -2,7 +2,9 @@ error[E0308]: mismatched types --> $DIR/missing-return.rs:3:11 | LL | fn f() -> isize { } - | ^^^^^ expected isize, found () + | - ^^^^^ expected isize, found () + | | + | this function's body doesn't return the expected type | = note: expected type `isize` found type `()` From 5d086c328276d428d499284d745a0a1814e8b11c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 30 Dec 2018 21:59:27 -0800 Subject: [PATCH 3/4] Tweak E0308 error for clarity --- src/librustc_typeck/check/mod.rs | 82 +++++++++++-------- .../consider-removing-last-semi.stderr | 4 +- src/test/ui/block-result/issue-11714.stderr | 2 +- src/test/ui/block-result/issue-13428.stderr | 4 +- src/test/ui/break-while-condition.stderr | 11 +-- ...coercion-missing-tail-expected-type.stderr | 4 +- src/test/ui/issues/issue-10536.stderr | 8 +- src/test/ui/issues/issue-32323.stderr | 2 +- src/test/ui/issues/issue-43162.stderr | 2 +- src/test/ui/issues/issue-44023.stderr | 2 +- src/test/ui/issues/issue-6458-4.stderr | 2 +- .../liveness-closure-require-ret.stderr | 6 +- .../ui/liveness/liveness-forgot-ret.stderr | 7 +- .../ui/liveness/liveness-issue-2163.stderr | 11 +-- .../ui/liveness/liveness-missing-ret2.stderr | 2 +- .../liveness-return-last-stmt-semi.stderr | 8 +- 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 381abcb977b26..9492b1a2341dc 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 { + 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 79e7a536cdc83..1bf17db21ac5a 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 82253911316ad..2c13b28766943 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 8b8eb825377c4..91e926eb5a73b 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 6709747b13767..3e81753a4105f 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 9ace5b8ad3a8d..c8ec2f0545e6b 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 { //~ 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 02008470e636f..d5caf777cd45e 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 bef3596103c2b..0339fdc55b9c8 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>>() -> >::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 `>::Out` found type `()` diff --git a/src/test/ui/issues/issue-43162.stderr b/src/test/ui/issues/issue-43162.stderr index 4d2b3549f8ed4..3fc5317830e48 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 944098a644df2..f1962a86ee03a 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 f4cdceac1726a..c087292e978c2 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 { //~ 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 d7992704c50e8..3133efdedd762 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 578890f5e625f..bbcbbdbe8dd5b 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 a8a5684207608..e91994d9a2299 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 201b3ee6861a1..58d0249ee3b24 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 2ee77f30a6608..c6d166d8b31a0 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 9e6ffd97312f0..42466e2fc6574 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 `()` From 211365d68c8eb5515cb658c4c240c73c122d2c5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 4 Jan 2019 11:17:23 -0800 Subject: [PATCH 4/4] review comments --- src/librustc_typeck/check/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 9492b1a2341dc..fa6f3843f7c52 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4859,13 +4859,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { None } - /// Given a function block's `NodeId`, return its `FnDecl` , `None` otherwise. + /// Given a function block's `NodeId`, return its `FnDecl` if it exists, or `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)); - self.get_node_fn_decl(parent).map(|(fn_decl, ident , _)| (fn_decl, ident)) + self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident)) } - /// Given a function `Node`, return its `FnDecl` , `None` otherwise. + /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise. fn get_node_fn_decl(&self, node: Node) -> Option<(hir::FnDecl, ast::Ident, bool)> { match node { Node::Item(&hir::Item {