diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index f69839bf859..1f929af6cc5 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -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 = self.tcx.hir().expect_item(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. + // Somewhat confusingly, get_parent_item() does not necessarily return an + // item -- it can also return a Foreign-/Impl-/TraitItem or a Crate (see + // 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 - // the first place. - assert_ne!(encl_item_id, encl_body_owner_id); + // If this didn't hold, we would not have to report an error in + // the first place. + 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 = self.tcx.hir().body(encl_body_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); - err.encl_body_span = Some(encl_body.value.span); - err.encl_fn_span = Some(encl_item.span); + err.encl_body_span = Some(encl_body.value.span); + err.encl_fn_span = Some(encl_item.span); + } } self.tcx.sess.emit_err(err); diff --git a/src/test/ui/typeck/issue-86721-return-expr-ice.rs b/src/test/ui/typeck/issue-86721-return-expr-ice.rs new file mode 100644 index 00000000000..9216fb0d171 --- /dev/null +++ b/src/test/ui/typeck/issue-86721-return-expr-ice.rs @@ -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] +} diff --git a/src/test/ui/typeck/issue-86721-return-expr-ice.stderr b/src/test/ui/typeck/issue-86721-return-expr-ice.stderr new file mode 100644 index 00000000000..39f8fb8da14 --- /dev/null +++ b/src/test/ui/typeck/issue-86721-return-expr-ice.stderr @@ -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`.