提交 21df9c80 编写于 作者: P Patrick Walton

librustc: Give trait methods accessible via fewer autoderefs priority

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]
上级 5d653c17
...@@ -158,13 +158,7 @@ pub fn lookup<'a, 'tcx>( ...@@ -158,13 +158,7 @@ pub fn lookup<'a, 'tcx>(
debug!("searching inherent candidates"); debug!("searching inherent candidates");
lcx.push_inherent_candidates(self_ty); lcx.push_inherent_candidates(self_ty);
let mme = lcx.search(self_ty);
if mme.is_some() {
return mme;
}
debug!("searching extension candidates"); debug!("searching extension candidates");
lcx.reset_candidates();
lcx.push_bound_candidates(self_ty, None); lcx.push_bound_candidates(self_ty, None);
lcx.push_extension_candidates(expr.id); lcx.push_extension_candidates(expr.id);
lcx.search(self_ty) lcx.search(self_ty)
...@@ -425,11 +419,6 @@ fn is_overloaded_deref(&self) -> bool { ...@@ -425,11 +419,6 @@ fn is_overloaded_deref(&self) -> bool {
// ______________________________________________________________________ // ______________________________________________________________________
// Candidate collection (see comment at start of file) // 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) { fn push_inherent_candidates(&mut self, self_ty: ty::t) {
/*! /*!
* Collect all inherent candidates into * Collect all inherent candidates into
......
...@@ -881,7 +881,8 @@ fn repr(&self, _: &ctxt) -> String { ...@@ -881,7 +881,8 @@ fn repr(&self, _: &ctxt) -> String {
// The first `.to_string()` returns a &'static str (it is not an implementation // 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 // of the ToString trait). Because of that, we need to call `.to_string()` again
// if we want to have a `String`. // if we want to have a `String`.
self.to_string().to_string() let result: &'static str = (*self).to_string();
result.to_string()
} }
} }
......
...@@ -946,11 +946,14 @@ fn by_ref<'a>(&'a mut self) -> RefReader<'a, Self> { ...@@ -946,11 +946,14 @@ fn by_ref<'a>(&'a mut self) -> RefReader<'a, Self> {
} }
impl<'a> Reader for Box<Reader+'a> { 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 { 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`. /// Returns a slice of `v` between `start` and `end`.
...@@ -1281,10 +1284,14 @@ fn by_ref<'a>(&'a mut self) -> RefWriter<'a, Self> { ...@@ -1281,10 +1284,14 @@ fn by_ref<'a>(&'a mut self) -> RefWriter<'a, Self> {
impl<'a> Writer for Box<Writer+'a> { impl<'a> Writer for Box<Writer+'a> {
#[inline] #[inline]
fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.write(buf) } fn write(&mut self, buf: &[u8]) -> IoResult<()> {
(&mut **self).write(buf)
}
#[inline] #[inline]
fn flush(&mut self) -> IoResult<()> { self.flush() } fn flush(&mut self) -> IoResult<()> {
(&mut **self).flush()
}
} }
impl<'a> Writer for &'a mut Writer+'a { impl<'a> Writer for &'a mut Writer+'a {
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
use cci_class_cast::kitty::cat; use cci_class_cast::kitty::cat;
fn print_out(thing: Box<ToString>, expected: String) { fn print_out(thing: Box<ToString>, expected: String) {
let actual = thing.to_string(); let actual = (*thing).to_string();
println!("{}", actual); println!("{}", actual);
assert_eq!(actual.to_string(), expected); assert_eq!(actual.to_string(), expected);
} }
......
...@@ -58,7 +58,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ...@@ -58,7 +58,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
} }
fn print_out(thing: Box<ToString>, expected: String) { fn print_out(thing: Box<ToString>, expected: String) {
let actual = thing.to_string(); let actual = (*thing).to_string();
println!("{}", actual); println!("{}", actual);
assert_eq!(actual.to_string(), expected); assert_eq!(actual.to_string(), expected);
} }
......
// 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();
}
...@@ -15,7 +15,7 @@ trait Text { ...@@ -15,7 +15,7 @@ trait Text {
} }
fn to_string(t: Box<Text>) { fn to_string(t: Box<Text>) {
println!("{}", t.to_string()); println!("{}", (*t).to_string());
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册