Skip to content

Commit 19eb4bf

Browse files
committed
Add coercions from *mut to *const and from &mut to *const.
1 parent 872ba2c commit 19eb4bf

File tree

3 files changed

+64
-4
lines changed

3 files changed

+64
-4
lines changed

Diff for: src/librustc/middle/infer/coercion.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -549,17 +549,18 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
549549
b.repr(self.get_ref().infcx.tcx));
550550

551551
let mt_a = match *sty_a {
552-
ty::ty_rptr(_, mt) => mt,
552+
ty::ty_rptr(_, mt) | ty::ty_ptr(mt) => mt,
553553
_ => {
554554
return self.subtype(a, b);
555555
}
556556
};
557557

558558
// Check that the types which they point at are compatible.
559-
// Note that we don't adjust the mutability here. We cannot change
560-
// the mutability and the kind of pointer in a single coercion.
561-
let a_unsafe = ty::mk_ptr(self.get_ref().infcx.tcx, mt_a);
559+
let a_unsafe = ty::mk_ptr(self.get_ref().infcx.tcx, ty::mt{ mutbl: mutbl_b, ty: mt_a.ty });
562560
try!(self.subtype(a_unsafe, b));
561+
if !can_coerce_mutbls(mt_a.mutbl, mutbl_b) {
562+
return Err(ty::terr_mutability);
563+
}
563564

564565
// Although references and unsafe ptrs have the same
565566
// representation, we still register an AutoDerefRef so that

Diff for: src/test/compile-fail/ptr-coercion.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test coercions between pointers which don't do anything fancy like unsizing.
12+
// These are testing that we don't lose mutability when converting to raw pointers.
13+
14+
pub fn main() {
15+
// *const -> *mut
16+
let x: *const int = &42i;
17+
let x: *mut int = x; //~ERROR values differ in mutability
18+
19+
// & -> *mut
20+
let x: *mut int = &42; //~ERROR values differ in mutability
21+
22+
let x: *const int = &42;
23+
let x: *mut int = x; //~ERROR values differ in mutability
24+
}

Diff for: src/test/run-pass/ptr-coercion.rs

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test coercions between pointers which don't do anything fancy like unsizing.
12+
13+
pub fn main() {
14+
// &mut -> &
15+
let x: &mut int = &mut 42i;
16+
let x: &int = x;
17+
18+
let x: &int = &mut 42i;
19+
20+
// & -> *const
21+
let x: &int = &42i;
22+
let x: *const int = x;
23+
24+
let x: *const int = &42i;
25+
26+
// &mut -> *const
27+
let x: &mut int = &mut 42i;
28+
let x: *const int = x;
29+
30+
let x: *const int = &mut 42i;
31+
32+
// *mut -> *const
33+
let x: *mut int = &mut 42i;
34+
let x: *const int = x;
35+
}

0 commit comments

Comments
 (0)