Skip to content

Commit 02b38a2

Browse files
committed
Rollup merge of rust-lang#23066 - michaelwoerister:unreachable-if, r=pnkfelix
This PR solves rust-lang#21559 by making sure that unreachable if-expressions are not further translated. Could someone who knows their way around `trans` take a look at the changes in `controlflow.rs`? I'm not sure if any other code relies on any side-effects of translating unreachable things. cc @nikomatsakis @nrc @eddyb
2 parents d528aa9 + e05c2f8 commit 02b38a2

File tree

2 files changed

+128
-2
lines changed

2 files changed

+128
-2
lines changed

src/librustc_trans/trans/controlflow.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ pub fn trans_stmt<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
4040
let fcx = cx.fcx;
4141
debug!("trans_stmt({})", s.repr(cx.tcx()));
4242

43+
if cx.unreachable.get() {
44+
return cx;
45+
}
46+
4347
if cx.sess().asm_comments() {
4448
add_span_comment(cx, s.span, &s.repr(cx.tcx()));
4549
}
@@ -76,6 +80,11 @@ pub fn trans_stmt<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
7680
pub fn trans_stmt_semi<'blk, 'tcx>(cx: Block<'blk, 'tcx>, e: &ast::Expr)
7781
-> Block<'blk, 'tcx> {
7882
let _icx = push_ctxt("trans_stmt_semi");
83+
84+
if cx.unreachable.get() {
85+
return cx;
86+
}
87+
7988
let ty = expr_ty(cx, e);
8089
if cx.fcx.type_needs_drop(ty) {
8190
expr::trans_to_lvalue(cx, e, "stmt").bcx
@@ -89,6 +98,11 @@ pub fn trans_block<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
8998
mut dest: expr::Dest)
9099
-> Block<'blk, 'tcx> {
91100
let _icx = push_ctxt("trans_block");
101+
102+
if bcx.unreachable.get() {
103+
return bcx;
104+
}
105+
92106
let fcx = bcx.fcx;
93107
let mut bcx = bcx;
94108

@@ -141,6 +155,11 @@ pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
141155
bcx.to_str(), if_id, bcx.expr_to_string(cond), thn.id,
142156
dest.to_string(bcx.ccx()));
143157
let _icx = push_ctxt("trans_if");
158+
159+
if bcx.unreachable.get() {
160+
return bcx;
161+
}
162+
144163
let mut bcx = bcx;
145164

146165
let cond_val = unpack_result!(bcx, expr::trans(bcx, cond).to_llbool());
@@ -214,6 +233,11 @@ pub fn trans_while<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
214233
body: &ast::Block)
215234
-> Block<'blk, 'tcx> {
216235
let _icx = push_ctxt("trans_while");
236+
237+
if bcx.unreachable.get() {
238+
return bcx;
239+
}
240+
217241
let fcx = bcx.fcx;
218242

219243
// bcx
@@ -257,6 +281,11 @@ pub fn trans_loop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
257281
body: &ast::Block)
258282
-> Block<'blk, 'tcx> {
259283
let _icx = push_ctxt("trans_loop");
284+
285+
if bcx.unreachable.get() {
286+
return bcx;
287+
}
288+
260289
let fcx = bcx.fcx;
261290

262291
// bcx
@@ -296,12 +325,13 @@ pub fn trans_break_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
296325
exit: usize)
297326
-> Block<'blk, 'tcx> {
298327
let _icx = push_ctxt("trans_break_cont");
299-
let fcx = bcx.fcx;
300328

301329
if bcx.unreachable.get() {
302330
return bcx;
303331
}
304332

333+
let fcx = bcx.fcx;
334+
305335
// Locate loop that we will break to
306336
let loop_id = match opt_label {
307337
None => fcx.top_loop_scope(),
@@ -341,6 +371,11 @@ pub fn trans_ret<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
341371
retval_expr: Option<&ast::Expr>)
342372
-> Block<'blk, 'tcx> {
343373
let _icx = push_ctxt("trans_ret");
374+
375+
if bcx.unreachable.get() {
376+
return bcx;
377+
}
378+
344379
let fcx = bcx.fcx;
345380
let mut bcx = bcx;
346381
let dest = match (fcx.llretslotptr.get(), retval_expr) {
@@ -372,6 +407,10 @@ pub fn trans_fail<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
372407
let ccx = bcx.ccx();
373408
let _icx = push_ctxt("trans_fail_value");
374409

410+
if bcx.unreachable.get() {
411+
return bcx;
412+
}
413+
375414
let v_str = C_str_slice(ccx, fail_str);
376415
let loc = bcx.sess().codemap().lookup_char_pos(call_info.span.lo);
377416
let filename = token::intern_and_get_ident(&loc.file.name);
@@ -399,6 +438,10 @@ pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
399438
let ccx = bcx.ccx();
400439
let _icx = push_ctxt("trans_fail_bounds_check");
401440

441+
if bcx.unreachable.get() {
442+
return bcx;
443+
}
444+
402445
// Extract the file/line from the span
403446
let loc = bcx.sess().codemap().lookup_char_pos(call_info.span.lo);
404447
let filename = token::intern_and_get_ident(&loc.file.name);

src/test/debuginfo/unreachable-locals.rs

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,22 @@ fn after_return() {
2626
(a, ref b) => {}
2727
}
2828
for a in &[111i32] {}
29+
let test = if some_predicate() { 1 } else { 2 };
30+
while some_predicate() {
31+
let abc = !some_predicate();
32+
}
33+
loop {
34+
let abc = !some_predicate();
35+
break;
36+
}
37+
// nested block
38+
{
39+
let abc = !some_predicate();
40+
41+
{
42+
let def = !some_predicate();
43+
}
44+
}
2945
}
3046

3147
fn after_panic() {
@@ -36,6 +52,22 @@ fn after_panic() {
3652
(a, ref b) => {}
3753
}
3854
for a in &[111i32] {}
55+
let test = if some_predicate() { 1 } else { 2 };
56+
while some_predicate() {
57+
let abc = !some_predicate();
58+
}
59+
loop {
60+
let abc = !some_predicate();
61+
break;
62+
}
63+
// nested block
64+
{
65+
let abc = !some_predicate();
66+
67+
{
68+
let def = !some_predicate();
69+
}
70+
}
3971
}
4072

4173
fn after_diverging_function() {
@@ -46,6 +78,22 @@ fn after_diverging_function() {
4678
(a, ref b) => {}
4779
}
4880
for a in &[111i32] {}
81+
let test = if some_predicate() { 1 } else { 2 };
82+
while some_predicate() {
83+
let abc = !some_predicate();
84+
}
85+
loop {
86+
let abc = !some_predicate();
87+
break;
88+
}
89+
// nested block
90+
{
91+
let abc = !some_predicate();
92+
93+
{
94+
let def = !some_predicate();
95+
}
96+
}
4997
}
5098

5199
fn after_break() {
@@ -57,18 +105,50 @@ fn after_break() {
57105
(a, ref b) => {}
58106
}
59107
for a in &[111i32] {}
108+
let test = if some_predicate() { 1 } else { 2 };
109+
while some_predicate() {
110+
let abc = !some_predicate();
111+
}
112+
loop {
113+
let abc = !some_predicate();
114+
break;
115+
}
116+
// nested block
117+
{
118+
let abc = !some_predicate();
119+
120+
{
121+
let def = !some_predicate();
122+
}
123+
}
60124
}
61125
}
62126

63127
fn after_continue() {
64128
for _ in 0..10i32 {
65-
break;
129+
continue;
66130
let x = "0";
67131
let (ref y,z) = (1i32, 2u32);
68132
match (20i32, 'c') {
69133
(a, ref b) => {}
70134
}
71135
for a in &[111i32] {}
136+
let test = if some_predicate() { 1 } else { 2 };
137+
while some_predicate() {
138+
let abc = !some_predicate();
139+
}
140+
loop {
141+
let abc = !some_predicate();
142+
break;
143+
}
144+
// nested block
145+
{
146+
let abc = !some_predicate();
147+
148+
{
149+
let def = !some_predicate();
150+
}
151+
}
72152
}
73153
}
74154

@@ -83,3 +163,6 @@ fn main() {
83163
fn diverge() -> ! {
84164
panic!();
85165
}
166+
167+
fn some_predicate() -> bool { true || false }
168+

0 commit comments

Comments
 (0)