about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_typeck/check/mod.rs82
-rw-r--r--src/test/ui/block-result/consider-removing-last-semi.stderr4
-rw-r--r--src/test/ui/block-result/issue-11714.stderr2
-rw-r--r--src/test/ui/block-result/issue-13428.stderr4
-rw-r--r--src/test/ui/break-while-condition.stderr11
-rw-r--r--src/test/ui/coercion/coercion-missing-tail-expected-type.stderr4
-rw-r--r--src/test/ui/issues/issue-10536.stderr8
-rw-r--r--src/test/ui/issues/issue-32323.stderr2
-rw-r--r--src/test/ui/issues/issue-43162.stderr2
-rw-r--r--src/test/ui/issues/issue-44023.stderr2
-rw-r--r--src/test/ui/issues/issue-6458-4.stderr2
-rw-r--r--src/test/ui/liveness/liveness-closure-require-ret.stderr6
-rw-r--r--src/test/ui/liveness/liveness-forgot-ret.stderr7
-rw-r--r--src/test/ui/liveness/liveness-issue-2163.stderr11
-rw-r--r--src/test/ui/liveness/liveness-missing-ret2.stderr2
-rw-r--r--src/test/ui/liveness/liveness-return-last-stmt-semi.stderr8
-rw-r--r--src/test/ui/missing/missing-return.stderr2
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 `()`