Skip to content

Commit

Permalink
auto merge of #17464 : pcwalton/rust/inherent-methods-on-equal-footin…
Browse files Browse the repository at this point in the history
…g, 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
  • Loading branch information
bors committed Sep 26, 2014
2 parents 5d653c1 + 21df9c8 commit d64b410
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 19 deletions.
11 changes: 0 additions & 11 deletions src/librustc/middle/typeck/check/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/util/ppaux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
}

Expand Down
15 changes: 11 additions & 4 deletions src/libstd/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-pass/class-cast-to-trait-cross-crate-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-pass/class-separate-impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
34 changes: 34 additions & 0 deletions src/test/run-pass/inherent-trait-method-order.rs
Original file line number Diff line number Diff line change
@@ -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();
}

2 changes: 1 addition & 1 deletion src/test/run-pass/issue-3702.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub fn main() {
}

fn to_string(t: Box<Text>) {
println!("{}", t.to_string());
println!("{}", (*t).to_string());
}

}

0 comments on commit d64b410

Please sign in to comment.