pub trait Cast: Sized {
// Provided method
fn cast<U>(self, interner: <U as HasInterner>::Interner) -> U
where Self: CastTo<U>,
U: HasInterner { ... }
}
Expand description
The Cast
trait is used to make annoying upcasts between
logically equivalent types that imply wrappers. For example, one
could convert a DomainGoal
into a Goal
by doing:
let goal: Goal = domain_goal.cast();
This is equivalent to the more explicit:
let goal: Goal = Goal::DomainGoal(domain_goal)
Another useful trick is the casted()
iterator adapter, which
casts each element in the iterator as it is produced (you must
have the Caster
trait in scope for that).
§Invariant
Cast
imposes a key invariant. You can only implement T: Cast<U>
if both T
and U
have the same semantic meaning. Also,
as part of this, they should always use the same set of free
variables (the Canonical
implementation, for example, relies on
that).
§Iterators
If you import the Caster
trait, you can also write .casted()
on an
iterator chain to cast every instance within.
§Implementing Cast
Do not implement Cast
directly. Instead, implement CastTo
.
This split setup allows us to write foo.cast::<T>()
to mean
“cast to T”.
Provided Methods§
fn cast<U>(self, interner: <U as HasInterner>::Interner) -> Uwhere
Self: CastTo<U>,
U: HasInterner,
fn cast<U>(self, interner: <U as HasInterner>::Interner) -> Uwhere
Self: CastTo<U>,
U: HasInterner,
Cast a value to type U
using CastTo
.