From 5cd9a69832f304c0bbb52d92ad3a0a7893760ae2 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Tue, 20 Jan 2015 22:56:53 +0900 Subject: [PATCH] Forbid coercing &T to &mut T --- src/librustc/middle/infer/coercion.rs | 7 ++++++- src/test/compile-fail/coerce-mut.rs | 20 ++++++++++++++++++++ src/test/compile-fail/issue-12028.rs | 2 +- src/test/compile-fail/method-self-arg-2.rs | 5 +++-- src/test/compile-fail/slice-mut.rs | 6 +++++- 5 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 src/test/compile-fail/coerce-mut.rs diff --git a/src/librustc/middle/infer/coercion.rs b/src/librustc/middle/infer/coercion.rs index 9f87e73d4af9d..e8b8ecc701f91 100644 --- a/src/librustc/middle/infer/coercion.rs +++ b/src/librustc/middle/infer/coercion.rs @@ -213,7 +213,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let inner_ty = match a.sty { ty::ty_uniq(_) => return Err(ty::terr_mismatch), - ty::ty_rptr(_, mt_a) => mt_a.ty, + ty::ty_rptr(_, mt_a) => { + if !can_coerce_mutbls(mt_a.mutbl, mutbl_b) { + return Err(ty::terr_mutability); + } + mt_a.ty + } _ => { return self.subtype(a, b); } diff --git a/src/test/compile-fail/coerce-mut.rs b/src/test/compile-fail/coerce-mut.rs new file mode 100644 index 0000000000000..30c1b66a7b81f --- /dev/null +++ b/src/test/compile-fail/coerce-mut.rs @@ -0,0 +1,20 @@ +// Copyright 2015 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(x: &mut i32) {} + +fn main() { + let x = 0; + f(&x); + //~^ ERROR mismatched types + //~| expected `&mut i32` + //~| found `&_` + //~| values differ in mutability +} diff --git a/src/test/compile-fail/issue-12028.rs b/src/test/compile-fail/issue-12028.rs index 24ffc5e9ee373..980385ce4cc6b 100644 --- a/src/test/compile-fail/issue-12028.rs +++ b/src/test/compile-fail/issue-12028.rs @@ -43,7 +43,7 @@ impl Hash for u8 { impl StreamHash for u8 { fn input_stream(&self, stream: &mut H::S) { - Stream::input(&*stream, &[*self]); + Stream::input(stream, &[*self]); } } diff --git a/src/test/compile-fail/method-self-arg-2.rs b/src/test/compile-fail/method-self-arg-2.rs index ad255ecd9c064..dd5b2004145c2 100644 --- a/src/test/compile-fail/method-self-arg-2.rs +++ b/src/test/compile-fail/method-self-arg-2.rs @@ -22,6 +22,7 @@ fn main() { let y = &mut x; Foo::bar(&x); //~ERROR cannot borrow `x` - let x = Foo; - Foo::baz(&x); //~ERROR cannot borrow immutable borrowed content as mutable + let mut x = Foo; + let y = &mut x; + Foo::baz(&mut x); //~ERROR cannot borrow `x` } diff --git a/src/test/compile-fail/slice-mut.rs b/src/test/compile-fail/slice-mut.rs index 0e1dd0d8f6c3f..a1747f3b6bdc7 100644 --- a/src/test/compile-fail/slice-mut.rs +++ b/src/test/compile-fail/slice-mut.rs @@ -13,5 +13,9 @@ fn main() { let x: &[isize] = &[1, 2, 3, 4, 5]; // Immutable slices are not mutable. - let y: &mut[_] = &x[2..4]; //~ ERROR cannot borrow immutable borrowed content as mutable + let y: &mut[_] = &x[2..4]; + //~^ ERROR mismatched types + //~| expected `&mut [_]` + //~| found `&_` + //~| values differ in mutability }