auto merge of #19761 : nick29581/rust/coerce-double, r=nikomatsakis
Part of #18469 [breaking-change] A receiver will only ever get a single auto-reference. Previously arrays and strings would get two, e.g., [T] would be auto-ref'ed to &&[T]. This is usually apparent when a trait is implemented for `&[T]` and has a method takes self by reference. The usual solution is to implement the trait for `[T]` (the DST form). r? @nikomatsakis (or anyone else, really)
This commit is contained in:
commit
4265e86844
@ -440,7 +440,7 @@ impl<'a> LabelText<'a> {
|
|||||||
/// Renders text as string suitable for a label in a .dot file.
|
/// Renders text as string suitable for a label in a .dot file.
|
||||||
pub fn escape(&self) -> String {
|
pub fn escape(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
&LabelStr(ref s) => s.escape_default(),
|
&LabelStr(ref s) => (&**s).escape_default(),
|
||||||
&EscStr(ref s) => LabelText::escape_str(s.as_slice()),
|
&EscStr(ref s) => LabelText::escape_str(s.as_slice()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -453,7 +453,7 @@ impl<'a> LabelText<'a> {
|
|||||||
match self {
|
match self {
|
||||||
EscStr(s) => s,
|
EscStr(s) => s,
|
||||||
LabelStr(s) => if s.contains_char('\\') {
|
LabelStr(s) => if s.contains_char('\\') {
|
||||||
s.escape_default().into_cow()
|
(&*s).escape_default().into_cow()
|
||||||
} else {
|
} else {
|
||||||
s
|
s
|
||||||
},
|
},
|
||||||
|
@ -628,17 +628,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.pick_autorefd_method(step) {
|
self.pick_autorefd_method(step)
|
||||||
Some(result) => return Some(result),
|
|
||||||
None => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME -- Super hack. For DST types, we will convert to
|
|
||||||
// &&[T] or &&str, as part of a kind of legacy lookup scheme.
|
|
||||||
match step.self_ty.sty {
|
|
||||||
ty::ty_str | ty::ty_vec(_, None) => self.pick_autorefrefd_method(step),
|
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pick_by_value_method(&mut self,
|
fn pick_by_value_method(&mut self,
|
||||||
@ -681,18 +671,6 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||||||
|m,r| ty::mk_rptr(tcx, r, ty::mt {ty:step.self_ty, mutbl:m}))
|
|m,r| ty::mk_rptr(tcx, r, ty::mt {ty:step.self_ty, mutbl:m}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pick_autorefrefd_method(&mut self,
|
|
||||||
step: &CandidateStep<'tcx>)
|
|
||||||
-> Option<PickResult<'tcx>>
|
|
||||||
{
|
|
||||||
let tcx = self.tcx();
|
|
||||||
self.search_mutabilities(
|
|
||||||
|m| AutoRef(m, box AutoRef(m, box step.adjustment.clone())),
|
|
||||||
|m,r| ty::mk_rptr(tcx, r, ty::mt { ty: ty::mk_rptr(tcx, r, ty::mt { ty:step.self_ty,
|
|
||||||
mutbl:m}),
|
|
||||||
mutbl: m }))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn search_mutabilities<F, G>(&mut self,
|
fn search_mutabilities<F, G>(&mut self,
|
||||||
mut mk_adjustment: F,
|
mut mk_adjustment: F,
|
||||||
mut mk_autoref_ty: G)
|
mut mk_autoref_ty: G)
|
||||||
|
@ -170,7 +170,7 @@ impl<'a> fmt::Show for Ascii {
|
|||||||
|
|
||||||
/// Trait for converting into an ascii type.
|
/// Trait for converting into an ascii type.
|
||||||
#[experimental = "may be replaced by generic conversion traits"]
|
#[experimental = "may be replaced by generic conversion traits"]
|
||||||
pub trait AsciiCast<T> {
|
pub trait AsciiCast<T> for Sized? {
|
||||||
/// Convert to an ascii type, panic on non-ASCII input.
|
/// Convert to an ascii type, panic on non-ASCII input.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_ascii(&self) -> T {
|
fn to_ascii(&self) -> T {
|
||||||
@ -196,10 +196,10 @@ pub trait AsciiCast<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[experimental = "may be replaced by generic conversion traits"]
|
#[experimental = "may be replaced by generic conversion traits"]
|
||||||
impl<'a> AsciiCast<&'a[Ascii]> for &'a [u8] {
|
impl<'a> AsciiCast<&'a[Ascii]> for [u8] {
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn to_ascii_nocheck(&self) -> &'a[Ascii] {
|
unsafe fn to_ascii_nocheck(&self) -> &'a[Ascii] {
|
||||||
mem::transmute(*self)
|
mem::transmute(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -212,10 +212,10 @@ impl<'a> AsciiCast<&'a[Ascii]> for &'a [u8] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[experimental = "may be replaced by generic conversion traits"]
|
#[experimental = "may be replaced by generic conversion traits"]
|
||||||
impl<'a> AsciiCast<&'a [Ascii]> for &'a str {
|
impl<'a> AsciiCast<&'a [Ascii]> for str {
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn to_ascii_nocheck(&self) -> &'a [Ascii] {
|
unsafe fn to_ascii_nocheck(&self) -> &'a [Ascii] {
|
||||||
mem::transmute(*self)
|
mem::transmute(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
// Copyright 2012-14 The Rust Project Developers. See the COPYRIGHT
|
||||||
// file at the top-level directory of this distribution and at
|
// file at the top-level directory of this distribution and at
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
//
|
//
|
||||||
@ -12,18 +12,27 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
|
|
||||||
// Testing that method lookup does not automatically borrow
|
// Testing that method lookup does not automatically borrow
|
||||||
// vectors to slices then automatically create a &mut self
|
// vectors to slices then automatically create a self reference.
|
||||||
// reference. That would allow creating a mutable pointer to a
|
|
||||||
// temporary, which would be a source of confusion
|
|
||||||
|
|
||||||
let mut a = vec!(0);
|
let mut a = vec!(0);
|
||||||
a.test_mut(); //~ ERROR does not implement any method in scope named `test_mut`
|
a.test_mut(); //~ ERROR does not implement any method in scope named `test_mut`
|
||||||
|
a.test(); //~ ERROR does not implement any method in scope named `test`
|
||||||
|
|
||||||
|
([1]).test(); //~ ERROR does not implement any method in scope named `test`
|
||||||
|
(&[1]).test(); //~ ERROR does not implement any method in scope named `test`
|
||||||
}
|
}
|
||||||
|
|
||||||
trait MyIter {
|
trait MyIter {
|
||||||
fn test_mut(&mut self);
|
fn test_mut(&mut self);
|
||||||
|
fn test(&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> MyIter for &'a [int] {
|
impl<'a> MyIter for &'a [int] {
|
||||||
fn test_mut(&mut self) { }
|
fn test_mut(&mut self) { }
|
||||||
|
fn test(&self) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> MyIter for &'a str {
|
||||||
|
fn test_mut(&mut self) { }
|
||||||
|
fn test(&self) { }
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
// Copyright 2012-4 The Rust Project Developers. See the COPYRIGHT
|
||||||
// file at the top-level directory of this distribution and at
|
// file at the top-level directory of this distribution and at
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
//
|
//
|
||||||
@ -51,8 +51,6 @@ pub fn main() {
|
|||||||
|
|
||||||
// Now try it with a type that *needs* to be borrowed
|
// Now try it with a type that *needs* to be borrowed
|
||||||
let z = [0,1,2,3];
|
let z = [0,1,2,3];
|
||||||
// Call a method
|
|
||||||
z.iterate(|y| { assert!(z[*y as uint] == *y); true });
|
|
||||||
// Call a parameterized function
|
// Call a parameterized function
|
||||||
assert_eq!(length::<int, &[int]>(&z), z.len());
|
assert_eq!(length::<int, &[int]>(&z), z.len());
|
||||||
}
|
}
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
// Copyright 2012 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.
|
|
||||||
|
|
||||||
// Testing that method lookup automatically both borrows vectors to slices
|
|
||||||
// and also references them to create the &self pointer
|
|
||||||
|
|
||||||
|
|
||||||
trait MyIter {
|
|
||||||
fn test_imm(&self);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> MyIter for &'a [int] {
|
|
||||||
fn test_imm(&self) { assert_eq!(self[0], 1) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> MyIter for &'a str {
|
|
||||||
fn test_imm(&self) { assert_eq!(*self, "test") }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn main() {
|
|
||||||
([1]).test_imm();
|
|
||||||
(vec!(1)).as_slice().test_imm();
|
|
||||||
(&[1]).test_imm();
|
|
||||||
("test").test_imm();
|
|
||||||
("test").test_imm();
|
|
||||||
|
|
||||||
// FIXME: Other types of mutable vecs don't currently exist
|
|
||||||
|
|
||||||
// NB: We don't do this double autoreffing for &mut self because that would
|
|
||||||
// allow creating a mutable pointer to a temporary, which would be a source
|
|
||||||
// of confusion
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user