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.
|
||||
pub fn escape(&self) -> String {
|
||||
match self {
|
||||
&LabelStr(ref s) => s.escape_default(),
|
||||
&LabelStr(ref s) => (&**s).escape_default(),
|
||||
&EscStr(ref s) => LabelText::escape_str(s.as_slice()),
|
||||
}
|
||||
}
|
||||
@ -453,7 +453,7 @@ impl<'a> LabelText<'a> {
|
||||
match self {
|
||||
EscStr(s) => s,
|
||||
LabelStr(s) => if s.contains_char('\\') {
|
||||
s.escape_default().into_cow()
|
||||
(&*s).escape_default().into_cow()
|
||||
} else {
|
||||
s
|
||||
},
|
||||
|
@ -628,17 +628,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
None => {}
|
||||
}
|
||||
|
||||
match 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
|
||||
}
|
||||
self.pick_autorefd_method(step)
|
||||
}
|
||||
|
||||
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}))
|
||||
}
|
||||
|
||||
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,
|
||||
mut mk_adjustment: F,
|
||||
mut mk_autoref_ty: G)
|
||||
|
@ -170,7 +170,7 @@ impl<'a> fmt::Show for Ascii {
|
||||
|
||||
/// Trait for converting into an ascii type.
|
||||
#[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.
|
||||
#[inline]
|
||||
fn to_ascii(&self) -> T {
|
||||
@ -196,10 +196,10 @@ pub trait AsciiCast<T> {
|
||||
}
|
||||
|
||||
#[experimental = "may be replaced by generic conversion traits"]
|
||||
impl<'a> AsciiCast<&'a[Ascii]> for &'a [u8] {
|
||||
impl<'a> AsciiCast<&'a[Ascii]> for [u8] {
|
||||
#[inline]
|
||||
unsafe fn to_ascii_nocheck(&self) -> &'a[Ascii] {
|
||||
mem::transmute(*self)
|
||||
mem::transmute(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -212,10 +212,10 @@ impl<'a> AsciiCast<&'a[Ascii]> for &'a [u8] {
|
||||
}
|
||||
|
||||
#[experimental = "may be replaced by generic conversion traits"]
|
||||
impl<'a> AsciiCast<&'a [Ascii]> for &'a str {
|
||||
impl<'a> AsciiCast<&'a [Ascii]> for str {
|
||||
#[inline]
|
||||
unsafe fn to_ascii_nocheck(&self) -> &'a [Ascii] {
|
||||
mem::transmute(*self)
|
||||
mem::transmute(self)
|
||||
}
|
||||
|
||||
#[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
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
@ -12,18 +12,27 @@
|
||||
fn main() {
|
||||
|
||||
// Testing that method lookup does not automatically borrow
|
||||
// vectors to slices then automatically create a &mut self
|
||||
// reference. That would allow creating a mutable pointer to a
|
||||
// temporary, which would be a source of confusion
|
||||
// vectors to slices then automatically create a self reference.
|
||||
|
||||
let mut a = vec!(0);
|
||||
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 {
|
||||
fn test_mut(&mut self);
|
||||
fn test(&self);
|
||||
}
|
||||
|
||||
impl<'a> MyIter for &'a [int] {
|
||||
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
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
@ -51,8 +51,6 @@ pub fn main() {
|
||||
|
||||
// Now try it with a type that *needs* to be borrowed
|
||||
let z = [0,1,2,3];
|
||||
// Call a method
|
||||
z.iterate(|y| { assert!(z[*y as uint] == *y); true });
|
||||
// Call a parameterized function
|
||||
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