about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2014-08-29 15:21:28 +1200
committerNick Cameron <ncameron@mozilla.com>2014-09-03 08:32:35 +1200
commit7f72884f1366ee9a46cd2b231c09c5c0e44f7ba3 (patch)
tree6f9bf04e0f6639a93b23fb13db4816cf44b37d91
parente9bd650cad7c519e3f39b8bbed5afeac94daff05 (diff)
downloadrust-7f72884f1366ee9a46cd2b231c09c5c0e44f7ba3.tar.gz
rust-7f72884f1366ee9a46cd2b231c09c5c0e44f7ba3.zip
Remove cross-borrowing for traits.
Closes #15349

[breaking-change]

Trait objects are no longer implicitly coerced from Box<T> to &T. You must make an explicit coercion using `&*`.
-rw-r--r--src/librustc/middle/trans/cleanup.rs4
-rw-r--r--src/librustc/middle/typeck/infer/coercion.rs3
-rw-r--r--src/librustrt/unwind.rs2
-rw-r--r--src/libstd/failure.rs2
-rw-r--r--src/libstd/io/stdio.rs2
-rw-r--r--src/libsyntax/parse/parser.rs6
-rw-r--r--src/test/compile-fail/cross-borrow-trait.rs22
-rw-r--r--src/test/compile-fail/regions-close-object-into-object.rs8
-rw-r--r--src/test/run-pass/cleanup-auto-borrow-obj.rs2
-rw-r--r--src/test/run-pass/issue-3794.rs2
-rw-r--r--src/test/run-pass/new-box.rs2
-rw-r--r--src/test/run-pass/regions-early-bound-trait-param.rs4
12 files changed, 40 insertions, 19 deletions
diff --git a/src/librustc/middle/trans/cleanup.rs b/src/librustc/middle/trans/cleanup.rs
index b36887c80e9..515413e03f0 100644
--- a/src/librustc/middle/trans/cleanup.rs
+++ b/src/librustc/middle/trans/cleanup.rs
@@ -640,7 +640,7 @@ impl<'a> CleanupHelperMethods<'a> for FunctionContext<'a> {
         while !popped_scopes.is_empty() {
             let mut scope = popped_scopes.pop().unwrap();
 
-            if scope.cleanups.iter().any(|c| cleanup_is_suitable_for(*c, label))
+            if scope.cleanups.iter().any(|c| cleanup_is_suitable_for(&**c, label))
             {
                 let name = scope.block_name("clean");
                 debug!("generating cleanups for {}", name);
@@ -649,7 +649,7 @@ impl<'a> CleanupHelperMethods<'a> for FunctionContext<'a> {
                                             None);
                 let mut bcx_out = bcx_in;
                 for cleanup in scope.cleanups.iter().rev() {
-                    if cleanup_is_suitable_for(*cleanup, label) {
+                    if cleanup_is_suitable_for(&**cleanup, label) {
                         bcx_out = cleanup.trans(bcx_out);
                     }
                 }
diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/typeck/infer/coercion.rs
index 381c47279e3..7763a992c8f 100644
--- a/src/librustc/middle/typeck/infer/coercion.rs
+++ b/src/librustc/middle/typeck/infer/coercion.rs
@@ -327,7 +327,6 @@ impl<'f> Coerce<'f> {
 
         let sty_b = &ty::get(b).sty;
         match (sty_a, sty_b) {
-            (&ty::ty_uniq(_), &ty::ty_rptr(..)) => Err(ty::terr_mismatch),
             (&ty::ty_rptr(_, ty::mt{ty: t_a, ..}), &ty::ty_rptr(_, mt_b)) => {
                 self.unpack_actual_value(t_a, |sty_a| {
                     match self.unsize_ty(sty_a, mt_b.ty) {
@@ -511,7 +510,7 @@ impl<'f> Coerce<'f> {
         let tcx = self.get_ref().infcx.tcx;
 
         match *sty_a {
-            ty::ty_uniq(ty) | ty::ty_rptr(_, ty::mt{ty, ..}) => match ty::get(ty).sty {
+            ty::ty_rptr(_, ty::mt{ty, ..}) => match ty::get(ty).sty {
                 ty::ty_trait(box ty::TyTrait {
                         def_id,
                         ref substs,
diff --git a/src/librustrt/unwind.rs b/src/librustrt/unwind.rs
index 9de58960c5e..9e6dff8a751 100644
--- a/src/librustrt/unwind.rs
+++ b/src/librustrt/unwind.rs
@@ -570,7 +570,7 @@ fn begin_unwind_inner(msg: Box<Any + Send>, file_line: &(&'static str, uint)) ->
             n => {
                 let f: Callback = unsafe { mem::transmute(n) };
                 let (file, line) = *file_line;
-                f(msg, file, line);
+                f(&*msg, file, line);
             }
         }
     };
diff --git a/src/libstd/failure.rs b/src/libstd/failure.rs
index 8c709d20d19..8d715de16e6 100644
--- a/src/libstd/failure.rs
+++ b/src/libstd/failure.rs
@@ -81,7 +81,7 @@ pub fn on_fail(obj: &Any + Send, file: &'static str, line: uint) {
                                  "task '{}' failed at '{}', {}:{}\n",
                                  n, msg, file, line);
                 if backtrace::log_enabled() {
-                    let _ = backtrace::write(stderr);
+                    let _ = backtrace::write(&mut *stderr);
                 }
                 local_stderr.replace(Some(stderr));
             }
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index fea161c426a..bd837b6f7b5 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -203,7 +203,7 @@ fn with_task_stdout(f: |&mut Writer| -> IoResult<()>) {
         let mut my_stdout = local_stdout.replace(None).unwrap_or_else(|| {
             box stdout() as Box<Writer + Send>
         });
-        let result = f(my_stdout);
+        let result = f(&mut *my_stdout);
         local_stdout.replace(Some(my_stdout));
         result
     } else {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index d3700059862..81ac789b683 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -351,7 +351,7 @@ impl<'a> Parser<'a> {
                mut rdr: Box<Reader+'a>)
                -> Parser<'a>
     {
-        let tok0 = real_token(rdr);
+        let tok0 = real_token(&mut *rdr);
         let span = tok0.sp;
         let placeholder = TokenAndSpan {
             tok: token::UNDERSCORE,
@@ -899,7 +899,7 @@ impl<'a> Parser<'a> {
             None
         };
         let next = if self.buffer_start == self.buffer_end {
-            real_token(self.reader)
+            real_token(&mut *self.reader)
         } else {
             // Avoid token copies with `replace`.
             let buffer_start = self.buffer_start as uint;
@@ -943,7 +943,7 @@ impl<'a> Parser<'a> {
                       -> R {
         let dist = distance as int;
         while self.buffer_length() < dist {
-            self.buffer[self.buffer_end as uint] = real_token(self.reader);
+            self.buffer[self.buffer_end as uint] = real_token(&mut *self.reader);
             self.buffer_end = (self.buffer_end + 1) & 3;
         }
         f(&self.buffer[((self.buffer_start + dist - 1) & 3) as uint].tok)
diff --git a/src/test/compile-fail/cross-borrow-trait.rs b/src/test/compile-fail/cross-borrow-trait.rs
new file mode 100644
index 00000000000..1ccd5290fef
--- /dev/null
+++ b/src/test/compile-fail/cross-borrow-trait.rs
@@ -0,0 +1,22 @@
+// Copyright 2012-2013-2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that cross-borrowing (implicitly converting from `Box<T>` to `&T`) is
+// forbidden when `T` is a trait.
+
+struct Foo;
+trait Trait {}
+impl Trait for Foo {}
+
+pub fn main() {
+    let x: Box<Trait> = box Foo;
+    let _y: &Trait = x; //~ ERROR mismatched types: expected `&Trait`, found `Box<Trait>`
+}
+
diff --git a/src/test/compile-fail/regions-close-object-into-object.rs b/src/test/compile-fail/regions-close-object-into-object.rs
index a45c8e1db54..835c55c9bd1 100644
--- a/src/test/compile-fail/regions-close-object-into-object.rs
+++ b/src/test/compile-fail/regions-close-object-into-object.rs
@@ -16,19 +16,19 @@ trait X {}
 impl<'a, T> X for B<'a, T> {}
 
 fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
-    box B(v) as Box<X>
+    box B(&*v) as Box<X>
 }
 
 fn g<'a, T: 'static>(v: Box<A<T>>) -> Box<X+'static> {
-    box B(v) as Box<X> //~ ERROR cannot infer
+    box B(&*v) as Box<X> //~ ERROR cannot infer
 }
 
 fn h<'a, T, U>(v: Box<A<U>+'static>) -> Box<X+'static> {
-    box B(v) as Box<X>
+    box B(&*v) as Box<X>
 }
 
 fn i<'a, T, U>(v: Box<A<U>>) -> Box<X+'static> {
-    box B(v) as Box<X> //~ ERROR cannot infer
+    box B(&*v) as Box<X> //~ ERROR cannot infer
 }
 
 fn main() {}
diff --git a/src/test/run-pass/cleanup-auto-borrow-obj.rs b/src/test/run-pass/cleanup-auto-borrow-obj.rs
index 23142082a8c..5d7dbbe5a29 100644
--- a/src/test/run-pass/cleanup-auto-borrow-obj.rs
+++ b/src/test/run-pass/cleanup-auto-borrow-obj.rs
@@ -29,7 +29,7 @@ impl Trait for Foo {}
 
 pub fn main() {
     {
-        let _x: &Trait = box Foo as Box<Trait>;
+        let _x: &Trait = &*(box Foo as Box<Trait>);
     }
     unsafe {
         assert!(DROP_RAN);
diff --git a/src/test/run-pass/issue-3794.rs b/src/test/run-pass/issue-3794.rs
index 9414a6f2302..54225bbe01e 100644
--- a/src/test/run-pass/issue-3794.rs
+++ b/src/test/run-pass/issue-3794.rs
@@ -36,5 +36,5 @@ pub fn main() {
     let s: Box<S> = box S { s: 5 };
     print_s(&*s);
     let t: Box<T> = s as Box<T>;
-    print_t(t);
+    print_t(&*t);
 }
diff --git a/src/test/run-pass/new-box.rs b/src/test/run-pass/new-box.rs
index 38f552e9a98..8531fd5f975 100644
--- a/src/test/run-pass/new-box.rs
+++ b/src/test/run-pass/new-box.rs
@@ -29,7 +29,7 @@ impl Trait for Struct {
 
 fn g(x: Box<Trait>) {
     x.printme();
-    let y: &Trait = x;
+    let y: &Trait = &*x;
     y.printme();
 }
 
diff --git a/src/test/run-pass/regions-early-bound-trait-param.rs b/src/test/run-pass/regions-early-bound-trait-param.rs
index 27ef90d7376..c732d20a156 100644
--- a/src/test/run-pass/regions-early-bound-trait-param.rs
+++ b/src/test/run-pass/regions-early-bound-trait-param.rs
@@ -120,8 +120,8 @@ pub fn main() {
     assert_eq!(field_invoke2(&s2), 3);
 
     let m : Box<Trait> = make_val();
-    assert_eq!(object_invoke1(m), (4,5));
-    assert_eq!(object_invoke2(m), 5);
+    assert_eq!(object_invoke1(&*m), (4,5));
+    assert_eq!(object_invoke2(&*m), 5);
 
     // The RefMakerTrait above is pretty strange (i.e. it is strange
     // to consume a value of type T and return a &T).  Easiest thing