1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! A collection of uninstantiable types.
//!
//! These uninstantiable types can be used to satisfy trait bounds in
//! uninstantiable situations. Different parts of core provide implementations
//! of their local traits on these types, so they can be used in uninstantiable
//! contexts.

use core::convert::Infallible as Never;
use core::marker::PhantomData;

use explicit::UnreachableExt as _;

use crate::{
    BidirectionalConverter, CoreTimerContext, CounterContext, Device, DeviceIdContext,
    TimerBindingsTypes,
};

/// An uninstantiable type.
#[derive(Clone, Copy)]
pub struct Uninstantiable(Never);

impl AsRef<Never> for Uninstantiable {
    fn as_ref(&self) -> &Never {
        &self.0
    }
}

impl<I, O> BidirectionalConverter<I, O> for Uninstantiable {
    fn convert_back(&self, _: O) -> I {
        self.uninstantiable_unreachable()
    }
    fn convert(&self, _: I) -> O {
        self.uninstantiable_unreachable()
    }
}

/// An uninstantiable type that wraps an instantiable type, `A`.
///
/// This type can be used to more easily implement traits where `A` already
/// implements the trait.
// TODO(https://github.com/rust-lang/rust/issues/118212): Simplify the trait
// implementations once Rust supports function delegation. Those impls are
// spread among the core crates.
pub struct UninstantiableWrapper<A>(Never, PhantomData<A>);

impl<A> AsRef<Never> for UninstantiableWrapper<A> {
    fn as_ref(&self) -> &Never {
        let Self(never, _marker) = self;
        &never
    }
}

impl<T, BT, C> CoreTimerContext<T, BT> for UninstantiableWrapper<C>
where
    BT: TimerBindingsTypes,
    C: CoreTimerContext<T, BT>,
{
    fn convert_timer(dispatch_id: T) -> BT::DispatchId {
        C::convert_timer(dispatch_id)
    }
}

impl<P, C> CounterContext<C> for UninstantiableWrapper<P> {
    fn with_counters<O, F: FnOnce(&C) -> O>(&self, _cb: F) -> O {
        self.uninstantiable_unreachable()
    }
}

impl<D: Device, C: DeviceIdContext<D>> DeviceIdContext<D> for UninstantiableWrapper<C> {
    type DeviceId = C::DeviceId;
    type WeakDeviceId = C::WeakDeviceId;
}

impl<A: Iterator> Iterator for UninstantiableWrapper<A> {
    type Item = A::Item;

    fn next(&mut self) -> Option<Self::Item> {
        self.uninstantiable_unreachable()
    }
}