diff options
| author | varkor <github@varkor.com> | 2018-01-25 18:03:48 +0000 |
|---|---|---|
| committer | varkor <github@varkor.com> | 2018-01-25 18:03:48 +0000 |
| commit | 6461532afa8ec554e1d40d5887a2de60aa658199 (patch) | |
| tree | 7210e05b144d50e345720a9d722c2d04f6000555 /src | |
| parent | da569fa9ddf8369a9809184d43c600dc06bd4b4d (diff) | |
| download | rust-6461532afa8ec554e1d40d5887a2de60aa658199.tar.gz rust-6461532afa8ec554e1d40d5887a2de60aa658199.zip | |
Fix never-type rvalue ICE
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_mir/build/block.rs | 8 | ||||
| -rw-r--r-- | src/librustc_mir/build/expr/into.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/never-type-rvalues.rs | 46 |
3 files changed, 54 insertions, 2 deletions
diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs index b2b615d29a5..f8718c36ede 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir/build/block.rs @@ -143,7 +143,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { if let Some(expr) = expr { unpack!(block = this.into(destination, block, expr)); } else { - this.cfg.push_assign_unit(block, source_info, destination); + let tcx = this.hir.tcx(); + let ty = destination.ty(&this.local_decls, tcx).to_ty(tcx); + if ty.is_nil() { + // We only want to assign an implicit `()` as the return value of the block if the + // block does not diverge. (Otherwise, we may try to assign a unit to a `!`-type.) + this.cfg.push_assign_unit(block, source_info, destination); + } } // Finally, we pop all the let scopes before exiting out from the scope of block // itself. diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 3e0ccc7d072..68b23d1ae17 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -272,7 +272,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::Continue { .. } | ExprKind::Break { .. } | ExprKind::InlineAsm { .. } | - ExprKind::Return {.. } => { + ExprKind::Return { .. } => { unpack!(block = this.stmt_expr(block, expr)); this.cfg.push_assign_unit(block, source_info, destination); block.unit() diff --git a/src/test/run-pass/never-type-rvalues.rs b/src/test/run-pass/never-type-rvalues.rs new file mode 100644 index 00000000000..9bf003ee1dd --- /dev/null +++ b/src/test/run-pass/never-type-rvalues.rs @@ -0,0 +1,46 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(never_type)] +#![allow(dead_code)] +#![allow(path_statements)] +#![allow(unreachable_patterns)] + +fn never_direct(x: !) { + x; +} + +fn never_ref_pat(ref x: !) { + *x; +} + +fn never_ref(x: &!) { + let &y = x; + y; +} + +fn never_pointer(x: *const !) { + unsafe { + *x; + } +} + +fn never_slice(x: &[!]) { + x[0]; +} + +fn never_match(x: Result<(), !>) { + match x { + Ok(_) => {}, + Err(_) => {}, + } +} + +pub fn main() { } |
