Auto merge of #48605 - KiChjang:unused-mut-warning, r=nikomatsakis

Allow MIR borrowck to catch unused mutable locals

Fixes #47279.

r? @nikomatsakis
This commit is contained in:
bors 2018-04-29 16:25:04 +00:00
commit 79252ff4e2
8 changed files with 414 additions and 119 deletions

View file

@ -563,6 +563,11 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Literal<'gcx> {
impl_stable_hash_for!(struct mir::Location { block, statement_index });
impl_stable_hash_for!(struct mir::BorrowCheckResult<'tcx> {
closure_requirements,
used_mut_upvars
});
impl_stable_hash_for!(struct mir::ClosureRegionRequirements<'tcx> {
num_external_vids,
outlives_requirements

View file

@ -21,6 +21,7 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use rustc_data_structures::control_flow_graph::dominators::{Dominators, dominators};
use rustc_data_structures::control_flow_graph::{GraphPredecessors, GraphSuccessors};
use rustc_data_structures::control_flow_graph::ControlFlowGraph;
use rustc_data_structures::small_vec::SmallVec;
use rustc_serialize as serialize;
use hir::def::CtorKind;
use hir::def_id::DefId;
@ -247,6 +248,22 @@ impl<'tcx> Mir<'tcx> {
})
}
/// Returns an iterator over all user-declared mutable arguments and locals.
#[inline]
pub fn mut_vars_and_args_iter<'a>(&'a self) -> impl Iterator<Item=Local> + 'a {
(1..self.local_decls.len()).filter_map(move |index| {
let local = Local::new(index);
let decl = &self.local_decls[local];
if (decl.is_user_variable || index < self.arg_count + 1)
&& decl.mutability == Mutability::Mut
{
Some(local)
} else {
None
}
})
}
/// Returns an iterator over all function arguments.
#[inline]
pub fn args_iter(&self) -> impl Iterator<Item=Local> {
@ -2029,6 +2046,12 @@ pub struct GeneratorLayout<'tcx> {
pub fields: Vec<LocalDecl<'tcx>>,
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct BorrowCheckResult<'gcx> {
pub closure_requirements: Option<ClosureRegionRequirements<'gcx>>,
pub used_mut_upvars: SmallVec<[Field; 8]>,
}
/// After we borrow check a closure, we are left with various
/// requirements that we have inferred between the free regions that
/// appear in the closure's signature or on its field types. These

View file

@ -211,7 +211,7 @@ define_maps! { <'tcx>
/// Borrow checks the function body. If this is a closure, returns
/// additional requirements that the closure's creator must verify.
[] fn mir_borrowck: MirBorrowCheck(DefId) -> Option<mir::ClosureRegionRequirements<'tcx>>,
[] fn mir_borrowck: MirBorrowCheck(DefId) -> mir::BorrowCheckResult<'tcx>,
/// Gets a complete map from all types to their inherent impls.
/// Not meant to be used directly outside of coherence.