From f6bfd2c65ba2a1292be1e62dd1c61a70abccdd1a Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 24 Jun 2014 23:11:57 -0700 Subject: [PATCH] librustc: Remove cross borrowing from mutable `Box`es to `&mut`. This will break code like: fn f(x: &mut int) {} let mut a = box 1i; f(a); Change it to: fn f(x: &mut int) {} let mut a = box 1i; f(&mut *a); RFC 33; issue #10504. [breaking-change] --- src/libcollections/dlist.rs | 10 +++++----- src/libcollections/treemap.rs | 2 +- src/libcore/any.rs | 2 +- src/libgreen/sched.rs | 2 +- src/librustc/middle/typeck/infer/coercion.rs | 7 ++++++- src/librustc/util/sha2.rs | 2 +- src/libsync/raw.rs | 2 +- src/test/bench/shootout-k-nucleotide.rs | 12 ++++++------ src/test/bench/sudoku.rs | 2 +- src/test/compile-fail/borrowck-lend-flow-if.rs | 4 ++-- .../compile-fail/borrowck-lend-flow-loop.rs | 12 ++++++------ src/test/compile-fail/borrowck-lend-flow.rs | 4 ++-- src/test/compile-fail/lint-allocation.rs | 2 -- src/test/compile-fail/mut-cross-borrowing.rs | 17 +++++++++++++++++ src/test/run-pass/borrowck-mut-uniq.rs | 4 ++-- 15 files changed, 52 insertions(+), 32 deletions(-) create mode 100644 src/test/compile-fail/mut-cross-borrowing.rs diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index 0e6cbe4e038..0ae0f906893 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -156,12 +156,12 @@ impl DList { fn push_front_node(&mut self, mut new_head: Box>) { match self.list_head { None => { - self.list_tail = Rawlink::some(new_head); + self.list_tail = Rawlink::some(&mut *new_head); self.list_head = link_with_prev(new_head, Rawlink::none()); } Some(ref mut head) => { new_head.prev = Rawlink::none(); - head.prev = Rawlink::some(new_head); + head.prev = Rawlink::some(&mut *new_head); mem::swap(head, &mut new_head); head.next = Some(new_head); } @@ -188,7 +188,7 @@ impl DList { match self.list_tail.resolve() { None => return self.push_front_node(new_tail), Some(tail) => { - self.list_tail = Rawlink::some(new_tail); + self.list_tail = Rawlink::some(&mut *new_tail); tail.next = link_with_prev(new_tail, Rawlink::some(tail)); } } @@ -379,7 +379,7 @@ impl DList { #[inline] pub fn mut_iter<'a>(&'a mut self) -> MutItems<'a, T> { let head_raw = match self.list_head { - Some(ref mut h) => Rawlink::some(*h), + Some(ref mut h) => Rawlink::some(&mut **h), None => Rawlink::none(), }; MutItems{ @@ -530,7 +530,7 @@ impl<'a, A> MutItems<'a, A> { Some(prev) => prev, }; let node_own = prev_node.next.take_unwrap(); - ins_node.next = link_with_prev(node_own, Rawlink::some(ins_node)); + ins_node.next = link_with_prev(node_own, Rawlink::some(&mut *ins_node)); prev_node.next = link_with_prev(ins_node, Rawlink::some(prev_node)); self.list.length += 1; } diff --git a/src/libcollections/treemap.rs b/src/libcollections/treemap.rs index 90f08bdd9dd..78770b6db8d 100644 --- a/src/libcollections/treemap.rs +++ b/src/libcollections/treemap.rs @@ -482,7 +482,7 @@ fn mut_deref(x: &mut Option>>) -> *mut TreeNode { match *x { Some(ref mut n) => { - let n: &mut TreeNode = *n; + let n: &mut TreeNode = &mut **n; n as *mut TreeNode } None => ptr::mut_null() diff --git a/src/libcore/any.rs b/src/libcore/any.rs index 0b621863e2c..4a35dde08eb 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -183,7 +183,7 @@ mod tests { let mut b = box 7u; let a_r = &mut a as &mut Any; - let tmp: &mut uint = b; + let tmp: &mut uint = &mut *b; let b_r = tmp as &mut Any; match a_r.as_mut::() { diff --git a/src/libgreen/sched.rs b/src/libgreen/sched.rs index 0402a93e468..f8272e5f237 100644 --- a/src/libgreen/sched.rs +++ b/src/libgreen/sched.rs @@ -641,7 +641,7 @@ impl Scheduler { }; let (current_task_context, next_task_context) = - Scheduler::get_contexts(current_task, next_task); + Scheduler::get_contexts(current_task, &mut *next_task); // Done with everything - put the next task in TLS. This // works because due to transmute the borrow checker diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/typeck/infer/coercion.rs index 2b330544239..f8efb3c38c2 100644 --- a/src/librustc/middle/typeck/infer/coercion.rs +++ b/src/librustc/middle/typeck/infer/coercion.rs @@ -248,7 +248,12 @@ impl<'f> Coerce<'f> { let r_borrow = self.get_ref().infcx.next_region_var(coercion); let inner_ty = match *sty_a { - ty::ty_box(typ) | ty::ty_uniq(typ) => typ, + ty::ty_box(typ) | ty::ty_uniq(typ) => { + if mt_b.mutbl == ast::MutMutable { + return Err(ty::terr_mutability) + } + typ + } ty::ty_rptr(_, mt_a) => mt_a.ty, _ => { return self.subtype(a, b); diff --git a/src/librustc/util/sha2.rs b/src/librustc/util/sha2.rs index 47d9e66fbd5..e9891533ac8 100644 --- a/src/librustc/util/sha2.rs +++ b/src/librustc/util/sha2.rs @@ -599,7 +599,7 @@ mod tests { let mut sh = box Sha256::new(); - test_hash(sh, tests.as_slice()); + test_hash(&mut *sh, tests.as_slice()); } /// Feed 1,000,000 'a's into the digest with varying input sizes and check that the result is diff --git a/src/libsync/raw.rs b/src/libsync/raw.rs index 28a08a7fef2..35865e65612 100644 --- a/src/libsync/raw.rs +++ b/src/libsync/raw.rs @@ -899,7 +899,7 @@ mod tests { }); } { - access_shared(sharedstate, &x, mode2, 10); + access_shared(&mut *sharedstate, &x, mode2, 10); let _ = rx.recv(); assert_eq!(*sharedstate, 20); diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs index 9b2b46d0a5a..fe0744e5e7c 100644 --- a/src/test/bench/shootout-k-nucleotide.rs +++ b/src/test/bench/shootout-k-nucleotide.rs @@ -115,16 +115,16 @@ impl Table { count: 0, next: None, }; - c.f(entry); + c.f(&mut *entry); item.next = Some(entry); } Some(ref mut entry) => { if entry.code == key { - c.f(*entry); + c.f(&mut **entry); return; } - Table::search_remainder(*entry, key, c) + Table::search_remainder(&mut **entry, key, c) } } } @@ -139,7 +139,7 @@ impl Table { count: 0, next: None, }; - c.f(entry); + c.f(&mut *entry); *self.items.get_mut(index as uint) = Some(entry); return; } @@ -148,11 +148,11 @@ impl Table { { let entry = &mut *self.items.get_mut(index as uint).get_mut_ref(); if entry.code == key { - c.f(*entry); + c.f(&mut **entry); return; } - Table::search_remainder(*entry, key, c) + Table::search_remainder(&mut **entry, key, c) } } diff --git a/src/test/bench/sudoku.rs b/src/test/bench/sudoku.rs index 4a81deaf529..f0988bcfcf4 100644 --- a/src/test/bench/sudoku.rs +++ b/src/test/bench/sudoku.rs @@ -138,7 +138,7 @@ impl Sudoku { let mut avail = box Colors::new(start_color); // drop colors already in use in neighbourhood - self.drop_colors(avail, row, col); + self.drop_colors(&mut *avail, row, col); // find first remaining color that is available let next = avail.next(); diff --git a/src/test/compile-fail/borrowck-lend-flow-if.rs b/src/test/compile-fail/borrowck-lend-flow-if.rs index b1ba057dc14..e556b1bc184 100644 --- a/src/test/compile-fail/borrowck-lend-flow-if.rs +++ b/src/test/compile-fail/borrowck-lend-flow-if.rs @@ -34,7 +34,7 @@ fn pre_freeze_cond() { if cond() { _w = &v; } - borrow_mut(v); //~ ERROR cannot borrow + borrow_mut(&mut *v); //~ ERROR cannot borrow } fn pre_freeze_else() { @@ -46,7 +46,7 @@ fn pre_freeze_else() { if cond() { _w = &v; } else { - borrow_mut(v); + borrow_mut(&mut *v); } } diff --git a/src/test/compile-fail/borrowck-lend-flow-loop.rs b/src/test/compile-fail/borrowck-lend-flow-loop.rs index 616320c168b..561d8c679a1 100644 --- a/src/test/compile-fail/borrowck-lend-flow-loop.rs +++ b/src/test/compile-fail/borrowck-lend-flow-loop.rs @@ -53,7 +53,7 @@ fn loop_aliased_mut() { let mut w = box 4; let mut _x = &w; loop { - borrow_mut(v); //~ ERROR cannot borrow + borrow_mut(&mut *v); //~ ERROR cannot borrow _x = &v; } } @@ -65,7 +65,7 @@ fn while_aliased_mut() { let mut w = box 4; let mut _x = &w; while cond() { - borrow_mut(v); //~ ERROR cannot borrow + borrow_mut(&mut *v); //~ ERROR cannot borrow _x = &v; } } @@ -78,11 +78,11 @@ fn loop_aliased_mut_break() { let mut w = box 4; let mut _x = &w; loop { - borrow_mut(v); + borrow_mut(&mut *v); _x = &v; break; } - borrow_mut(v); //~ ERROR cannot borrow + borrow_mut(&mut *v); //~ ERROR cannot borrow } fn while_aliased_mut_break() { @@ -92,11 +92,11 @@ fn while_aliased_mut_break() { let mut w = box 4; let mut _x = &w; while cond() { - borrow_mut(v); + borrow_mut(&mut *v); _x = &v; break; } - borrow_mut(v); //~ ERROR cannot borrow + borrow_mut(&mut *v); //~ ERROR cannot borrow } fn while_aliased_mut_cond(cond: bool, cond2: bool) { diff --git a/src/test/compile-fail/borrowck-lend-flow.rs b/src/test/compile-fail/borrowck-lend-flow.rs index 54f326b479a..7ad2d904094 100644 --- a/src/test/compile-fail/borrowck-lend-flow.rs +++ b/src/test/compile-fail/borrowck-lend-flow.rs @@ -30,14 +30,14 @@ fn pre_freeze() { let mut v = box 3; let _w = &v; - borrow_mut(v); //~ ERROR cannot borrow + borrow_mut(&mut *v); //~ ERROR cannot borrow } fn post_freeze() { // In this instance, the const alias starts after the borrow. let mut v = box 3; - borrow_mut(v); + borrow_mut(&mut *v); let _w = &v; } diff --git a/src/test/compile-fail/lint-allocation.rs b/src/test/compile-fail/lint-allocation.rs index c898107f5e3..1600043acbf 100644 --- a/src/test/compile-fail/lint-allocation.rs +++ b/src/test/compile-fail/lint-allocation.rs @@ -11,9 +11,7 @@ #![deny(unnecessary_allocation)] fn f(_: &int) {} -fn g(_: &mut int) {} fn main() { f(box 1); //~ ERROR unnecessary allocation, use & instead - g(box 1); //~ ERROR unnecessary allocation, use &mut instead } diff --git a/src/test/compile-fail/mut-cross-borrowing.rs b/src/test/compile-fail/mut-cross-borrowing.rs new file mode 100644 index 00000000000..657c2832c49 --- /dev/null +++ b/src/test/compile-fail/mut-cross-borrowing.rs @@ -0,0 +1,17 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn f(_: &mut int) {} + +fn main() { + let mut x = box 3i; + f(x) //~ ERROR mismatched types +} + diff --git a/src/test/run-pass/borrowck-mut-uniq.rs b/src/test/run-pass/borrowck-mut-uniq.rs index 1ab573db37b..1bf29fb3482 100644 --- a/src/test/run-pass/borrowck-mut-uniq.rs +++ b/src/test/run-pass/borrowck-mut-uniq.rs @@ -29,8 +29,8 @@ fn iter_ints(x: &Ints, f: |x: &int| -> bool) -> bool { pub fn main() { let mut ints = box Ints {sum: box 0, values: Vec::new()}; - add_int(ints, 22); - add_int(ints, 44); + add_int(&mut *ints, 22); + add_int(&mut *ints, 44); iter_ints(ints, |i| { println!("int = {}", *i);