Skip to content
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

Dynamic dispatch through traits requires a managed pointer #8804

Closed
zeux opened this issue Aug 28, 2013 · 3 comments
Closed

Dynamic dispatch through traits requires a managed pointer #8804

zeux opened this issue Aug 28, 2013 · 3 comments

Comments

@zeux
Copy link

zeux commented Aug 28, 2013

I'm trying to write a function that reads 4 bytes from the reader using Reader trait and dynamic dispatch. This code:

fn readbytes(reader: &std::io::Reader) -> ~[u8] { reader.read_bytes(4) }

results in this error:

<anon>:5:59: 5:81 error: failed to find an implementation of trait std::io::Reader for &std::io::Reader<no-bounds>

The error message is confusing; nevertheless, replacing borrowed pointer with a managed one makes the code compile:

fn readbytes(reader: @std::io::Reader) -> ~[u8] { reader.read_bytes(4) }

However, requiring a managed pointer for dynamic dispatch seems excessive. Is this a bug?

@alexcrichton
Copy link
Member

This may not be so much of a bug with dynamic dispatch, but rather with how std::io is designed. Inside of that module, you'll find:

impl Reader for @Reader { ... }
impl<T: Reader> ReaderUtil for T { ... }

I think what's happening here is that there's no impl of Reader for &Reader (which is a bit odd), so that's why @Reader is explicitly working. There's a few things to note about this though:

  1. std::io is going to be removed soon
  2. ReaderUtil should probably be implemented as default methods (now that they work) instead of a helper trait.
  3. The method lookup should probably actually work in this case.

As an example, I think that this code should compile:

trait A {}
trait B { fn foo(&self); }

impl<T: A> B for T {
    fn foo(&self) {}
}

fn foo(a: &A) {
    a.foo();
}

fn main() {}

Basically, if you ignore all the ways in which I think std::io should change, I think that this small code sample should compile regardless.

@thestinger
Copy link
Contributor

Note that std::io is being replaced with std::rt::io.

@nikomatsakis
Copy link
Contributor

As @alexcrichton said, this is a bug with io (which is a known problem). Regarding the later example he gave, that snippet does not compile and should not compile because the object type &A does not automatically implement the trait A. The reason for this is that, to implement a trait, a type must implement ALL of the trait methods, but some traits have methods that are not usable with various object types (as a simple example, consider an @self method -- how could you invoke that on an &A object?). Closing since there is no bug to be fixed except for io, and work there is in progress.

Jarcho pushed a commit to Jarcho/rust that referenced this issue Aug 29, 2022
Rework `only_used_in_recursion`

fixes rust-lang#8782
fixes rust-lang#8629
fixes rust-lang#8560
fixes rust-lang#8556

This is a complete rewrite of the lint. This loses some capabilities of the old implementation. Namely the ability to track through tuple and slice patterns, as well as the ability to trace through assignments.

The two reported bugs are fixed with this. One was caused by using the name of the method rather than resolving to the `DefId` of the called method. The second was cause by using the existence of a cycle in the dependency graph to determine whether the parameter was used in recursion even though there were other ways to create a cycle in the graph.

Implementation wise this switches from using a visitor to walking up the tree from every use of each parameter until it has been determined the parameter is used for something other than recursion. This is likely to perform better as it avoids walking the entire function a second time, and it is unlikely to walk up the HIR tree very much. Some cases would perform worse though.

cc `@buttercrab`

changelog: Scale back `only_used_in_recursion` to fix false positives
changelog: Move `only_used_in_recursion` back to `complexity`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants