about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-12-17 08:33:57 -0800
committerAlex Crichton <alex@alexcrichton.com>2014-12-17 11:50:24 -0800
commit126a83f433db665cf6ad6389070104dff5b1eccc (patch)
tree3a35edfb8becaa4c8c02bf4a32180e467e4cb857 /src
parent6089699411d4644981808c20661fa559646293c8 (diff)
parent19eb4bf0b2d59c1d1dc78fe52fb98fe61a9a2783 (diff)
downloadrust-126a83f433db665cf6ad6389070104dff5b1eccc.tar.gz
rust-126a83f433db665cf6ad6389070104dff5b1eccc.zip
rollup merge of #19766: nick29581/coerce-raw
r?
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/infer/coercion.rs9
-rw-r--r--src/test/compile-fail/ptr-coercion.rs24
-rw-r--r--src/test/run-pass/ptr-coercion.rs35
3 files changed, 64 insertions, 4 deletions
diff --git a/src/librustc/middle/infer/coercion.rs b/src/librustc/middle/infer/coercion.rs
index 1d1ee39d684..e268160a42b 100644
--- a/src/librustc/middle/infer/coercion.rs
+++ b/src/librustc/middle/infer/coercion.rs
@@ -552,17 +552,18 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                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
index 00000000000..d9b20748a7a
--- /dev/null
+++ b/src/test/compile-fail/ptr-coercion.rs
@@ -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
index 00000000000..1b77c1316ed
--- /dev/null
+++ b/src/test/run-pass/ptr-coercion.rs
@@ -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;
+}