Skip to content

Commit 2586e96

Browse files
committed
Check node kind to avoid ICE in check_expr_return()
1 parent e98897e commit 2586e96

File tree

3 files changed

+33
-12
lines changed

3 files changed

+33
-12
lines changed

compiler/rustc_typeck/src/check/expr.rs

+16-12
Original file line numberDiff line numberDiff line change
@@ -682,23 +682,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
682682
};
683683

684684
let encl_item_id = self.tcx.hir().get_parent_item(expr.hir_id);
685-
let encl_item = self.tcx.hir().expect_item(encl_item_id);
686685

687-
if let hir::ItemKind::Fn(..) = encl_item.kind {
688-
// We are inside a function body, so reporting "return statement
689-
// outside of function body" needs an explanation.
686+
// Somewhat confusingly, get_parent_item() does not necessarily return an
687+
// item -- it can also return a Foreign-/Impl-/TraitItem or a Crate (see
688+
// issue #86721). If it does, we still report the same error.
689+
if let Some(hir::Node::Item(encl_item)) = self.tcx.hir().find(encl_item_id) {
690+
if let hir::ItemKind::Fn(..) = encl_item.kind {
691+
// We are inside a function body, so reporting "return statement
692+
// outside of function body" needs an explanation.
690693

691-
let encl_body_owner_id = self.tcx.hir().enclosing_body_owner(expr.hir_id);
694+
let encl_body_owner_id = self.tcx.hir().enclosing_body_owner(expr.hir_id);
692695

693-
// If this didn't hold, we would not have to report an error in
694-
// the first place.
695-
assert_ne!(encl_item_id, encl_body_owner_id);
696+
// If this didn't hold, we would not have to report an error in
697+
// the first place.
698+
assert_ne!(encl_item_id, encl_body_owner_id);
696699

697-
let encl_body_id = self.tcx.hir().body_owned_by(encl_body_owner_id);
698-
let encl_body = self.tcx.hir().body(encl_body_id);
700+
let encl_body_id = self.tcx.hir().body_owned_by(encl_body_owner_id);
701+
let encl_body = self.tcx.hir().body(encl_body_id);
699702

700-
err.encl_body_span = Some(encl_body.value.span);
701-
err.encl_fn_span = Some(encl_item.span);
703+
err.encl_body_span = Some(encl_body.value.span);
704+
err.encl_fn_span = Some(encl_item.span);
705+
}
702706
}
703707

704708
self.tcx.sess.emit_err(err);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Regression test for the ICE described in #86721.
2+
3+
#![crate_type="lib"]
4+
5+
trait T {
6+
const U: usize = return;
7+
//~^ ERROR: return statement outside of function body [E0572]
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0572]: return statement outside of function body
2+
--> $DIR/issue-86721-return-expr-ice.rs:6:22
3+
|
4+
LL | const U: usize = return;
5+
| ^^^^^^
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0572`.

0 commit comments

Comments
 (0)