Skip to content

Trait object coercion supercedes deref coercion #39801

Open
@abonander

Description

@abonander

This seems like it should work: Playground link

use std::sync::Arc;

trait Foo {}

struct Bar;

impl Foo for Bar {}

fn takes_foo(foo: &Foo) {}

fn main() {
    let foo: Arc<Foo> = Arc::new(Bar);
    takes_foo(&foo);
}

However, it seems the compiler is attempting to coerce &Arc<Foo> to a trait object before attempting deref coercion, which gives this unintuitive error:

rustc 1.15.1 (021bd294c 2017-02-08)
error[E0277]: the trait bound `std::sync::Arc<Foo>: Foo` is not satisfied
  --> <anon>:13:15
   |
13 |     takes_foo(&foo);
   |               ^^^^ the trait `Foo` is not implemented for `std::sync::Arc<Foo>`
   |
   = note: required for the cast to the object type `Foo`

Adding a deref-reref seems to fix the issue, but it's definitely a papercut:

takes_foo(&*foo);

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-coercionsArea: implicit and explicit `expr as Type` coercionsA-dyn-traitArea: trait objects, vtable layoutC-feature-requestCategory: A feature request, i.e: not implemented / a PR.I-needs-decisionIssue: In need of a decision.T-langRelevant to the language teamT-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions