Skip to content

Instantly share code, notes, and snippets.

@nikomatsakis
Last active August 29, 2015 13:57
Show Gist options
  • Save nikomatsakis/9348385 to your computer and use it in GitHub Desktop.
Save nikomatsakis/9348385 to your computer and use it in GitHub Desktop.
commit a0049922adf1efd3ac0f416f6bf2bea472b08277
Author: Niko Matsakis <[email protected]>
Date: Tue Mar 4 10:20:16 2014 -0500
WIP -- new tests, patch
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 2ba008b..6a2c4e2 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -434,12 +434,12 @@ impl<TYPER:Typer> MemCategorizationContext<TYPER> {
let expr_ty = if_ok!(self.expr_ty(expr));
match expr.node {
ast::ExprUnary(ast::UnDeref, e_base) => {
- let ref_ty = self.typer.node_method_ty(expr.id).map(ty::ty_fn_ret);
- let base_cmt = match ref_ty {
- Some(ref_ty) => {
- self.cat_rvalue_node(expr.id(), expr.span(), ref_ty)
+ let base_cmt = match self.typer.node_method_ty(expr.id) {
+ None => if_ok!(self.cat_expr(e_base)),
+ Some(fn_ty) => {
+ let ret_ty = ty::ty_fn_ret(fn_ty);
+ self.cat_rvalue_node(expr.id(), expr.span(), ret_ty)
}
- None => if_ok!(self.cat_expr(e_base))
};
Ok(self.cat_deref(expr, base_cmt, 0))
}
diff --git a/src/test/compile-fail/borrowck-borrow-overloaded-deref-mut.rs b/src/test/compile-fail/borrowck-borrow-overloaded-deref-mut.rs
new file mode 100644
index 0000000..b0194b5
--- /dev/null
+++ b/src/test/compile-fail/borrowck-borrow-overloaded-deref-mut.rs
@@ -0,0 +1,68 @@
+// 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 how overloaded deref interacts with borrows when DerefMut
+// is implemented.
+
+use std::ops::{Deref, DerefMut};
+
+struct Own<T> {
+ value: *mut T
+}
+
+impl<T> Deref<T> for Own<T> {
+ fn deref<'a>(&'a self) -> &'a T {
+ unsafe { &*self.value }
+ }
+}
+
+impl<T> DerefMut<T> for Own<T> {
+ fn deref_mut<'a>(&'a mut self) -> &'a mut T {
+ unsafe { &mut *self.value }
+ }
+}
+
+fn deref_imm(x: Own<int>) {
+ let _i = &*x;
+}
+
+fn deref_mut1(x: Own<int>) {
+ let _i = &mut *x; //~ ERROR cannot borrow
+}
+
+fn deref_mut2(mut x: Own<int>) {
+ let _i = &mut *x;
+}
+
+fn deref_extend<'a>(x: &'a Own<int>) -> &'a int {
+ &**x
+}
+
+fn deref_extend_mut1<'a>(x: &'a Own<int>) -> &'a mut int {
+ &mut **x //~ ERROR cannot borrow
+}
+
+fn deref_extend_mut2<'a>(x: &'a mut Own<int>) -> &'a mut int {
+ &mut **x
+}
+
+fn assign1<'a>(x: Own<int>) {
+ *x = 3; //~ ERROR cannot assign
+}
+
+fn assign2<'a>(x: &'a Own<int>) {
+ **x = 3; //~ ERROR cannot assign
+}
+
+fn assign3<'a>(x: &'a mut Own<int>) {
+ **x = 3;
+}
+
+pub fn main() {}
diff --git a/src/test/compile-fail/borrowck-borrow-overloaded-deref.rs b/src/test/compile-fail/borrowck-borrow-overloaded-deref.rs
new file mode 100644
index 0000000..7aac945
--- /dev/null
+++ b/src/test/compile-fail/borrowck-borrow-overloaded-deref.rs
@@ -0,0 +1,62 @@
+// 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 how overloaded deref interacts with borrows when only
+// Deref and not DerefMut is implemented.
+
+use std::ops::Deref;
+
+struct Rc<T> {
+ value: *T
+}
+
+impl<T> Deref<T> for Rc<T> {
+ fn deref<'a>(&'a self) -> &'a T {
+ unsafe { &*self.value }
+ }
+}
+
+fn deref_imm(x: Rc<int>) {
+ let _i = &*x;
+}
+
+fn deref_mut1(x: Rc<int>) {
+ let _i = &mut *x; //~ ERROR cannot borrow
+}
+
+fn deref_mut2(mut x: Rc<int>) {
+ let _i = &mut *x; //~ ERROR cannot borrow
+}
+
+fn deref_extend<'a>(x: &'a Rc<int>) -> &'a int {
+ &**x
+}
+
+fn deref_extend_mut1<'a>(x: &'a Rc<int>) -> &'a mut int {
+ &mut **x //~ ERROR cannot borrow
+}
+
+fn deref_extend_mut2<'a>(x: &'a mut Rc<int>) -> &'a mut int {
+ &mut **x //~ ERROR cannot borrow
+}
+
+fn assign1<'a>(x: Rc<int>) {
+ *x = 3; //~ ERROR cannot assign
+}
+
+fn assign2<'a>(x: &'a Rc<int>) {
+ **x = 3; //~ ERROR cannot assign
+}
+
+fn assign3<'a>(x: &'a mut Rc<int>) {
+ **x = 3; //~ ERROR cannot assign
+}
+
+pub fn main() {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment