Skip to content

Commit d21ec9b

Browse files
committed
Auto merge of #43582 - ivanbakel:unused_mut_ref, r=arielb1
Fixed mutable vars being marked used when they weren't #### NB : bootstrapping is slow on my machine, even with `keep-stage` - fixes for occurances in the current codebase are <s>in the pipeline</s> done. This PR is being put up for review of the fix of the issue. Fixes #43526, Fixes #30280, Fixes #25049 ### Issue Whenever the compiler detected a mutable deref being used mutably, it marked an associated value as being used mutably as well. In the case of derefencing local variables which were mutable references, this incorrectly marked the reference itself being used mutably, instead of its contents - with the consequence of making the following code emit no warnings ``` fn do_thing<T>(mut arg : &mut T) { ... // don't touch arg - just deref it to access the T } ``` ### Fix Make dereferences not be counted as a mutable use, but only when they're on borrows on local variables. #### Why not on things other than local variables? * Whenever you capture a variable in a closure, it gets turned into a hidden reference - when you use it in the closure, it gets dereferenced. If the closure uses the variable mutably, that is actually a mutable use of the thing being dereffed to, so it has to be counted. * If you deref a mutable `Box` to access the contents mutably, you are using the `Box` mutably - so it has to be counted.
2 parents 2ac5f7d + 8f78d45 commit d21ec9b

File tree

42 files changed

+110
-70
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+110
-70
lines changed

src/liballoc/btree/node.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,7 @@ impl<'a, K: 'a, V: 'a, NodeType>
10371037
Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> {
10381038

10391039
pub fn into_kv_mut(self) -> (&'a mut K, &'a mut V) {
1040-
let (mut keys, mut vals) = self.node.into_slices_mut();
1040+
let (keys, vals) = self.node.into_slices_mut();
10411041
unsafe {
10421042
(keys.get_unchecked_mut(self.idx), vals.get_unchecked_mut(self.idx))
10431043
}
@@ -1047,7 +1047,7 @@ impl<'a, K: 'a, V: 'a, NodeType>
10471047
impl<'a, K, V, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> {
10481048
pub fn kv_mut(&mut self) -> (&mut K, &mut V) {
10491049
unsafe {
1050-
let (mut keys, mut vals) = self.node.reborrow_mut().into_slices_mut();
1050+
let (keys, vals) = self.node.reborrow_mut().into_slices_mut();
10511051
(keys.get_unchecked_mut(self.idx), vals.get_unchecked_mut(self.idx))
10521052
}
10531053
}

src/liballoc/vec.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1751,7 +1751,7 @@ impl<'a, T> IntoIterator for &'a mut Vec<T> {
17511751
type Item = &'a mut T;
17521752
type IntoIter = slice::IterMut<'a, T>;
17531753

1754-
fn into_iter(mut self) -> slice::IterMut<'a, T> {
1754+
fn into_iter(self) -> slice::IterMut<'a, T> {
17551755
self.iter_mut()
17561756
}
17571757
}

src/liballoc/vec_deque.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2394,7 +2394,7 @@ impl<'a, T> IntoIterator for &'a mut VecDeque<T> {
23942394
type Item = &'a mut T;
23952395
type IntoIter = IterMut<'a, T>;
23962396

2397-
fn into_iter(mut self) -> IterMut<'a, T> {
2397+
fn into_iter(self) -> IterMut<'a, T> {
23982398
self.iter_mut()
23992399
}
24002400
}
@@ -2558,7 +2558,7 @@ impl<'a, T> Place<T> for PlaceBack<'a, T> {
25582558
impl<'a, T> InPlace<T> for PlaceBack<'a, T> {
25592559
type Owner = &'a mut T;
25602560

2561-
unsafe fn finalize(mut self) -> &'a mut T {
2561+
unsafe fn finalize(self) -> &'a mut T {
25622562
let head = self.vec_deque.head;
25632563
self.vec_deque.head = self.vec_deque.wrap_add(head, 1);
25642564
&mut *(self.vec_deque.ptr().offset(head as isize))
@@ -2605,7 +2605,7 @@ impl<'a, T> Place<T> for PlaceFront<'a, T> {
26052605
impl<'a, T> InPlace<T> for PlaceFront<'a, T> {
26062606
type Owner = &'a mut T;
26072607

2608-
unsafe fn finalize(mut self) -> &'a mut T {
2608+
unsafe fn finalize(self) -> &'a mut T {
26092609
self.vec_deque.tail = self.vec_deque.wrap_sub(self.vec_deque.tail, 1);
26102610
&mut *(self.vec_deque.ptr().offset(self.vec_deque.tail as isize))
26112611
}

src/libcore/ops/function.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ mod impls {
187187
where F : FnMut<A>
188188
{
189189
type Output = F::Output;
190-
extern "rust-call" fn call_once(mut self, args: A) -> F::Output {
190+
extern "rust-call" fn call_once(self, args: A) -> F::Output {
191191
(*self).call_mut(args)
192192
}
193193
}

src/libcore/option.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ impl<'a, T> IntoIterator for &'a mut Option<T> {
872872
type Item = &'a mut T;
873873
type IntoIter = IterMut<'a, T>;
874874

875-
fn into_iter(mut self) -> IterMut<'a, T> {
875+
fn into_iter(self) -> IterMut<'a, T> {
876876
self.iter_mut()
877877
}
878878
}

src/libcore/result.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ impl<'a, T, E> IntoIterator for &'a mut Result<T, E> {
909909
type Item = &'a mut T;
910910
type IntoIter = IterMut<'a, T>;
911911

912-
fn into_iter(mut self) -> IterMut<'a, T> {
912+
fn into_iter(self) -> IterMut<'a, T> {
913913
self.iter_mut()
914914
}
915915
}

src/libcore/tests/slice.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -105,27 +105,27 @@ fn test_chunks_last() {
105105

106106
#[test]
107107
fn test_chunks_mut_count() {
108-
let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
108+
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
109109
let c = v.chunks_mut(3);
110110
assert_eq!(c.count(), 2);
111111

112-
let mut v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
112+
let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
113113
let c2 = v2.chunks_mut(2);
114114
assert_eq!(c2.count(), 3);
115115

116-
let mut v3: &mut [i32] = &mut [];
116+
let v3: &mut [i32] = &mut [];
117117
let c3 = v3.chunks_mut(2);
118118
assert_eq!(c3.count(), 0);
119119
}
120120

121121
#[test]
122122
fn test_chunks_mut_nth() {
123-
let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
123+
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
124124
let mut c = v.chunks_mut(2);
125125
assert_eq!(c.nth(1).unwrap()[1], 3);
126126
assert_eq!(c.next().unwrap()[0], 4);
127127

128-
let mut v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
128+
let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
129129
let mut c2 = v2.chunks_mut(3);
130130
assert_eq!(c2.nth(1).unwrap()[1], 4);
131131
assert_eq!(c2.next(), None);
@@ -194,7 +194,7 @@ fn get_range() {
194194

195195
#[test]
196196
fn get_mut_range() {
197-
let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
197+
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
198198
assert_eq!(v.get_mut(..), Some(&mut [0, 1, 2, 3, 4, 5][..]));
199199
assert_eq!(v.get_mut(..2), Some(&mut [0, 1][..]));
200200
assert_eq!(v.get_mut(2..), Some(&mut [2, 3, 4, 5][..]));

src/librustc/infer/error_reporting/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
415415
/// -------- this type is the same as a type argument in the other type, not highlighted
416416
/// ```
417417
fn highlight_outer(&self,
418-
mut value: &mut DiagnosticStyledString,
419-
mut other_value: &mut DiagnosticStyledString,
418+
value: &mut DiagnosticStyledString,
419+
other_value: &mut DiagnosticStyledString,
420420
name: String,
421421
sub: &ty::subst::Substs<'tcx>,
422422
pos: usize,

src/librustc/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ pub fn fully_normalize<'a, 'gcx, 'tcx, T>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
560560
{
561561
debug!("fully_normalize(value={:?})", value);
562562

563-
let mut selcx = &mut SelectionContext::new(infcx);
563+
let selcx = &mut SelectionContext::new(infcx);
564564
// FIXME (@jroesch) ISSUE 26721
565565
// I'm not sure if this is a bug or not, needs further investigation.
566566
// It appears that by reusing the fulfillment_cx here we incur more

src/librustc/traits/select.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
494494
never_obligation.predicate = never_obligation.predicate.map_bound(|mut trait_pred| {
495495
// Swap out () with ! so we can check if the trait is impld for !
496496
{
497-
let mut trait_ref = &mut trait_pred.trait_ref;
497+
let trait_ref = &mut trait_pred.trait_ref;
498498
let unit_substs = trait_ref.substs;
499499
let mut never_substs = Vec::with_capacity(unit_substs.len());
500500
never_substs.push(From::from(tcx.types.never));

src/librustc/ty/inhabitedness/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
171171
match self.sty {
172172
TyAdt(def, substs) => {
173173
{
174-
let mut substs_set = visited.entry(def.did).or_insert(FxHashSet::default());
174+
let substs_set = visited.entry(def.did).or_insert(FxHashSet::default());
175175
if !substs_set.insert(substs) {
176176
// We are already calculating the inhabitedness of this type.
177177
// The type must contain a reference to itself. Break the
@@ -193,7 +193,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
193193
}
194194
}
195195
let ret = def.uninhabited_from(visited, tcx, substs);
196-
let mut substs_set = visited.get_mut(&def.did).unwrap();
196+
let substs_set = visited.get_mut(&def.did).unwrap();
197197
substs_set.remove(substs);
198198
ret
199199
},

src/librustc_allocator/expand.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ impl<'a> AllocFnFactory<'a> {
188188
fn arg_ty(&self,
189189
ty: &AllocatorTy,
190190
args: &mut Vec<Arg>,
191-
mut ident: &mut FnMut() -> Ident) -> P<Expr> {
191+
ident: &mut FnMut() -> Ident) -> P<Expr> {
192192
match *ty {
193193
AllocatorTy::Layout => {
194194
let usize = self.cx.path_ident(self.span, Ident::from_str("usize"));
@@ -263,7 +263,7 @@ impl<'a> AllocFnFactory<'a> {
263263
fn ret_ty(&self,
264264
ty: &AllocatorTy,
265265
args: &mut Vec<Arg>,
266-
mut ident: &mut FnMut() -> Ident,
266+
ident: &mut FnMut() -> Ident,
267267
expr: P<Expr>) -> (P<Ty>, P<Expr>)
268268
{
269269
match *ty {

src/librustc_borrowck/borrowck/gather_loans/mod.rs

+32-12
Original file line numberDiff line numberDiff line change
@@ -436,20 +436,40 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
436436
//! For mutable loans of content whose mutability derives
437437
//! from a local variable, mark the mutability decl as necessary.
438438
439-
match loan_path.kind {
440-
LpVar(local_id) |
441-
LpUpvar(ty::UpvarId{ var_id: local_id, closure_expr_id: _ }) => {
442-
self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
443-
}
444-
LpDowncast(ref base, _) |
445-
LpExtend(ref base, mc::McInherited, _) |
446-
LpExtend(ref base, mc::McDeclared, _) => {
447-
self.mark_loan_path_as_mutated(&base);
448-
}
449-
LpExtend(_, mc::McImmutable, _) => {
450-
// Nothing to do.
439+
let mut wrapped_path = Some(loan_path);
440+
let mut through_borrow = false;
441+
442+
while let Some(current_path) = wrapped_path {
443+
wrapped_path = match current_path.kind {
444+
LpVar(local_id) => {
445+
if !through_borrow {
446+
self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
447+
}
448+
None
449+
}
450+
LpUpvar(ty::UpvarId{ var_id: local_id, closure_expr_id: _ }) => {
451+
self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
452+
None
453+
}
454+
LpExtend(ref base, mc::McInherited, LpDeref(pointer_kind)) |
455+
LpExtend(ref base, mc::McDeclared, LpDeref(pointer_kind)) => {
456+
if pointer_kind != mc::Unique {
457+
through_borrow = true;
458+
}
459+
Some(base)
460+
}
461+
LpDowncast(ref base, _) |
462+
LpExtend(ref base, mc::McInherited, _) |
463+
LpExtend(ref base, mc::McDeclared, _) => {
464+
Some(base)
465+
}
466+
LpExtend(_, mc::McImmutable, _) => {
467+
// Nothing to do.
468+
None
469+
}
451470
}
452471
}
472+
453473
}
454474

455475
pub fn compute_gen_scope(&self,

src/librustc_borrowck/borrowck/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) {
9898
let body_id = tcx.hir.body_owned_by(owner_id);
9999
let tables = tcx.typeck_tables_of(owner_def_id);
100100
let region_maps = tcx.region_maps(owner_def_id);
101-
let mut bccx = &mut BorrowckCtxt { tcx, tables, region_maps, owner_def_id };
101+
let bccx = &mut BorrowckCtxt { tcx, tables, region_maps, owner_def_id };
102102

103103
let body = bccx.tcx.hir.body(body_id);
104104

src/librustc_data_structures/array_vec.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ impl<'a, A: Array> Drop for Drain<'a, A> {
260260
let start = source_array_vec.len();
261261
let tail = self.tail_start;
262262
{
263-
let mut arr = &mut source_array_vec.values as &mut [ManuallyDrop<_>];
263+
let arr = &mut source_array_vec.values as &mut [ManuallyDrop<_>];
264264
let src = arr.as_ptr().offset(tail as isize);
265265
let dst = arr.as_mut_ptr().offset(start as isize);
266266
ptr::copy(src, dst, self.tail_len);

src/librustc_data_structures/bitvec.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ impl BitMatrix {
166166
pub fn add(&mut self, source: usize, target: usize) -> bool {
167167
let (start, _) = self.range(source);
168168
let (word, mask) = word_mask(target);
169-
let mut vector = &mut self.vector[..];
169+
let vector = &mut self.vector[..];
170170
let v1 = vector[start + word];
171171
let v2 = v1 | mask;
172172
vector[start + word] = v2;

src/librustc_data_structures/indexed_vec.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec<I, T> {
259259
type IntoIter = slice::IterMut<'a, T>;
260260

261261
#[inline]
262-
fn into_iter(mut self) -> slice::IterMut<'a, T> {
262+
fn into_iter(self) -> slice::IterMut<'a, T> {
263263
self.raw.iter_mut()
264264
}
265265
}

src/librustc_driver/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ fn show_content_with_pager(content: &String) {
422422

423423
match Command::new(pager_name).stdin(Stdio::piped()).spawn() {
424424
Ok(mut pager) => {
425-
if let Some(mut pipe) = pager.stdin.as_mut() {
425+
if let Some(pipe) = pager.stdin.as_mut() {
426426
if pipe.write_all(content.as_bytes()).is_err() {
427427
fallback_to_println = true;
428428
}

src/librustc_metadata/cstore_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ impl CrateStore for cstore::CStore {
479479
_ => {},
480480
}
481481

482-
let mut bfs_queue = &mut VecDeque::new();
482+
let bfs_queue = &mut VecDeque::new();
483483
let mut add_child = |bfs_queue: &mut VecDeque<_>, child: def::Export, parent: DefId| {
484484
let child = child.def.def_id();
485485

src/librustc_mir/build/matches/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
206206
self.schedule_drop(span, extent, &Lvalue::Local(local_id), var_ty);
207207
}
208208

209-
pub fn visit_bindings<F>(&mut self, pattern: &Pattern<'tcx>, mut f: &mut F)
209+
pub fn visit_bindings<F>(&mut self, pattern: &Pattern<'tcx>, f: &mut F)
210210
where F: FnMut(&mut Self, Mutability, Name, NodeId, Span, Ty<'tcx>)
211211
{
212212
match *pattern.kind {

src/librustc_mir/transform/type_check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
721721
value,
722722
obligations);
723723

724-
let mut fulfill_cx = &mut self.fulfillment_cx;
724+
let fulfill_cx = &mut self.fulfillment_cx;
725725
for obligation in obligations {
726726
fulfill_cx.register_predicate_obligation(self.infcx, obligation);
727727
}

src/librustc_privacy/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
781781
hir::ItemTrait(.., ref trait_item_refs) => {
782782
self.check_item(item.id).generics().predicates();
783783
for trait_item_ref in trait_item_refs {
784-
let mut check = self.check_item(trait_item_ref.id.node_id);
784+
let check = self.check_item(trait_item_ref.id.node_id);
785785
check.generics().predicates();
786786
if trait_item_ref.kind != hir::AssociatedItemKind::Type ||
787787
trait_item_ref.defaultness.has_value() {
@@ -814,7 +814,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
814814
}
815815
hir::ItemImpl(.., ref trait_ref, _, ref impl_item_refs) => {
816816
{
817-
let mut check = self.check_item(item.id);
817+
let check = self.check_item(item.id);
818818
check.ty().generics().predicates();
819819
if trait_ref.is_some() {
820820
check.impl_trait_ref();

src/librustc_resolve/resolve_imports.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ impl<'a> Resolver<'a> {
379379
// Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
380380
// during which the resolution might end up getting re-defined via a glob cycle.
381381
let (binding, t) = {
382-
let mut resolution = &mut *self.resolution(module, ident, ns).borrow_mut();
382+
let resolution = &mut *self.resolution(module, ident, ns).borrow_mut();
383383
let old_binding = resolution.binding();
384384

385385
let t = f(self, resolution);

src/librustc_trans/base.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1464,7 +1464,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
14641464
let mut output = i.to_string(scx.tcx());
14651465
output.push_str(" @@");
14661466
let mut empty = Vec::new();
1467-
let mut cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
1467+
let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
14681468
cgus.as_mut_slice().sort_by_key(|&(ref name, _)| name.clone());
14691469
cgus.dedup();
14701470
for &(ref cgu_name, (linkage, _)) in cgus.iter() {

src/librustc_trans/partitioning.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ fn place_root_translation_items<'a, 'tcx, I>(scx: &SharedCrateContext<'a, 'tcx>,
335335
CodegenUnit::empty(codegen_unit_name.clone())
336336
};
337337

338-
let mut codegen_unit = codegen_units.entry(codegen_unit_name.clone())
338+
let codegen_unit = codegen_units.entry(codegen_unit_name.clone())
339339
.or_insert_with(make_codegen_unit);
340340

341341
let (linkage, visibility) = match trans_item.explicit_linkage(tcx) {

src/librustc_trans/time_graph.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ impl TimeGraph {
7070
{
7171
let mut table = self.data.lock().unwrap();
7272

73-
let mut data = table.entry(timeline).or_insert(PerThread {
73+
let data = table.entry(timeline).or_insert(PerThread {
7474
timings: Vec::new(),
7575
open_work_package: None,
7676
});
@@ -90,7 +90,7 @@ impl TimeGraph {
9090
let end = Instant::now();
9191

9292
let mut table = self.data.lock().unwrap();
93-
let mut data = table.get_mut(&timeline).unwrap();
93+
let data = table.get_mut(&timeline).unwrap();
9494

9595
if let Some((start, work_package_kind)) = data.open_work_package {
9696
data.timings.push(Timing {

src/librustc_typeck/check/coercion.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1204,7 +1204,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
12041204
}
12051205
}
12061206

1207-
if let Some(mut augment_error) = augment_error {
1207+
if let Some(augment_error) = augment_error {
12081208
augment_error(&mut db);
12091209
}
12101210

0 commit comments

Comments
 (0)