1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
45//! A collection of uninstantiable types.
6//!
7//! These uninstantiable types can be used to satisfy trait bounds in
8//! uninstantiable situations. Different parts of core provide implementations
9//! of their local traits on these types, so they can be used in uninstantiable
10//! contexts.
1112use core::convert::Infallible as Never;
13use core::marker::PhantomData;
1415use explicit::UnreachableExt as _;
1617use crate::{
18 BidirectionalConverter, CoreTimerContext, CoreTxMetadataContext, CounterContext, Device,
19 DeviceIdContext, ResourceCounterContext, TimerBindingsTypes, TxMetadataBindingsTypes,
20};
2122/// An uninstantiable type.
23#[derive(Clone, Copy)]
24pub struct Uninstantiable(Never);
2526impl AsRef<Never> for Uninstantiable {
27fn as_ref(&self) -> &Never {
28&self.0
29}
30}
3132impl<I, O> BidirectionalConverter<I, O> for Uninstantiable {
33fn convert_back(&self, _: O) -> I {
34self.uninstantiable_unreachable()
35 }
36fn convert(&self, _: I) -> O {
37self.uninstantiable_unreachable()
38 }
39}
4041/// An uninstantiable type that wraps an instantiable type, `A`.
42///
43/// This type can be used to more easily implement traits where `A` already
44/// implements the trait.
45// TODO(https://github.com/rust-lang/rust/issues/118212): Simplify the trait
46// implementations once Rust supports function delegation. Those impls are
47// spread among the core crates.
48pub struct UninstantiableWrapper<A>(Never, PhantomData<A>);
4950impl<A> AsRef<Never> for UninstantiableWrapper<A> {
51fn as_ref(&self) -> &Never {
52let Self(never, _marker) = self;
53&never
54 }
55}
5657impl<T, BT, C> CoreTimerContext<T, BT> for UninstantiableWrapper<C>
58where
59BT: TimerBindingsTypes,
60 C: CoreTimerContext<T, BT>,
61{
62fn convert_timer(dispatch_id: T) -> BT::DispatchId {
63 C::convert_timer(dispatch_id)
64 }
65}
6667impl<P, C> CounterContext<C> for UninstantiableWrapper<P> {
68fn counters(&self) -> &C {
69self.uninstantiable_unreachable()
70 }
71}
7273impl<P, R, C> ResourceCounterContext<R, C> for UninstantiableWrapper<P> {
74fn per_resource_counters(&self, _resource: &R) -> &C {
75self.uninstantiable_unreachable()
76 }
77}
7879impl<T, BT, C> CoreTxMetadataContext<T, BT> for UninstantiableWrapper<C>
80where
81BT: TxMetadataBindingsTypes,
82{
83fn convert_tx_meta(&self, _tx_meta: T) -> BT::TxMetadata {
84self.uninstantiable_unreachable()
85 }
86}
8788impl<D: Device, C: DeviceIdContext<D>> DeviceIdContext<D> for UninstantiableWrapper<C> {
89type DeviceId = C::DeviceId;
90type WeakDeviceId = C::WeakDeviceId;
91}
9293impl<A: Iterator> Iterator for UninstantiableWrapper<A> {
94type Item = A::Item;
9596fn next(&mut self) -> Option<Self::Item> {
97self.uninstantiable_unreachable()
98 }
99}