]> git.lizzy.rs Git - rust.git/commitdiff
Add coercions from *mut to *const and from &mut to *const.
authorNick Cameron <ncameron@mozilla.com>
Fri, 12 Dec 2014 03:54:57 +0000 (16:54 +1300)
committerNick Cameron <ncameron@mozilla.com>
Fri, 12 Dec 2014 03:54:57 +0000 (16:54 +1300)
src/librustc/middle/infer/coercion.rs
src/test/compile-fail/ptr-coercion.rs [new file with mode: 0644]
src/test/run-pass/ptr-coercion.rs [new file with mode: 0644]

index f04c519badc8c2d28aa607264bdd77a7af9a7329..babef6bae3df1b7f747506ed6416e86ff0e0a889 100644 (file)
@@ -549,17 +549,18 @@ pub fn coerce_unsafe_ptr(&self,
                b.repr(self.get_ref().infcx.tcx));
 
         let mt_a = match *sty_a {
-            ty::ty_rptr(_, mt) => mt,
+            ty::ty_rptr(_, mt) | ty::ty_ptr(mt) => mt,
             _ => {
                 return self.subtype(a, b);
             }
         };
 
         // Check that the types which they point at are compatible.
-        // Note that we don't adjust the mutability here. We cannot change
-        // the mutability and the kind of pointer in a single coercion.
-        let a_unsafe = ty::mk_ptr(self.get_ref().infcx.tcx, mt_a);
+        let a_unsafe = ty::mk_ptr(self.get_ref().infcx.tcx, ty::mt{ mutbl: mutbl_b, ty: mt_a.ty });
         try!(self.subtype(a_unsafe, b));
+        if !can_coerce_mutbls(mt_a.mutbl, mutbl_b) {
+            return Err(ty::terr_mutability);
+        }
 
         // Although references and unsafe ptrs have the same
         // representation, we still register an AutoDerefRef so that
diff --git a/src/test/compile-fail/ptr-coercion.rs b/src/test/compile-fail/ptr-coercion.rs
new file mode 100644 (file)
index 0000000..d9b2074
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 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 coercions between pointers which don't do anything fancy like unsizing.
+// These are testing that we don't lose mutability when converting to raw pointers.
+
+pub fn main() {
+    // *const -> *mut
+    let x: *const int = &42i;
+    let x: *mut int = x; //~ERROR values differ in mutability
+
+    // & -> *mut
+    let x: *mut int = &42; //~ERROR values differ in mutability
+
+    let x: *const int = &42;
+    let x: *mut int = x; //~ERROR values differ in mutability
+}
diff --git a/src/test/run-pass/ptr-coercion.rs b/src/test/run-pass/ptr-coercion.rs
new file mode 100644 (file)
index 0000000..1b77c13
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 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 coercions between pointers which don't do anything fancy like unsizing.
+
+pub fn main() {
+    // &mut -> &
+    let x: &mut int = &mut 42i;
+    let x: &int = x;
+
+    let x: &int = &mut 42i;
+
+    // & -> *const
+    let x: &int = &42i;
+    let x: *const int = x;
+
+    let x: *const int = &42i;
+
+    // &mut -> *const
+    let x: &mut int = &mut 42i;
+    let x: *const int = x;
+
+    let x: *const int = &mut 42i;
+
+    // *mut -> *const
+    let x: *mut int = &mut 42i;
+    let x: *const int = x;
+}