Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed mutable vars being marked used when they weren't #43582

Merged
merged 11 commits into from
Aug 10, 2017
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