Skip to content

Commit 6461532

Browse files
committed
Fix never-type rvalue ICE
1 parent da569fa commit 6461532

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

src/librustc_mir/build/block.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
143143
if let Some(expr) = expr {
144144
unpack!(block = this.into(destination, block, expr));
145145
} else {
146-
this.cfg.push_assign_unit(block, source_info, destination);
146+
let tcx = this.hir.tcx();
147+
let ty = destination.ty(&this.local_decls, tcx).to_ty(tcx);
148+
if ty.is_nil() {
149+
// We only want to assign an implicit `()` as the return value of the block if the
150+
// block does not diverge. (Otherwise, we may try to assign a unit to a `!`-type.)
151+
this.cfg.push_assign_unit(block, source_info, destination);
152+
}
147153
}
148154
// Finally, we pop all the let scopes before exiting out from the scope of block
149155
// itself.

src/librustc_mir/build/expr/into.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
272272
ExprKind::Continue { .. } |
273273
ExprKind::Break { .. } |
274274
ExprKind::InlineAsm { .. } |
275-
ExprKind::Return {.. } => {
275+
ExprKind::Return { .. } => {
276276
unpack!(block = this.stmt_expr(block, expr));
277277
this.cfg.push_assign_unit(block, source_info, destination);
278278
block.unit()
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(never_type)]
12+
#![allow(dead_code)]
13+
#![allow(path_statements)]
14+
#![allow(unreachable_patterns)]
15+
16+
fn never_direct(x: !) {
17+
x;
18+
}
19+
20+
fn never_ref_pat(ref x: !) {
21+
*x;
22+
}
23+
24+
fn never_ref(x: &!) {
25+
let &y = x;
26+
y;
27+
}
28+
29+
fn never_pointer(x: *const !) {
30+
unsafe {
31+
*x;
32+
}
33+
}
34+
35+
fn never_slice(x: &[!]) {
36+
x[0];
37+
}
38+
39+
fn never_match(x: Result<(), !>) {
40+
match x {
41+
Ok(_) => {},
42+
Err(_) => {},
43+
}
44+
}
45+
46+
pub fn main() { }

0 commit comments

Comments
 (0)