Tweak E0308 error for clarity

This commit is contained in:
Esteban Küber 2018-12-30 21:59:27 -08:00
parent f62f540b4e
commit 5d086c3282
17 changed files with 87 additions and 72 deletions

View file

@ -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,
}
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 `()`

View file

@ -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
|

View file

@ -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 `()`

View file

@ -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 `()`

View file

@ -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

View file

@ -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 `()`

View file

@ -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
|

View file

@ -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 `()`

View file

@ -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 `()`

View file

@ -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 `()`

View file

@ -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 `()`

View file

@ -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 `()`

View file

@ -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 `()`