]> git.lizzy.rs Git - rust.git/commitdiff
Remove the double auto-ref on arrays/strings as receivers
authorNick Cameron <ncameron@mozilla.com>
Fri, 12 Dec 2014 00:23:21 +0000 (13:23 +1300)
committerNick Cameron <ncameron@mozilla.com>
Tue, 16 Dec 2014 04:05:33 +0000 (17:05 +1300)
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).

src/libgraphviz/lib.rs
src/librustc_typeck/check/method/probe.rs
src/libstd/ascii.rs
src/test/compile-fail/auto-ref-slice-plus-ref.rs
src/test/run-pass/assignability-trait.rs
src/test/run-pass/auto-ref-slice-plus-ref.rs [deleted file]

index fa048346e99b593d1378d52b6137e3da3975e590..e1c44e658f1c8665eefc2063e215e4c536be9346 100644 (file)
@@ -440,7 +440,7 @@ fn escape_str(s: &str) -> String {
     /// 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 @@ fn pre_escaped_content(self) -> CowString<'a> {
         match self {
             EscStr(s) => s,
             LabelStr(s) => if s.contains_char('\\') {
-                s.escape_default().into_cow()
+                (&*s).escape_default().into_cow()
             } else {
                 s
             },
index d3879e49034b19df674b54cf13aa161b7135fa4b..41bb338e9e66b6d66759e7c3c07a4b6e1506be47 100644 (file)
@@ -628,17 +628,7 @@ fn pick_step(&mut self, step: &CandidateStep<'tcx>) -> Option<PickResult<'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 @@ fn pick_autorefd_method(&mut self,
             |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)
index ad2167214a7d413c8e688fb70f78e47954b46250..81e8e4e4d7c6c85e652c9957fff7cc0814f792e9 100644 (file)
@@ -170,7 +170,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 /// 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 @@ fn to_ascii_opt(&self) -> Option<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 @@ fn is_ascii(&self) -> bool {
 }
 
 #[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]
index 83acce2003c2e5004afd40264c7cc0f1bf947320..fb935cf10309629e1017e06673de2bbf03b49e72 100644 (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.
 //
 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) { }
 }
index f623b7911ce6d3c49673629ae9ed6c23a9f70892..b7e3480c076262aeeac3ef82e38d4dfc49f7ff68 100644 (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());
 }
diff --git a/src/test/run-pass/auto-ref-slice-plus-ref.rs b/src/test/run-pass/auto-ref-slice-plus-ref.rs
deleted file mode 100644 (file)
index 13dd55c..0000000
+++ /dev/null
@@ -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
-}