Remove the double auto-ref on arrays/strings as receivers

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).
This commit is contained in:
Nick Cameron 2014-12-12 13:23:21 +13:00
parent 0669a432a2
commit 769aa0a7b3
6 changed files with 22 additions and 76 deletions

View File

@ -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
},

View File

@ -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)

View File

@ -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]

View File

@ -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) { }
}

View File

@ -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());
}

View File

@ -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
}