Description
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.