Skip to content

Commit f62f540

Browse files
committed
Point at function name span
1 parent 1f65dc0 commit f62f540

17 files changed

+132
-77
lines changed

src/librustc_typeck/check/mod.rs

+61-47
Original file line numberDiff line numberDiff line change
@@ -4796,16 +4796,20 @@ 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 = if let Some((decl, _)) = self.get_fn_decl(blk.id) {
4800-
decl.output.span()
4799+
let (sp, fn_span) = if let Some((decl, ident)) = self.get_parent_fn_decl(blk.id) {
4800+
(decl.output.span(), Some(ident.span))
48014801
} else {
4802-
blk.span
4802+
(blk.span, None)
48034803
};
48044804
coerce.coerce_forced_unit(self, &self.misc(sp), &mut |err| {
48054805
if let Some(expected_ty) = expected.only_has_type(self) {
4806-
self.consider_hint_about_removing_semicolon(blk,
4807-
expected_ty,
4808-
err);
4806+
self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
4807+
}
4808+
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+
);
48094813
}
48104814
}, false);
48114815
}
@@ -4830,59 +4834,69 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
48304834
ty
48314835
}
48324836

4837+
/// Given a function block's `NodeId`, return its `FnDecl` , `None` otherwise.
4838+
fn get_parent_fn_decl(&self, blk_id: ast::NodeId) -> Option<(hir::FnDecl, ast::Ident)> {
4839+
let parent = self.tcx.hir().get(self.tcx.hir().get_parent(blk_id));
4840+
self.get_node_fn_decl(parent).map(|(fn_decl, ident , _)| (fn_decl, ident))
4841+
}
4842+
4843+
/// Given a function `Node`, return its `FnDecl` , `None` otherwise.
4844+
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| {
4849+
// This is less than ideal, it will not suggest a return type span on any
4850+
// method called `main`, regardless of whether it is actually the entry point,
4851+
// but it will still present it as the reason for the expected type.
4852+
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
4872+
}
4873+
}
4874+
48334875
/// Given a `NodeId`, return the `FnDecl` of the method it is enclosed by and whether a
48344876
/// suggestion can be made, `None` otherwise.
48354877
pub fn get_fn_decl(&self, blk_id: ast::NodeId) -> Option<(hir::FnDecl, bool)> {
48364878
// Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
48374879
// `while` before reaching it, as block tail returns are not available in them.
4838-
if let Some(fn_id) = self.tcx.hir().get_return_block(blk_id) {
4839-
let parent = self.tcx.hir().get(fn_id);
4840-
4841-
if let Node::Item(&hir::Item {
4842-
ident, node: hir::ItemKind::Fn(ref decl, ..), ..
4843-
}) = parent {
4844-
decl.clone().and_then(|decl| {
4845-
// This is less than ideal, it will not suggest a return type span on any
4846-
// method called `main`, regardless of whether it is actually the entry point,
4847-
// but it will still present it as the reason for the expected type.
4848-
Some((decl, ident.name != Symbol::intern("main")))
4849-
})
4850-
} else if let Node::TraitItem(&hir::TraitItem {
4851-
node: hir::TraitItemKind::Method(hir::MethodSig {
4852-
ref decl, ..
4853-
}, ..), ..
4854-
}) = parent {
4855-
decl.clone().and_then(|decl| {
4856-
Some((decl, true))
4857-
})
4858-
} else if let Node::ImplItem(&hir::ImplItem {
4859-
node: hir::ImplItemKind::Method(hir::MethodSig {
4860-
ref decl, ..
4861-
}, ..), ..
4862-
}) = parent {
4863-
decl.clone().and_then(|decl| {
4864-
Some((decl, false))
4865-
})
4866-
} else {
4867-
None
4868-
}
4869-
} else {
4870-
None
4871-
}
4880+
self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
4881+
let parent = self.tcx.hir().get(blk_id);
4882+
self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
4883+
})
48724884
}
48734885

48744886
/// On implicit return expressions with mismatched types, provide the following suggestions:
48754887
///
48764888
/// - Point out the method's return type as the reason for the expected type
48774889
/// - Possible missing semicolon
48784890
/// - Possible missing return type if the return type is the default, and not `fn main()`
4879-
pub fn suggest_mismatched_types_on_tail(&self,
4880-
err: &mut DiagnosticBuilder<'tcx>,
4881-
expression: &'gcx hir::Expr,
4882-
expected: Ty<'tcx>,
4883-
found: Ty<'tcx>,
4884-
cause_span: Span,
4885-
blk_id: ast::NodeId) {
4891+
pub fn suggest_mismatched_types_on_tail(
4892+
&self,
4893+
err: &mut DiagnosticBuilder<'tcx>,
4894+
expression: &'gcx hir::Expr,
4895+
expected: Ty<'tcx>,
4896+
found: Ty<'tcx>,
4897+
cause_span: Span,
4898+
blk_id: ast::NodeId,
4899+
) {
48864900
self.suggest_missing_semicolon(err, expression, expected, cause_span);
48874901
if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
48884902
self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);

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

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
22
--> $DIR/consider-removing-last-semi.rs:1:11
33
|
44
LL | fn f() -> String { //~ ERROR mismatched types
5-
| ^^^^^^ expected struct `std::string::String`, found ()
5+
| - ^^^^^^ expected struct `std::string::String`, found ()
6+
| |
7+
| this function's body doesn't return the expected type
68
LL | 0u8;
79
LL | "bla".to_string();
810
| - help: consider removing this semicolon
@@ -14,7 +16,9 @@ error[E0308]: mismatched types
1416
--> $DIR/consider-removing-last-semi.rs:6:11
1517
|
1618
LL | fn g() -> String { //~ ERROR mismatched types
17-
| ^^^^^^ expected struct `std::string::String`, found ()
19+
| - ^^^^^^ expected struct `std::string::String`, found ()
20+
| |
21+
| this function's body doesn't return the expected type
1822
LL | "this won't work".to_string();
1923
LL | "removeme".to_string();
2024
| - help: consider removing this semicolon

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
22
--> $DIR/issue-11714.rs:1:14
33
|
44
LL | fn blah() -> i32 { //~ ERROR mismatched types
5-
| ^^^ expected i32, found ()
5+
| ---- ^^^ expected i32, found ()
6+
| |
7+
| this function's body doesn't return the expected type
68
...
79
LL | ;
810
| - help: consider removing this semicolon

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

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
22
--> $DIR/issue-13428.rs:3:13
33
|
44
LL | fn foo() -> String { //~ ERROR mismatched types
5-
| ^^^^^^ expected struct `std::string::String`, found ()
5+
| --- ^^^^^^ expected struct `std::string::String`, found ()
6+
| |
7+
| this function's body doesn't return the expected type
68
...
79
LL | ;
810
| - help: consider removing this semicolon
@@ -14,7 +16,9 @@ error[E0308]: mismatched types
1416
--> $DIR/issue-13428.rs:11:13
1517
|
1618
LL | fn bar() -> String { //~ ERROR mismatched types
17-
| ^^^^^^ expected struct `std::string::String`, found ()
19+
| --- ^^^^^^ expected struct `std::string::String`, found ()
20+
| |
21+
| this function's body doesn't return the expected type
1822
LL | "foobar".to_string()
1923
LL | ;
2024
| - help: consider removing this semicolon

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
22
--> $DIR/break-while-condition.rs:3:11
33
|
44
LL | fn main() {
5-
| ^ expected !, found ()
5+
| ---- ^ expected !, found ()
6+
| |
7+
| this function's body doesn't return the expected type
68
|
79
= note: expected type `!`
810
found type `()`

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

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
22
--> $DIR/coercion-missing-tail-expected-type.rs:3:24
33
|
44
LL | fn plus_one(x: i32) -> i32 { //~ ERROR mismatched types
5-
| ^^^ expected i32, found ()
5+
| -------- ^^^ expected i32, found ()
6+
| |
7+
| this function's body doesn't return the expected type
68
LL | x + 1;
79
| - help: consider removing this semicolon
810
|
@@ -13,7 +15,9 @@ error[E0308]: mismatched types
1315
--> $DIR/coercion-missing-tail-expected-type.rs:7:13
1416
|
1517
LL | fn foo() -> Result<u8, u64> { //~ ERROR mismatched types
16-
| ^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
18+
| --- ^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
19+
| |
20+
| this function's body doesn't return the expected type
1721
LL | Ok(1);
1822
| - help: consider removing this semicolon
1923
|

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ error[E0308]: mismatched types
2020
--> $DIR/issue-10536.rs:11:15
2121
|
2222
LL | pub fn main() {
23-
| ^ expected bool, found ()
23+
| ---- ^ expected bool, found ()
24+
| |
25+
| this function's body doesn't return the expected type
2426
|
2527
= note: expected type `bool`
2628
found type `()`

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
22
--> $DIR/issue-32323.rs:5:30
33
|
44
LL | pub fn f<'a, T: Tr<'a>>() -> <T as Tr<'a>>::Out {}
5-
| ^^^^^^^^^^^^^^^^^^ expected associated type, found ()
5+
| - ^^^^^^^^^^^^^^^^^^ expected associated type, found ()
6+
| |
7+
| this function's body doesn't return the expected type
68
|
79
= note: expected type `<T as Tr<'a>>::Out`
810
found type `()`

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ error[E0308]: mismatched types
1414
--> $DIR/issue-43162.rs:1:13
1515
|
1616
LL | fn foo() -> bool {
17-
| ^^^^ expected bool, found ()
17+
| --- ^^^^ expected bool, found ()
18+
| |
19+
| this function's body doesn't return the expected type
1820
LL | //~^ ERROR E0308
1921
LL | break true; //~ ERROR E0268
2022
| - help: consider removing this semicolon

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
22
--> $DIR/issue-44023.rs:5:36
33
|
44
LL | fn საჭმელად_გემრიელი_სადილი ( ) -> isize { //~ ERROR mismatched types
5-
| ^^^^^ expected isize, found ()
5+
| ------------------------ ^^^^^ expected isize, found ()
6+
| |
7+
| this function's body doesn't return the expected type
68
|
79
= note: expected type `isize`
810
found type `()`

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
22
--> $DIR/issue-6458-4.rs:1:20
33
|
44
LL | fn foo(b: bool) -> Result<bool,String> { //~ ERROR mismatched types
5-
| ^^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
5+
| --- ^^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
6+
| |
7+
| this function's body doesn't return the expected type
68
LL | Err("bar".to_string());
79
| - help: consider removing this semicolon
810
|

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

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

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ 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 isize, found () - expected because of this statement
5+
| - ^^^^^ - expected because of this statement
6+
| | |
7+
| | expected isize, found ()
8+
| this function's body doesn't return the expected type
69
|
710
= note: expected type `isize`
811
found type `()`

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

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

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
22
--> $DIR/liveness-missing-ret2.rs:1:11
33
|
44
LL | fn f() -> isize { //~ ERROR mismatched types
5-
| ^^^^^ expected isize, found ()
5+
| - ^^^^^ expected isize, found ()
6+
| |
7+
| this function's body doesn't return the expected type
68
|
79
= note: expected type `isize`
810
found type `()`

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

+13-6
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ error[E0308]: mismatched types
22
--> $DIR/liveness-return-last-stmt-semi.rs:4:41
33
|
44
LL | macro_rules! test { () => { fn foo() -> i32 { 1; } } }
5-
| ^^^ - help: consider removing this semicolon
6-
| |
7-
| expected i32, found ()
5+
| --- ^^^ - help: consider removing this semicolon
6+
| | |
7+
| | expected i32, found ()
8+
| this function's body doesn't return the expected type
89
...
910
LL | test!();
1011
| -------- in this macro invocation
@@ -16,7 +17,9 @@ error[E0308]: mismatched types
1617
--> $DIR/liveness-return-last-stmt-semi.rs:7:19
1718
|
1819
LL | fn no_return() -> i32 {} //~ ERROR mismatched types
19-
| ^^^ expected i32, found ()
20+
| --------- ^^^ expected i32, found ()
21+
| |
22+
| this function's body doesn't return the expected type
2023
|
2124
= note: expected type `i32`
2225
found type `()`
@@ -25,7 +28,9 @@ error[E0308]: mismatched types
2528
--> $DIR/liveness-return-last-stmt-semi.rs:9:19
2629
|
2730
LL | fn bar(x: u32) -> u32 { //~ ERROR mismatched types
28-
| ^^^ expected u32, found ()
31+
| --- ^^^ expected u32, found ()
32+
| |
33+
| this function's body doesn't return the expected type
2934
LL | x * 2;
3035
| - help: consider removing this semicolon
3136
|
@@ -36,7 +41,9 @@ error[E0308]: mismatched types
3641
--> $DIR/liveness-return-last-stmt-semi.rs:13:19
3742
|
3843
LL | fn baz(x: u64) -> u32 { //~ ERROR mismatched types
39-
| ^^^ expected u32, found ()
44+
| --- ^^^ expected u32, found ()
45+
| |
46+
| this function's body doesn't return the expected type
4047
|
4148
= note: expected type `u32`
4249
found type `()`

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
22
--> $DIR/missing-return.rs:3:11
33
|
44
LL | fn f() -> isize { }
5-
| ^^^^^ expected isize, found ()
5+
| - ^^^^^ expected isize, found ()
6+
| |
7+
| this function's body doesn't return the expected type
68
|
79
= note: expected type `isize`
810
found type `()`

0 commit comments

Comments
 (0)