1use core::{convert::Infallible, ops::Add};
9
10#[sealed::sealed]
11pub trait DropKind {
12 type NeedsDrop: DropKind;
15}
16
17pub(crate) type NeedsDrop<T> = <T as DropKind>::NeedsDrop;
18
19pub enum NoDrop {}
21
22pub enum AutoDrop {}
24
25pub struct CustomDrop<I: DropKind>(core::marker::PhantomData<I>, Infallible);
27
28#[sealed::sealed]
29impl DropKind for NoDrop {
30 type NeedsDrop = NoDrop;
31}
32#[sealed::sealed]
33impl DropKind for AutoDrop {
34 type NeedsDrop = AutoDrop;
35}
36#[sealed::sealed]
37impl<K: DropKind> DropKind for CustomDrop<K> {
38 type NeedsDrop = AutoDrop;
39}
40
41impl<I: DropKind> Add<I> for NoDrop {
42 type Output = I::NeedsDrop;
43
44 fn add(self, _: I) -> Self::Output {
45 unreachable!()
46 }
47}
48
49impl<Rhs> Add<Rhs> for AutoDrop {
50 type Output = Self;
51
52 fn add(self, _: Rhs) -> Self::Output {
53 unreachable!()
54 }
55}
56
57impl Add<NoDrop> for CustomDrop<NoDrop> {
58 type Output = AutoDrop;
59
60 fn add(self, _: NoDrop) -> Self::Output {
61 unreachable!()
62 }
63}
64
65impl Add<AutoDrop> for CustomDrop<NoDrop> {
66 type Output = AutoDrop;
67
68 fn add(self, _: AutoDrop) -> Self::Output {
69 unreachable!()
70 }
71}
72
73impl<I: DropKind> Add<CustomDrop<I>> for CustomDrop<NoDrop> {
74 type Output = AutoDrop;
75
76 fn add(self, _: CustomDrop<I>) -> Self::Output {
77 unreachable!()
78 }
79}
80
81impl<Rhs> Add<Rhs> for CustomDrop<AutoDrop> {
82 type Output = AutoDrop;
83
84 fn add(self, _: Rhs) -> Self::Output {
85 unreachable!()
86 }
87}