Skip to content

Commit 79252ff

Browse files
committed
Auto merge of #48605 - KiChjang:unused-mut-warning, r=nikomatsakis
Allow MIR borrowck to catch unused mutable locals Fixes #47279. r? @nikomatsakis
2 parents 96e1828 + 0a1cb9b commit 79252ff

File tree

8 files changed

+414
-119
lines changed

8 files changed

+414
-119
lines changed

src/librustc/ich/impls_mir.rs

+5
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,11 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for mir::Literal<'gcx> {
563563

564564
impl_stable_hash_for!(struct mir::Location { block, statement_index });
565565

566+
impl_stable_hash_for!(struct mir::BorrowCheckResult<'tcx> {
567+
closure_requirements,
568+
used_mut_upvars
569+
});
570+
566571
impl_stable_hash_for!(struct mir::ClosureRegionRequirements<'tcx> {
567572
num_external_vids,
568573
outlives_requirements

src/librustc/mir/mod.rs

+23
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx};
2121
use rustc_data_structures::control_flow_graph::dominators::{Dominators, dominators};
2222
use rustc_data_structures::control_flow_graph::{GraphPredecessors, GraphSuccessors};
2323
use rustc_data_structures::control_flow_graph::ControlFlowGraph;
24+
use rustc_data_structures::small_vec::SmallVec;
2425
use rustc_serialize as serialize;
2526
use hir::def::CtorKind;
2627
use hir::def_id::DefId;
@@ -247,6 +248,22 @@ impl<'tcx> Mir<'tcx> {
247248
})
248249
}
249250

251+
/// Returns an iterator over all user-declared mutable arguments and locals.
252+
#[inline]
253+
pub fn mut_vars_and_args_iter<'a>(&'a self) -> impl Iterator<Item=Local> + 'a {
254+
(1..self.local_decls.len()).filter_map(move |index| {
255+
let local = Local::new(index);
256+
let decl = &self.local_decls[local];
257+
if (decl.is_user_variable || index < self.arg_count + 1)
258+
&& decl.mutability == Mutability::Mut
259+
{
260+
Some(local)
261+
} else {
262+
None
263+
}
264+
})
265+
}
266+
250267
/// Returns an iterator over all function arguments.
251268
#[inline]
252269
pub fn args_iter(&self) -> impl Iterator<Item=Local> {
@@ -2029,6 +2046,12 @@ pub struct GeneratorLayout<'tcx> {
20292046
pub fields: Vec<LocalDecl<'tcx>>,
20302047
}
20312048

2049+
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
2050+
pub struct BorrowCheckResult<'gcx> {
2051+
pub closure_requirements: Option<ClosureRegionRequirements<'gcx>>,
2052+
pub used_mut_upvars: SmallVec<[Field; 8]>,
2053+
}
2054+
20322055
/// After we borrow check a closure, we are left with various
20332056
/// requirements that we have inferred between the free regions that
20342057
/// appear in the closure's signature or on its field types. These

src/librustc/ty/maps/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ define_maps! { <'tcx>
211211

212212
/// Borrow checks the function body. If this is a closure, returns
213213
/// additional requirements that the closure's creator must verify.
214-
[] fn mir_borrowck: MirBorrowCheck(DefId) -> Option<mir::ClosureRegionRequirements<'tcx>>,
214+
[] fn mir_borrowck: MirBorrowCheck(DefId) -> mir::BorrowCheckResult<'tcx>,
215215

216216
/// Gets a complete map from all types to their inherent impls.
217217
/// Not meant to be used directly outside of coherence.

src/librustc_borrowck/borrowck/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,10 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
144144
{
145145
check_loans::check_loans(&mut bccx, &loan_dfcx, &flowed_moves, &all_loans, body);
146146
}
147-
unused::check(&mut bccx, body);
147+
148+
if !tcx.use_mir_borrowck() {
149+
unused::check(&mut bccx, body);
150+
}
148151

149152
Lrc::new(BorrowCheckResult {
150153
used_mut_nodes: bccx.used_mut_nodes.into_inner(),

0 commit comments

Comments
 (0)