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

Additional trait restrictions prevent use of trait methods #44064

Closed
Xaeroxe opened this issue Aug 23, 2017 · 3 comments
Closed

Additional trait restrictions prevent use of trait methods #44064

Xaeroxe opened this issue Aug 23, 2017 · 3 comments

Comments

@Xaeroxe
Copy link
Contributor

Xaeroxe commented Aug 23, 2017

Adding Send + Sync restrictions to an Any trait object causes the trait object to lose the downcast_ref method

https://play.rust-lang.org/?gist=9c665d721a9c6a2845f55e56d97ffe27&version=stable

use std::any::Any;

struct Foo;

// This compiles
fn main() {
    let foo: Box<Any> = Box::new(Foo) as Box<Any>;
    let foo = &foo;
    let foo = foo.downcast_ref::<Foo>().unwrap();
}

// This compiles
fn main_2() {
    let foo: Box<Any + Send + Sync> = Box::new(Foo) as Box<Any + Send + Sync>;
    let foo = &foo;
    let foo = Any::downcast_ref::<Foo>(foo).unwrap();
}

// This doesn't compile
fn main_3() {
    let foo: Box<Any + Send + Sync> = Box::new(Foo) as Box<Any + Send + Sync>;
    let foo = &foo;
    let foo = foo.downcast_ref::<Foo>().unwrap();
}

I would expect main_3 to compile, because main_2 compiles, however main_3 fails to compile with the error

error[E0599]: no method named `downcast_ref` found for type `&std::boxed::Box<std::any::Any + std::marker::Send + std::marker::Sync>` in the current scope
  --> src/main.rs:23:19
   |
23 |     let foo = foo.downcast_ref::<Foo>().unwrap();
   |                   ^^^^^^^^^^^^

error: aborting due to previous error(s)

error: Could not compile `playground`.

To learn more, run the command again with --verbose.

Meta

$ rustc --version
rustc 1.19.0 (0ade339 2017-07-17)

@kennytm
Copy link
Member

kennytm commented Aug 23, 2017

Any + Send also works, since there is an impl for it. This needs a separate impl due to #23423, in order to fix #18737.

So to fix this we just need to forward Any + Sync and Any + Send + Sync also.

@Xaeroxe
Copy link
Contributor Author

Xaeroxe commented Aug 23, 2017

After thoughts on filing this issue:

I guess the question is "should adding a provided method on a trait be a breaking change for multi-trait trait objects in the event that ambiguity between methods for multiple traits is introduced by the provided method's presence?" Which I think the answer is no, so yeah it makes sense to prevent method calls in this way, but perhaps the compiler could give a better syntax hint as to what should be done instead.

I wouldn't be opposed to an impl for Any + Send + Sync but I also don't think it's terribly necessary.

@Xaeroxe
Copy link
Contributor Author

Xaeroxe commented Aug 23, 2017

I also don't think it's terribly necessary.

So I'm going to close this issue.

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

2 participants