pub trait BarT {
fn x(&self);
fn y(&self) {
foo(&self)
}
}
fn foo(bar: &dyn BarT) {
bar.x()
}
Why does this function not compile? It seems obvious that the called of BarT::y has a &self that satisfies &dyn BarT.
pub trait BarT {
fn x(&self);
fn y(&self) {
foo(&self)
}
}
fn foo(bar: &dyn BarT) {
bar.x()
}
Why does this function not compile? It seems obvious that the called of BarT::y has a &self that satisfies &dyn BarT.
When a function is defined with &self
, the type of self
is &Self
, so &self
is of type &&Self
.
And even if you call foo(self)
, that won't work either:
pub
trait BarT {
fn x (self: &'_ Self)
;
fn y (self: &'_ Self)
{
foo(self)
}
}
fn foo (bar: &'_ (dyn BarT))
{
bar.x()
}
Indeed you can only coerce an &'_ (impl BarT + Sized)
to the &'_ (dyn BarT)
type; you cannot coerce a &'_ (impl BarT + ?Sized)
. And unless you opt out through some trait bound, inside a trait the Self
parameter defaults to ?Sized
.
The reason for that, I think, is that at some point there could be:
trait SubTrait : BarT { ... }
leading to the type dyn SubTrait : BarT
, so for Self = dyn SubTrait
, the default method would monomorphise to:
fn y (self: &'_ (dyn SubTrait))
{
foo(self); // Error, expected `&'_ (dyn Bar)`, found `&'_ dyn SubTrait`
}
The solution, in a word with partial implementations (a feature that, for some reason, is intertwined with specialization
), would be:
pub
trait BarT {
fn x (self: &'_ Self)
;
fn y (self: &'_ Self)
{
foo(self)
}
}
default // partial
impl<T : BarT /* + Sized */> BarT for T {
fn y (self: &'_ T)
{
foo(self)
}
}
And a translation of that in stable Rust is:
pub
trait BarT : BarT_y {
fn x (self: &'_ Self)
;
}
pub
trait BarT_y {
fn y (self: &'_ Self)
;
}
impl<T : BarT /* + Sized */> BarT_y for T {
fn y (self: &'_ T)
{
foo(self)
}
}
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.