diff options
| author | Tyler Mandry <tmandry@gmail.com> | 2019-10-01 23:06:09 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-10-01 23:06:09 -0700 |
| commit | c11cb25262c52e2c9b6dd711eddfc6aecf59d51c (patch) | |
| tree | e86b44b5adc6c9b04daab372f1bca35edc31088f | |
| parent | ff191b54cc8a95e3bfc7ae5f8f9984f934758165 (diff) | |
| parent | 0e6fb8e8da2f3256f9e2c2c079b8174acf80d94d (diff) | |
| download | rust-c11cb25262c52e2c9b6dd711eddfc6aecf59d51c.tar.gz rust-c11cb25262c52e2c9b6dd711eddfc6aecf59d51c.zip | |
Rollup merge of #64649 - estebank:returnator, r=varkor
Avoid ICE on return outside of fn with literal array
Do not ICE when encountering `enum E { A = return [0][0] }`.
Fix #64638.
| -rw-r--r-- | src/librustc_typeck/check/writeback.rs | 23 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-64620.rs | 5 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-64620.stderr | 9 |
3 files changed, 34 insertions, 3 deletions
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 99d62d198a9..7a8a209a535 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -190,9 +190,26 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { if let hir::ExprKind::Index(ref base, ref index) = e.kind { let mut tables = self.fcx.tables.borrow_mut(); - // All valid indexing looks like this; might encounter non-valid indexes at this point - if let ty::Ref(_, base_ty, _) = tables.expr_ty_adjusted(&base).kind { - let index_ty = tables.expr_ty_adjusted(&index); + // All valid indexing looks like this; might encounter non-valid indexes at this point. + let base_ty = tables.expr_ty_adjusted_opt(&base).map(|t| &t.kind); + if base_ty.is_none() { + // When encountering `return [0][0]` outside of a `fn` body we can encounter a base + // that isn't in the type table. We assume more relevant errors have already been + // emitted, so we delay an ICE if none have. (#64638) + self.tcx().sess.delay_span_bug(e.span, &format!("bad base: `{:?}`", base)); + } + if let Some(ty::Ref(_, base_ty, _)) = base_ty { + let index_ty = tables.expr_ty_adjusted_opt(&index).unwrap_or_else(|| { + // When encountering `return [0][0]` outside of a `fn` body we would attempt + // to access an unexistend index. We assume that more relevant errors will + // already have been emitted, so we only gate on this with an ICE if no + // error has been emitted. (#64638) + self.tcx().sess.delay_span_bug( + e.span, + &format!("bad index {:?} for base: `{:?}`", index, base), + ); + self.fcx.tcx.types.err + }); let index_ty = self.fcx.resolve_vars_if_possible(&index_ty); if base_ty.builtin_index().is_some() && index_ty == self.fcx.tcx.types.usize { diff --git a/src/test/ui/issues/issue-64620.rs b/src/test/ui/issues/issue-64620.rs new file mode 100644 index 00000000000..a62e5bf8d3c --- /dev/null +++ b/src/test/ui/issues/issue-64620.rs @@ -0,0 +1,5 @@ +enum Bug { + V1 = return [0][0] //~ERROR return statement outside of function body +} + +fn main() {} diff --git a/src/test/ui/issues/issue-64620.stderr b/src/test/ui/issues/issue-64620.stderr new file mode 100644 index 00000000000..f40ac4de32d --- /dev/null +++ b/src/test/ui/issues/issue-64620.stderr @@ -0,0 +1,9 @@ +error[E0572]: return statement outside of function body + --> $DIR/issue-64620.rs:2:10 + | +LL | V1 = return [0][0] + | ^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0572`. |
