Skip to content

Commit 561d088

Browse files
committed
Auto merge of #30000 - Manishearth:unreachable-call, r=nrc
Fixes #1889
2 parents 92f96b2 + 7fbcb51 commit 561d088

File tree

4 files changed

+64
-4
lines changed

4 files changed

+64
-4
lines changed

src/librustc_typeck/check/mod.rs

+28
Original file line numberDiff line numberDiff line change
@@ -2490,6 +2490,8 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
24902490
// of arguments when we typecheck the functions. This isn't really the
24912491
// right way to do this.
24922492
let xs = [false, true];
2493+
let mut any_diverges = false; // has any of the arguments diverged?
2494+
let mut warned = false; // have we already warned about unreachable code?
24932495
for check_blocks in &xs {
24942496
let check_blocks = *check_blocks;
24952497
debug!("check_blocks={}", check_blocks);
@@ -2512,6 +2514,16 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
25122514
supplied_arg_count
25132515
};
25142516
for (i, arg) in args.iter().take(t).enumerate() {
2517+
if any_diverges && !warned {
2518+
fcx.ccx
2519+
.tcx
2520+
.sess
2521+
.add_lint(lint::builtin::UNREACHABLE_CODE,
2522+
arg.id,
2523+
arg.span,
2524+
"unreachable expression".to_string());
2525+
warned = true;
2526+
}
25152527
let is_block = match arg.node {
25162528
hir::ExprClosure(..) => true,
25172529
_ => false
@@ -2542,7 +2554,23 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
25422554
coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
25432555
});
25442556
}
2557+
2558+
if let Some(&arg_ty) = fcx.inh.tables.borrow().node_types.get(&arg.id) {
2559+
any_diverges = any_diverges || fcx.infcx().type_var_diverges(arg_ty);
2560+
}
2561+
}
2562+
if any_diverges && !warned {
2563+
let parent = fcx.ccx.tcx.map.get_parent_node(args[0].id);
2564+
fcx.ccx
2565+
.tcx
2566+
.sess
2567+
.add_lint(lint::builtin::UNREACHABLE_CODE,
2568+
parent,
2569+
sp,
2570+
"unreachable call".to_string());
2571+
warned = true;
25452572
}
2573+
25462574
}
25472575

25482576
// We also need to make sure we at least write the ty of the other

src/libsyntax/ext/base.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -678,9 +678,9 @@ impl<'a> ExtCtxt<'a> {
678678
pub fn bt_push(&mut self, ei: ExpnInfo) {
679679
self.recursion_count += 1;
680680
if self.recursion_count > self.ecfg.recursion_limit {
681-
panic!(self.span_fatal(ei.call_site,
681+
self.span_fatal(ei.call_site,
682682
&format!("recursion limit reached while expanding the macro `{}`",
683-
ei.callee.name())));
683+
ei.callee.name()));
684684
}
685685

686686
let mut call_site = ei.call_site;

src/libsyntax/ext/tt/macro_rules.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -209,12 +209,12 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
209209
best_fail_msg = (*msg).clone();
210210
},
211211
Error(err_sp, ref msg) => {
212-
panic!(cx.span_fatal(err_sp.substitute_dummy(sp), &msg[..]))
212+
cx.span_fatal(err_sp.substitute_dummy(sp), &msg[..])
213213
}
214214
}
215215
}
216216

217-
panic!(cx.span_fatal(best_fail_spot.substitute_dummy(sp), &best_fail_msg[..]));
217+
cx.span_fatal(best_fail_spot.substitute_dummy(sp), &best_fail_msg[..]);
218218
}
219219

220220
// Note that macro-by-example's input is also matched against a token tree:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2014 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+
#![allow(dead_code)]
12+
#![deny(unreachable_code)]
13+
14+
fn diverge() -> ! { panic!() }
15+
16+
fn get_u8() -> u8 {
17+
1
18+
}
19+
fn call(_: u8, _: u8) {
20+
21+
}
22+
fn diverge_first() {
23+
call(diverge(),
24+
get_u8()); //~ ERROR unreachable expression
25+
}
26+
fn diverge_second() {
27+
call( //~ ERROR unreachable call
28+
get_u8(),
29+
diverge());
30+
}
31+
32+
fn main() {}

0 commit comments

Comments
 (0)