diff options
| author | Fabian Wolff <fabian.wolff@alumni.ethz.ch> | 2021-06-29 22:11:48 +0200 |
|---|---|---|
| committer | Fabian Wolff <fabian.wolff@alumni.ethz.ch> | 2021-06-29 22:20:06 +0200 |
| commit | 2586e962e0924d832c708a7308d88da27d8bc01b (patch) | |
| tree | d0e116114edbc4b5343dd7bf7a40fdf4b5171409 | |
| parent | e98897e5dc9898707bf4331c43b2e76ab7e282fe (diff) | |
| download | rust-2586e962e0924d832c708a7308d88da27d8bc01b.tar.gz rust-2586e962e0924d832c708a7308d88da27d8bc01b.zip | |
Check node kind to avoid ICE in `check_expr_return()`
| -rw-r--r-- | compiler/rustc_typeck/src/check/expr.rs | 28 | ||||
| -rw-r--r-- | src/test/ui/typeck/issue-86721-return-expr-ice.rs | 8 | ||||
| -rw-r--r-- | src/test/ui/typeck/issue-86721-return-expr-ice.stderr | 9 |
3 files changed, 33 insertions, 12 deletions
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`. |
