Skip to content

No error despite of multiple applicable methods in scope #26080

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
michas2 opened this issue Jun 7, 2015 · 7 comments
Open

No error despite of multiple applicable methods in scope #26080

michas2 opened this issue Jun 7, 2015 · 7 comments
Labels
C-bug Category: This is a bug. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@michas2
Copy link

michas2 commented Jun 7, 2015

Given the following code:

extern crate mio;
use mio::buf::RingBuf;
use mio::buf::Buf;
use std::io::Read;

fn main() {
    let buf = RingBuf::new(10);
    let bytes = buf.bytes();
    println!("{:?}", bytes);
}

buf is of type RingBuf. RingBuf does not provide .bytes(), but it implements both Buf and Read, which both provide a .bytes() implementation.

According to https://doc.rust-lang.org/book/ufcs.html the compiler should complain. But it simply chooses to take the implementation of Read, which return the "wrong" result type.

(Without the "use Read" line rust chooses the implementation of Buf, which return the "correct" type.)

(I am using Rust 1.0.0.)

@bluss
Copy link
Member

bluss commented Jun 7, 2015

Edit: Found a good reproduction, I think this explains the situation. I'm still surprised that this is allowed, but the methods in question have different self type -- &self vs self.

struct Type;

trait A {
    fn foo(&self) -> bool { false }
}

trait B : Sized {
    fn foo(self) -> bool { true }
}

impl A for Type { }
impl B for Type { }

fn main() {
    println!("{}", Type.foo());   // This will call B::foo -- it will prefer `self`.
}

@arielb1
Copy link
Contributor

arielb1 commented Jun 8, 2015

UFCS is not used here (that would be <RingBuf>::bytes). Method lookup tries autoderefs/autorefs in the order 0 autoderef -> 0 autoderef + autoref -> 1 autoderef -> 1 autoderef + autoref -> .... This is required for e.g. rc.clone() (but, of course, not for <Rc>::clone) to work.

We might want to make k autoderefs be ambiguous with k autoderefs + autoref, but this is of course a breaking change (an annotatable one, through) and somebody may be relying on it.

@bluss
Copy link
Member

bluss commented Jun 8, 2015

@michas2 It may be that it's a known "feature" of method look up priorities, yours and my example both use the fact that the methods use self vs. &self and thus the self is preferred.

It's confusing but perhaps not a bug like I thought!

As @arielb1 says, using the <Typename>::bytes(...) syntax will produce the ambiguous methods error message.

@alexcrichton
Copy link
Member

triage: I-nominated

@alexcrichton alexcrichton added T-lang Relevant to the language team, which will review and decide on the PR/issue. and removed I-nominated labels Jun 8, 2015
@pnkfelix
Copy link
Member

pnkfelix commented Jan 3, 2017

triage: still an issue.

@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 22, 2017
@steveklabnik
Copy link
Member

Triage: still reproduces, not something that I think we're likely to change?

@Spoonbender
Copy link

Triage: still reproduces

Do we still consider this a bug?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

9 participants