Skip to content

Additional trait restrictions prevent use of trait methods #44064

Closed

Description

@Xaeroxe

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)

Activity

  1. kennytm commented on Aug 23, 2017

    @kennytm
    Member

    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.

  2. Xaeroxe commented on Aug 23, 2017

    @Xaeroxe
    ContributorAuthor

    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.

  3. Xaeroxe commented on Aug 23, 2017

    @Xaeroxe
    ContributorAuthor

    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions