Skip to content
4 changes: 2 additions & 2 deletions src/liballoc/btree/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,7 @@ impl<'a, K: 'a, V: 'a, NodeType>
Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> {

pub fn into_kv_mut(self) -> (&'a mut K, &'a mut V) {
let (mut keys, mut vals) = self.node.into_slices_mut();
let (keys, vals) = self.node.into_slices_mut();
unsafe {
(keys.get_unchecked_mut(self.idx), vals.get_unchecked_mut(self.idx))
}
Expand All @@ -1047,7 +1047,7 @@ impl<'a, K: 'a, V: 'a, NodeType>
impl<'a, K, V, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> {
pub fn kv_mut(&mut self) -> (&mut K, &mut V) {
unsafe {
let (mut keys, mut vals) = self.node.reborrow_mut().into_slices_mut();
let (keys, vals) = self.node.reborrow_mut().into_slices_mut();
(keys.get_unchecked_mut(self.idx), vals.get_unchecked_mut(self.idx))
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1751,7 +1751,7 @@ impl<'a, T> IntoIterator for &'a mut Vec<T> {
type Item = &'a mut T;
type IntoIter = slice::IterMut<'a, T>;

fn into_iter(mut self) -> slice::IterMut<'a, T> {
fn into_iter(self) -> slice::IterMut<'a, T> {
self.iter_mut()
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/liballoc/vec_deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2394,7 +2394,7 @@ impl<'a, T> IntoIterator for &'a mut VecDeque<T> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;

fn into_iter(mut self) -> IterMut<'a, T> {
fn into_iter(self) -> IterMut<'a, T> {
self.iter_mut()
}
}
Expand Down Expand Up @@ -2558,7 +2558,7 @@ impl<'a, T> Place<T> for PlaceBack<'a, T> {
impl<'a, T> InPlace<T> for PlaceBack<'a, T> {
type Owner = &'a mut T;

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

unsafe fn finalize(mut self) -> &'a mut T {
unsafe fn finalize(self) -> &'a mut T {
self.vec_deque.tail = self.vec_deque.wrap_sub(self.vec_deque.tail, 1);
&mut *(self.vec_deque.ptr().offset(self.vec_deque.tail as isize))
}
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/ops/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ mod impls {
where F : FnMut<A>
{
type Output = F::Output;
extern "rust-call" fn call_once(mut self, args: A) -> F::Output {
extern "rust-call" fn call_once(self, args: A) -> F::Output {
(*self).call_mut(args)
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ impl<'a, T> IntoIterator for &'a mut Option<T> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;

fn into_iter(mut self) -> IterMut<'a, T> {
fn into_iter(self) -> IterMut<'a, T> {
self.iter_mut()
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,7 @@ impl<'a, T, E> IntoIterator for &'a mut Result<T, E> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;

fn into_iter(mut self) -> IterMut<'a, T> {
fn into_iter(self) -> IterMut<'a, T> {
self.iter_mut()
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/libcore/tests/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,27 +105,27 @@ fn test_chunks_last() {

#[test]
fn test_chunks_mut_count() {
let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
let c = v.chunks_mut(3);
assert_eq!(c.count(), 2);

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

let mut v3: &mut [i32] = &mut [];
let v3: &mut [i32] = &mut [];
let c3 = v3.chunks_mut(2);
assert_eq!(c3.count(), 0);
}

#[test]
fn test_chunks_mut_nth() {
let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
let mut c = v.chunks_mut(2);
assert_eq!(c.nth(1).unwrap()[1], 3);
assert_eq!(c.next().unwrap()[0], 4);

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

#[test]
fn get_mut_range() {
let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
assert_eq!(v.get_mut(..), Some(&mut [0, 1, 2, 3, 4, 5][..]));
assert_eq!(v.get_mut(..2), Some(&mut [0, 1][..]));
assert_eq!(v.get_mut(2..), Some(&mut [2, 3, 4, 5][..]));
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,8 +415,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
/// -------- this type is the same as a type argument in the other type, not highlighted
/// ```
fn highlight_outer(&self,
mut value: &mut DiagnosticStyledString,
mut other_value: &mut DiagnosticStyledString,
value: &mut DiagnosticStyledString,
other_value: &mut DiagnosticStyledString,
name: String,
sub: &ty::subst::Substs<'tcx>,
pos: usize,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ pub fn fully_normalize<'a, 'gcx, 'tcx, T>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
{
debug!("fully_normalize(value={:?})", value);

let mut selcx = &mut SelectionContext::new(infcx);
let selcx = &mut SelectionContext::new(infcx);
// FIXME (@jroesch) ISSUE 26721
// I'm not sure if this is a bug or not, needs further investigation.
// It appears that by reusing the fulfillment_cx here we incur more
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
never_obligation.predicate = never_obligation.predicate.map_bound(|mut trait_pred| {
// Swap out () with ! so we can check if the trait is impld for !
{
let mut trait_ref = &mut trait_pred.trait_ref;
let trait_ref = &mut trait_pred.trait_ref;
let unit_substs = trait_ref.substs;
let mut never_substs = Vec::with_capacity(unit_substs.len());
never_substs.push(From::from(tcx.types.never));
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/ty/inhabitedness/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
match self.sty {
TyAdt(def, substs) => {
{
let mut substs_set = visited.entry(def.did).or_insert(FxHashSet::default());
let substs_set = visited.entry(def.did).or_insert(FxHashSet::default());
if !substs_set.insert(substs) {
// We are already calculating the inhabitedness of this type.
// The type must contain a reference to itself. Break the
Expand All @@ -193,7 +193,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
}
}
let ret = def.uninhabited_from(visited, tcx, substs);
let mut substs_set = visited.get_mut(&def.did).unwrap();
let substs_set = visited.get_mut(&def.did).unwrap();
substs_set.remove(substs);
ret
},
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_allocator/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ impl<'a> AllocFnFactory<'a> {
fn arg_ty(&self,
ty: &AllocatorTy,
args: &mut Vec<Arg>,
mut ident: &mut FnMut() -> Ident) -> P<Expr> {
ident: &mut FnMut() -> Ident) -> P<Expr> {
match *ty {
AllocatorTy::Layout => {
let usize = self.cx.path_ident(self.span, Ident::from_str("usize"));
Expand Down Expand Up @@ -263,7 +263,7 @@ impl<'a> AllocFnFactory<'a> {
fn ret_ty(&self,
ty: &AllocatorTy,
args: &mut Vec<Arg>,
mut ident: &mut FnMut() -> Ident,
ident: &mut FnMut() -> Ident,
expr: P<Expr>) -> (P<Ty>, P<Expr>)
{
match *ty {
Expand Down
44 changes: 32 additions & 12 deletions src/librustc_borrowck/borrowck/gather_loans/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,20 +436,40 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
//! For mutable loans of content whose mutability derives
//! from a local variable, mark the mutability decl as necessary.

match loan_path.kind {
LpVar(local_id) |
LpUpvar(ty::UpvarId{ var_id: local_id, closure_expr_id: _ }) => {
self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
}
LpDowncast(ref base, _) |
LpExtend(ref base, mc::McInherited, _) |
LpExtend(ref base, mc::McDeclared, _) => {
self.mark_loan_path_as_mutated(&base);
}
LpExtend(_, mc::McImmutable, _) => {
// Nothing to do.
let mut wrapped_path = Some(loan_path);
let mut through_borrow = false;

while let Some(current_path) = wrapped_path {
wrapped_path = match current_path.kind {
LpVar(local_id) => {
if !through_borrow {
self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
}
None
}
LpUpvar(ty::UpvarId{ var_id: local_id, closure_expr_id: _ }) => {
self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No through_borrow here?

fn main() {
    let mut z = 0;
    let mut x = &mut z;
    let mut klos = || {
        *x = 1;
    };
    klos();
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's not needed because closures don't borrow mutably (they borrow uniquely) unless they have to. But please add a test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm don't understand your example: This already gives a warning for x being mut, even with the new code. through_borrow is always true reaching the upvar case, since it is always wrapped in a LpExtend(.., .., LpDeref(..)).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. I understand why it works. Just add it as a test to make sure it does work, because it could be an edge case (e.g. when we move to MIR borrowck, we'll like to keep everything working).

None
}
LpExtend(ref base, mc::McInherited, LpDeref(pointer_kind)) |
LpExtend(ref base, mc::McDeclared, LpDeref(pointer_kind)) => {
if pointer_kind != mc::Unique {
through_borrow = true;
}
Some(base)
}
LpDowncast(ref base, _) |
LpExtend(ref base, mc::McInherited, _) |
LpExtend(ref base, mc::McDeclared, _) => {
Some(base)
}
LpExtend(_, mc::McImmutable, _) => {
// Nothing to do.
None
}
}
}

}

pub fn compute_gen_scope(&self,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_borrowck/borrowck/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) {
let body_id = tcx.hir.body_owned_by(owner_id);
let tables = tcx.typeck_tables_of(owner_def_id);
let region_maps = tcx.region_maps(owner_def_id);
let mut bccx = &mut BorrowckCtxt { tcx, tables, region_maps, owner_def_id };
let bccx = &mut BorrowckCtxt { tcx, tables, region_maps, owner_def_id };

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

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_data_structures/array_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ impl<'a, A: Array> Drop for Drain<'a, A> {
let start = source_array_vec.len();
let tail = self.tail_start;
{
let mut arr = &mut source_array_vec.values as &mut [ManuallyDrop<_>];
let arr = &mut source_array_vec.values as &mut [ManuallyDrop<_>];
let src = arr.as_ptr().offset(tail as isize);
let dst = arr.as_mut_ptr().offset(start as isize);
ptr::copy(src, dst, self.tail_len);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_data_structures/bitvec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ impl BitMatrix {
pub fn add(&mut self, source: usize, target: usize) -> bool {
let (start, _) = self.range(source);
let (word, mask) = word_mask(target);
let mut vector = &mut self.vector[..];
let vector = &mut self.vector[..];
let v1 = vector[start + word];
let v2 = v1 | mask;
vector[start + word] = v2;
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_data_structures/indexed_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec<I, T> {
type IntoIter = slice::IterMut<'a, T>;

#[inline]
fn into_iter(mut self) -> slice::IterMut<'a, T> {
fn into_iter(self) -> slice::IterMut<'a, T> {
self.raw.iter_mut()
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ fn show_content_with_pager(content: &String) {

match Command::new(pager_name).stdin(Stdio::piped()).spawn() {
Ok(mut pager) => {
if let Some(mut pipe) = pager.stdin.as_mut() {
if let Some(pipe) = pager.stdin.as_mut() {
if pipe.write_all(content.as_bytes()).is_err() {
fallback_to_println = true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_metadata/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ impl CrateStore for cstore::CStore {
_ => {},
}

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

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/build/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
self.schedule_drop(span, extent, &Lvalue::Local(local_id), var_ty);
}

pub fn visit_bindings<F>(&mut self, pattern: &Pattern<'tcx>, mut f: &mut F)
pub fn visit_bindings<F>(&mut self, pattern: &Pattern<'tcx>, f: &mut F)
where F: FnMut(&mut Self, Mutability, Name, NodeId, Span, Ty<'tcx>)
{
match *pattern.kind {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/transform/type_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
value,
obligations);

let mut fulfill_cx = &mut self.fulfillment_cx;
let fulfill_cx = &mut self.fulfillment_cx;
for obligation in obligations {
fulfill_cx.register_predicate_obligation(self.infcx, obligation);
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_privacy/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
hir::ItemTrait(.., ref trait_item_refs) => {
self.check_item(item.id).generics().predicates();
for trait_item_ref in trait_item_refs {
let mut check = self.check_item(trait_item_ref.id.node_id);
let check = self.check_item(trait_item_ref.id.node_id);
check.generics().predicates();
if trait_item_ref.kind != hir::AssociatedItemKind::Type ||
trait_item_ref.defaultness.has_value() {
Expand Down Expand Up @@ -814,7 +814,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
}
hir::ItemImpl(.., ref trait_ref, _, ref impl_item_refs) => {
{
let mut check = self.check_item(item.id);
let check = self.check_item(item.id);
check.ty().generics().predicates();
if trait_ref.is_some() {
check.impl_trait_ref();
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_resolve/resolve_imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ impl<'a> Resolver<'a> {
// Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
// during which the resolution might end up getting re-defined via a glob cycle.
let (binding, t) = {
let mut resolution = &mut *self.resolution(module, ident, ns).borrow_mut();
let resolution = &mut *self.resolution(module, ident, ns).borrow_mut();
let old_binding = resolution.binding();

let t = f(self, resolution);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1465,7 +1465,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
let mut output = i.to_string(scx.tcx());
output.push_str(" @@");
let mut empty = Vec::new();
let mut cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
cgus.as_mut_slice().sort_by_key(|&(ref name, _)| name.clone());
cgus.dedup();
for &(ref cgu_name, (linkage, _)) in cgus.iter() {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/partitioning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ fn place_root_translation_items<'a, 'tcx, I>(scx: &SharedCrateContext<'a, 'tcx>,
CodegenUnit::empty(codegen_unit_name.clone())
};

let mut codegen_unit = codegen_units.entry(codegen_unit_name.clone())
let codegen_unit = codegen_units.entry(codegen_unit_name.clone())
.or_insert_with(make_codegen_unit);

let (linkage, visibility) = match trans_item.explicit_linkage(tcx) {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_trans/time_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ impl TimeGraph {
{
let mut table = self.data.lock().unwrap();

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

let mut table = self.data.lock().unwrap();
let mut data = table.get_mut(&timeline).unwrap();
let data = table.get_mut(&timeline).unwrap();

if let Some((start, work_package_kind)) = data.open_work_package {
data.timings.push(Timing {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1204,7 +1204,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
}
}

if let Some(mut augment_error) = augment_error {
if let Some(augment_error) = augment_error {
augment_error(&mut db);
}

Expand Down
Loading