Expand description
§Calling Convention Polymorphism in Rust
To parameterize a function by calling convention, we can specify that it takes some T: By<'a, Convention>
, and say that its input is of type <T as By<'a, Convention>>::Type
. This is essentially a defunctionalization of Rust’s reference operators.
This trick can be used to permit the implementor of a trait to pick the calling convention for
a value passed into (or out of) a function defined in that trait, rather than this being
hardcoded in the trait definition.
§Examples
For instance, say we wanted to define an abstraction for channels that can send values. Imagine, however, that some channels might need to take ownership of the values they send, while others might serialize values given only a reference to that value. In order to unify these two notions into one trait, we can parameterize over the calling convention for the input value:
use call_by::{By, Convention};
trait Sender<'a, T>
where
T: By<'a, Self::Convention>,
{
type Convention: Convention;
fn send(&self, value: <T as By<'a, Self::Convention>>::Type);
}
Implementers of the Sender
trait can choose whether the associated type Convention
should be
Val
, Ref
, or Mut
, which toggles the result of <T as By<'a, Self::Convention>>::Type
between T
, &'a T
, and &'a mut T
, respectively. Meanwhile, callers of the send
method on
concretely known types don’t need to specify the calling convention; the type-level function
determines what type they need to pass as the argument to send
, and type errors are reported
in reference to that concrete type if it is known at the call site.
Structs§
- Mut
- Taking a
T
byMut
able reference means taking&'a mut T
as input to or output from a function. - Ref
- Taking a
T
byRef
erence means taking&'a T
as input to or output from a function. - Val
- Taking a
T
byVal
ue means taking aT
as input to or output from a function.
Traits§
- As
- The generalization of
Into
,AsRef
, andAsMut
: in a calling-convention polymorphic context, this trait allows you to invoke the appropriate conversion method depending on the applicable calling convention. - By
- To get the type of
T
via calling conventionConvention
, write<T as By<'a, Convention>>::Type
. - Convention
- There are three fundamental ways to pass a
T
as input or return aT
as output: byVal
ue, by shared immutableRef
erence, and by uniqueMut
able reference. - Convert
- Convert between different calling conventions.
Functions§
- from_
mut - Safe, zero-cost cast from
&'a mut T
to<T as By<'a, Mut>>::Type
. - from_
ref - Safe, zero-cost cast from
&'a T
to<T as By<'a, Ref>>::Type
. - from_
val - Safe, zero-cost cast from
T
to<T as By<'a, Val>>::Type
. - to_mut
- Safe, zero-cost cast from
<T as By<'a, Mut>>::Type
to&'a mut T
. - to_ref
- Safe, zero-cost cast from
<T as By<'a, Ref>>::Type
to&'a T
. - to_val
- Safe, zero-cost cast from
<T as By<'a, Val>>::Type
toT
.