pub trait DefaultViewInstance {
// Required method
fn default_view_instance<'a>() -> &'a Self
where Self: 'a;
}Expand description
Provides access to a lazily-initialized default view instance.
View types implement this trait so that MessageFieldView can
dereference to a default when unset, just as MessageField
does for owned types via DefaultInstance.
Generated view types like FooView<'a> contain only covariant borrows
(&'a str, &'a [u8], etc.). A default view holds only 'static data
("", &[], 0), so an implementation stores a single
&'static FooView<'static> and returns it at the caller’s lifetime via
ordinary covariant subtyping — the compiler verifies covariance at the
impl site, so no unsafe is required.
§Recommended implementation
The pattern codegen uses (and the recommended pattern for hand-written
view types) stores the instance in a static
once_cell::race::OnceBox (re-exported as
::buffa::__private::OnceBox):
impl<'v> DefaultViewInstance for MyView<'v> {
fn default_view_instance<'a>() -> &'a Self
where
Self: 'a,
{
static VALUE: ::buffa::__private::OnceBox<MyView<'static>>
= ::buffa::__private::OnceBox::new();
VALUE.get_or_init(|| Box::new(<MyView<'static>>::default()))
}
}The return expression has type &'static MyView<'static>; the compiler
coerces it to &'a MyView<'v> iff MyView is covariant in 'v —
non-covariant view types fail to compile here rather than risk an
unsound cast.
§Non-covariant types are rejected
A type that is invariant in its lifetime parameter cannot satisfy the
recommended pattern, because the &'static T<'static> → &'a T<'v>
coercion is refused:
// `fn(&'v ()) -> &'v ()` is invariant in 'v, making `Invariant<'v>` invariant.
struct Invariant<'v>(PhantomData<fn(&'v ()) -> &'v ()>);
static INST: Invariant<'static> = Invariant(PhantomData);
impl<'v> buffa::view::DefaultViewInstance for Invariant<'v> {
fn default_view_instance<'a>() -> &'a Self where Self: 'a {
// error: lifetime may not live long enough
// note: requirement occurs because of the type `Invariant<'_>`,
// which makes the generic argument `'_` invariant
&INST
}
}Required Methods§
Sourcefn default_view_instance<'a>() -> &'a Selfwhere
Self: 'a,
fn default_view_instance<'a>() -> &'a Selfwhere
Self: 'a,
Return a reference to the single default view instance.
The lifetime 'a is caller-chosen up to Self: 'a, so a
FooView<'v> can serve its 'static default at any 'a ≤ 'v.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.