Check node kind to avoid ICE in check_expr_return()
This commit is contained in:
parent
e98897e5dc
commit
2586e962e0
3 changed files with 33 additions and 12 deletions
|
@ -682,23 +682,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let encl_item_id = self.tcx.hir().get_parent_item(expr.hir_id);
|
let encl_item_id = self.tcx.hir().get_parent_item(expr.hir_id);
|
||||||
let encl_item = self.tcx.hir().expect_item(encl_item_id);
|
|
||||||
|
|
||||||
if let hir::ItemKind::Fn(..) = encl_item.kind {
|
// Somewhat confusingly, get_parent_item() does not necessarily return an
|
||||||
// We are inside a function body, so reporting "return statement
|
// item -- it can also return a Foreign-/Impl-/TraitItem or a Crate (see
|
||||||
// outside of function body" needs an explanation.
|
// issue #86721). If it does, we still report the same error.
|
||||||
|
if let Some(hir::Node::Item(encl_item)) = self.tcx.hir().find(encl_item_id) {
|
||||||
|
if let hir::ItemKind::Fn(..) = encl_item.kind {
|
||||||
|
// We are inside a function body, so reporting "return statement
|
||||||
|
// outside of function body" needs an explanation.
|
||||||
|
|
||||||
let encl_body_owner_id = self.tcx.hir().enclosing_body_owner(expr.hir_id);
|
let encl_body_owner_id = self.tcx.hir().enclosing_body_owner(expr.hir_id);
|
||||||
|
|
||||||
// If this didn't hold, we would not have to report an error in
|
// If this didn't hold, we would not have to report an error in
|
||||||
// the first place.
|
// the first place.
|
||||||
assert_ne!(encl_item_id, encl_body_owner_id);
|
assert_ne!(encl_item_id, encl_body_owner_id);
|
||||||
|
|
||||||
let encl_body_id = self.tcx.hir().body_owned_by(encl_body_owner_id);
|
let encl_body_id = self.tcx.hir().body_owned_by(encl_body_owner_id);
|
||||||
let encl_body = self.tcx.hir().body(encl_body_id);
|
let encl_body = self.tcx.hir().body(encl_body_id);
|
||||||
|
|
||||||
err.encl_body_span = Some(encl_body.value.span);
|
err.encl_body_span = Some(encl_body.value.span);
|
||||||
err.encl_fn_span = Some(encl_item.span);
|
err.encl_fn_span = Some(encl_item.span);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tcx.sess.emit_err(err);
|
self.tcx.sess.emit_err(err);
|
||||||
|
|
8
src/test/ui/typeck/issue-86721-return-expr-ice.rs
Normal file
8
src/test/ui/typeck/issue-86721-return-expr-ice.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
// Regression test for the ICE described in #86721.
|
||||||
|
|
||||||
|
#![crate_type="lib"]
|
||||||
|
|
||||||
|
trait T {
|
||||||
|
const U: usize = return;
|
||||||
|
//~^ ERROR: return statement outside of function body [E0572]
|
||||||
|
}
|
9
src/test/ui/typeck/issue-86721-return-expr-ice.stderr
Normal file
9
src/test/ui/typeck/issue-86721-return-expr-ice.stderr
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
error[E0572]: return statement outside of function body
|
||||||
|
--> $DIR/issue-86721-return-expr-ice.rs:6:22
|
||||||
|
|
|
||||||
|
LL | const U: usize = return;
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0572`.
|
Loading…
Add table
Add a link
Reference in a new issue