auto merge of #18714 : nikomatsakis/rust/issue-18621-deref-for-refs, r=aturon
libs: add Deref, DerefMut impls for references, fixing a bug in compiler in the process that was blocking this. r? @aturon
This commit is contained in:
commit
97a57ec909
@ -166,7 +166,7 @@ impl<T: Send + Sync + Clone> Arc<T> {
|
||||
// additional reference of either kind.
|
||||
if self.inner().strong.load(atomic::SeqCst) != 1 ||
|
||||
self.inner().weak.load(atomic::SeqCst) != 1 {
|
||||
*self = Arc::new(self.deref().clone())
|
||||
*self = Arc::new((**self).clone())
|
||||
}
|
||||
// This unsafety is ok because we're guaranteed that the pointer
|
||||
// returned is the *only* pointer that will ever be returned to T. Our
|
||||
|
@ -805,6 +805,16 @@ pub trait Deref<Sized? Result> {
|
||||
fn deref<'a>(&'a self) -> &'a Result;
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
impl<'a, Sized? T> Deref<T> for &'a T {
|
||||
fn deref(&self) -> &T { *self }
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
impl<'a, Sized? T> Deref<T> for &'a mut T {
|
||||
fn deref(&self) -> &T { *self }
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* The `DerefMut` trait is used to specify the functionality of dereferencing
|
||||
@ -845,6 +855,11 @@ pub trait DerefMut<Sized? Result>: Deref<Result> {
|
||||
fn deref_mut<'a>(&'a mut self) -> &'a mut Result;
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
impl<'a, Sized? T> DerefMut<T> for &'a mut T {
|
||||
fn deref_mut(&mut self) -> &mut T { *self }
|
||||
}
|
||||
|
||||
/// A version of the call operator that takes an immutable receiver.
|
||||
#[lang="fn"]
|
||||
pub trait Fn<Args,Result> {
|
||||
|
@ -1702,13 +1702,18 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
|
||||
PreferMutLvalue);
|
||||
}
|
||||
ast::ExprUnary(ast::UnDeref, ref base_expr) => {
|
||||
check::try_overloaded_deref(
|
||||
self.fcx,
|
||||
expr.span,
|
||||
Some(MethodCall::expr(expr.id)),
|
||||
Some(&**base_expr),
|
||||
self.fcx.expr_ty(&**base_expr),
|
||||
PreferMutLvalue);
|
||||
// if this is an overloaded deref, then re-evaluate with
|
||||
// a preference for mut
|
||||
let method_call = MethodCall::expr(expr.id);
|
||||
if self.fcx.inh.method_map.borrow().contains_key(&method_call) {
|
||||
check::try_overloaded_deref(
|
||||
self.fcx,
|
||||
expr.span,
|
||||
Some(method_call),
|
||||
Some(&**base_expr),
|
||||
self.fcx.expr_ty(&**base_expr),
|
||||
PreferMutLvalue);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -166,18 +166,22 @@ impl<K, V> RawBucket<K, V> {
|
||||
}
|
||||
|
||||
// For parameterizing over mutability.
|
||||
|
||||
#[cfg(stage0)]
|
||||
impl<'t, K, V> Deref<RawTable<K, V>> for &'t RawTable<K, V> {
|
||||
fn deref(&self) -> &RawTable<K, V> {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
impl<'t, K, V> Deref<RawTable<K, V>> for &'t mut RawTable<K, V> {
|
||||
fn deref(&self) -> &RawTable<K,V> {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
impl<'t, K, V> DerefMut<RawTable<K, V>> for &'t mut RawTable<K, V> {
|
||||
fn deref_mut(&mut self) -> &mut RawTable<K,V> {
|
||||
&mut **self
|
||||
|
21
src/test/run-pass/deref-mut-on-ref.rs
Normal file
21
src/test/run-pass/deref-mut-on-ref.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// 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 that `&mut T` implements `DerefMut<T>`
|
||||
|
||||
fn inc<T:DerefMut<int>>(mut t: T) {
|
||||
*t += 1;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut x: int = 5;
|
||||
inc(&mut x);
|
||||
assert_eq!(x, 6);
|
||||
}
|
25
src/test/run-pass/deref-on-ref.rs
Normal file
25
src/test/run-pass/deref-on-ref.rs
Normal file
@ -0,0 +1,25 @@
|
||||
// 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 that `&T` and `&mut T` implement `Deref<T>`
|
||||
|
||||
fn deref<U:Copy,T:Deref<U>>(t: T) -> U {
|
||||
*t
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x: int = 3;
|
||||
let y = deref(&x);
|
||||
assert_eq!(y, 3);
|
||||
|
||||
let mut x: int = 4;
|
||||
let y = deref(&mut x);
|
||||
assert_eq!(y, 4);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user