commit
561d0884e5
@ -2490,6 +2490,8 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
// of arguments when we typecheck the functions. This isn't really the
|
||||
// right way to do this.
|
||||
let xs = [false, true];
|
||||
let mut any_diverges = false; // has any of the arguments diverged?
|
||||
let mut warned = false; // have we already warned about unreachable code?
|
||||
for check_blocks in &xs {
|
||||
let check_blocks = *check_blocks;
|
||||
debug!("check_blocks={}", check_blocks);
|
||||
@ -2512,6 +2514,16 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
supplied_arg_count
|
||||
};
|
||||
for (i, arg) in args.iter().take(t).enumerate() {
|
||||
if any_diverges && !warned {
|
||||
fcx.ccx
|
||||
.tcx
|
||||
.sess
|
||||
.add_lint(lint::builtin::UNREACHABLE_CODE,
|
||||
arg.id,
|
||||
arg.span,
|
||||
"unreachable expression".to_string());
|
||||
warned = true;
|
||||
}
|
||||
let is_block = match arg.node {
|
||||
hir::ExprClosure(..) => true,
|
||||
_ => false
|
||||
@ -2542,7 +2554,23 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
coerce_ty.map(|ty| demand::suptype(fcx, arg.span, formal_ty, ty));
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(&arg_ty) = fcx.inh.tables.borrow().node_types.get(&arg.id) {
|
||||
any_diverges = any_diverges || fcx.infcx().type_var_diverges(arg_ty);
|
||||
}
|
||||
}
|
||||
if any_diverges && !warned {
|
||||
let parent = fcx.ccx.tcx.map.get_parent_node(args[0].id);
|
||||
fcx.ccx
|
||||
.tcx
|
||||
.sess
|
||||
.add_lint(lint::builtin::UNREACHABLE_CODE,
|
||||
parent,
|
||||
sp,
|
||||
"unreachable call".to_string());
|
||||
warned = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// We also need to make sure we at least write the ty of the other
|
||||
|
@ -678,9 +678,9 @@ impl<'a> ExtCtxt<'a> {
|
||||
pub fn bt_push(&mut self, ei: ExpnInfo) {
|
||||
self.recursion_count += 1;
|
||||
if self.recursion_count > self.ecfg.recursion_limit {
|
||||
panic!(self.span_fatal(ei.call_site,
|
||||
self.span_fatal(ei.call_site,
|
||||
&format!("recursion limit reached while expanding the macro `{}`",
|
||||
ei.callee.name())));
|
||||
ei.callee.name()));
|
||||
}
|
||||
|
||||
let mut call_site = ei.call_site;
|
||||
|
@ -209,12 +209,12 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
|
||||
best_fail_msg = (*msg).clone();
|
||||
},
|
||||
Error(err_sp, ref msg) => {
|
||||
panic!(cx.span_fatal(err_sp.substitute_dummy(sp), &msg[..]))
|
||||
cx.span_fatal(err_sp.substitute_dummy(sp), &msg[..])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
panic!(cx.span_fatal(best_fail_spot.substitute_dummy(sp), &best_fail_msg[..]));
|
||||
cx.span_fatal(best_fail_spot.substitute_dummy(sp), &best_fail_msg[..]);
|
||||
}
|
||||
|
||||
// Note that macro-by-example's input is also matched against a token tree:
|
||||
|
32
src/test/compile-fail/unreachable-in-call.rs
Normal file
32
src/test/compile-fail/unreachable-in-call.rs
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![deny(unreachable_code)]
|
||||
|
||||
fn diverge() -> ! { panic!() }
|
||||
|
||||
fn get_u8() -> u8 {
|
||||
1
|
||||
}
|
||||
fn call(_: u8, _: u8) {
|
||||
|
||||
}
|
||||
fn diverge_first() {
|
||||
call(diverge(),
|
||||
get_u8()); //~ ERROR unreachable expression
|
||||
}
|
||||
fn diverge_second() {
|
||||
call( //~ ERROR unreachable call
|
||||
get_u8(),
|
||||
diverge());
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user