Skip to content

Method resolution fails when through a reference to a trait object on Self: Sized methods #82825

Open
@guswynn

Description

@guswynn
trait Trait {
    fn static_call(&self) where Self: Sized;
    
    fn maybe_dynamic_call(&self) {
        unimplemented!("unsupported maybe_dynamic_call");
    }
}

impl<T: ?Sized + Trait> Trait for &T {
    fn static_call(&self) where Self: Sized {
        (**self).maybe_dynamic_call();
    }
}

fn foo(x: &dyn Trait) {
    // Works.
    (&x).static_call();
    
    // Doesn't work (goes through `dyn Trait: Trait`,
    // despite `static_call` not being object-safe)
    x.static_call();
}

(playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=8d985c6ac7adc1a9835d4c7b5cd74f31)

To me it appears that method resolution should autoref and find the impl on the &T automatically, as the Self: Sized should be

Note that this is specific to &self/&mut self methods, and by-value receivers work, like MANY of the methods on Iterator:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=4dbe34cf1ffec880d225d96bd2370907 (rustc even gives an extremely good diagnostic about & vs &mut), though its unclear to me why in that cause, next is callable in that case, but I think it's because it lacks the Self: Sized bound)

(note that the origin of this issue is me investigating how to stabilize the not-yet implemented std::stream::Stream::next https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7e9fe3092902bafe9e5ae607a12e9b4e)

Thanks @eddyb for helping me minimize this and suggesting that this may be possible to resolve in a simple way.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-dyn-traitArea: trait objects, vtable layoutA-trait-systemArea: Trait systemT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-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