auto merge of #17464 : pcwalton/rust/inherent-methods-on-equal-footing, r=nikomatsakis

over inherent methods accessible via more autoderefs.

This simplifies the trait matching algorithm. It breaks code like:

    impl Foo {
        fn foo(self) {
            // before this change, this will be called
        }
    }

    impl<'a,'b,'c> Trait for &'a &'b &'c Foo {
        fn foo(self) {
            // after this change, this will be called
        }
    }

    fn main() {
        let x = &(&(&Foo));
        x.foo();
    }

To explicitly indicate that you wish to call the inherent method, perform
explicit dereferences. For example:

    fn main() {
        let x = &(&(&Foo));
        (***x).foo();
    }

Part of #17282.

[breaking-change]

r? @nikomatsakis
This commit is contained in:
bors 2014-09-26 21:47:47 +00:00
commit d64b4103d6
7 changed files with 50 additions and 19 deletions

View File

@ -158,13 +158,7 @@ pub fn lookup<'a, 'tcx>(
debug!("searching inherent candidates");
lcx.push_inherent_candidates(self_ty);
let mme = lcx.search(self_ty);
if mme.is_some() {
return mme;
}
debug!("searching extension candidates");
lcx.reset_candidates();
lcx.push_bound_candidates(self_ty, None);
lcx.push_extension_candidates(expr.id);
lcx.search(self_ty)
@ -425,11 +419,6 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> {
// ______________________________________________________________________
// Candidate collection (see comment at start of file)
fn reset_candidates(&mut self) {
self.inherent_candidates = Vec::new();
self.extension_candidates = Vec::new();
}
fn push_inherent_candidates(&mut self, self_ty: ty::t) {
/*!
* Collect all inherent candidates into

View File

@ -881,7 +881,8 @@ impl Repr for ty::Variance {
// The first `.to_string()` returns a &'static str (it is not an implementation
// of the ToString trait). Because of that, we need to call `.to_string()` again
// if we want to have a `String`.
self.to_string().to_string()
let result: &'static str = (*self).to_string();
result.to_string()
}
}

View File

@ -946,11 +946,14 @@ pub trait Reader {
}
impl<'a> Reader for Box<Reader+'a> {
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.read(buf) }
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
let reader: &mut Reader = &mut **self;
reader.read(buf)
}
}
impl<'a> Reader for &'a mut Reader+'a {
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.read(buf) }
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { (*self).read(buf) }
}
/// Returns a slice of `v` between `start` and `end`.
@ -1281,10 +1284,14 @@ pub trait Writer {
impl<'a> Writer for Box<Writer+'a> {
#[inline]
fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.write(buf) }
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
(&mut **self).write(buf)
}
#[inline]
fn flush(&mut self) -> IoResult<()> { self.flush() }
fn flush(&mut self) -> IoResult<()> {
(&mut **self).flush()
}
}
impl<'a> Writer for &'a mut Writer+'a {

View File

@ -15,7 +15,7 @@ use std::to_string::ToString;
use cci_class_cast::kitty::cat;
fn print_out(thing: Box<ToString>, expected: String) {
let actual = thing.to_string();
let actual = (*thing).to_string();
println!("{}", actual);
assert_eq!(actual.to_string(), expected);
}

View File

@ -58,7 +58,7 @@ impl fmt::Show for cat {
}
fn print_out(thing: Box<ToString>, expected: String) {
let actual = thing.to_string();
let actual = (*thing).to_string();
println!("{}", actual);
assert_eq!(actual.to_string(), expected);
}

View File

@ -0,0 +1,34 @@
// Copyright 2014 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.
struct Foo;
impl Foo {
#[allow(dead_code)]
fn foo(self) {
fail!("wrong method!")
}
}
trait Trait {
fn foo(self);
}
impl<'a,'b,'c> Trait for &'a &'b &'c Foo {
fn foo(self) {
// ok
}
}
fn main() {
let x = &(&(&Foo));
x.foo();
}

View File

@ -15,7 +15,7 @@ pub fn main() {
}
fn to_string(t: Box<Text>) {
println!("{}", t.to_string());
println!("{}", (*t).to_string());
}
}