Skip to content

Commit

Permalink
Make unreachable_code lint warn on diverging call arguments as well
Browse files Browse the repository at this point in the history
  • Loading branch information
Manishearth committed Nov 23, 2015
1 parent 4891c00 commit 2eca64d
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/librustc_typeck/check/mod.rs
Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
37 changes: 37 additions & 0 deletions src/test/compile-fail/unreachable-in-call.rs
@@ -0,0 +1,37 @@
// 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.

// Test that the unboxed closure sugar can be used with an arbitrary
// struct type and that it is equivalent to the same syntax using
// angle brackets. This test covers only simple types and in
// particular doesn't test bound regions.

#![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() {}

0 comments on commit 2eca64d

Please sign in to comment.