Skip to content

Commit

Permalink
Remove the double auto-ref on arrays/strings as receivers
Browse files Browse the repository at this point in the history
Part of rust-lang#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).
  • Loading branch information
nrc committed Dec 16, 2014
1 parent 0669a43 commit 769aa0a
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 76 deletions.
4 changes: 2 additions & 2 deletions src/libgraphviz/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()),
}
}
Expand All @@ -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
},
Expand Down
24 changes: 1 addition & 23 deletions src/librustc_typeck/check/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 5 additions & 5 deletions src/libstd/ascii.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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]
Expand All @@ -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]
Expand Down
17 changes: 13 additions & 4 deletions src/test/compile-fail/auto-ref-slice-plus-ref.rs
Original file line number Diff line number Diff line change
@@ -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.
//
Expand All @@ -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) { }
}
4 changes: 1 addition & 3 deletions src/test/run-pass/assignability-trait.rs
Original file line number Diff line number Diff line change
@@ -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.
//
Expand Down Expand Up @@ -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());
}
39 changes: 0 additions & 39 deletions src/test/run-pass/auto-ref-slice-plus-ref.rs

This file was deleted.

1 comment on commit 769aa0a

@nikomatsakis
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r+

Please sign in to comment.