Skip to main content

safe_manually_drop/
_lib.rs

1//! [SafeManuallyDrop]: `SafeManuallyDrop`
2//! [`SafeManuallyDrop`]: `SafeManuallyDrop`
3//! [`SafeManuallyDrop::into_inner_defusing_impl_Drop()`]: `SafeManuallyDrop::into_inner_defusing_impl_Drop()`
4//! [`DropManually`]: `DropManually`
5//! [`DropManually::drop_manually()`]: `DropManually::drop_manually()`
6//! [`appendix`]: `appendix`
7//!
8//! [`ManuallyDrop`]: `ManuallyDrop`
9//! [`::core::ops::Deref`]: `::core::ops::Deref`
10//! [`::core::ops::DerefMut`]: `::core::ops::DerefMut`
11//! [`Drop`]: `Drop`
12//! [`Option`]: `Option`
13//! [`From::from()`]: `From::from()`
14#![doc = include_str!("../README.md")]
15#![cfg_attr(not(doc), no_std)]
16#![allow(unused_braces)]
17#![cfg_attr(feature = "better-docs", feature(doc_cfg, negative_impls))]
18
19use ::core::{
20    marker::PhantomData as PD,
21    mem::{ManuallyDrop, ManuallyDrop as MD},
22};
23
24#[cfg(doc)]
25#[cfg_attr(feature = "better-docs", doc(cfg(doc)))]
26#[doc = include_str!("appendix.md")]
27pub mod appendix {}
28
29/// The crate's prelude.
30pub
31mod prelude {
32    #[doc(no_inline)]
33    pub use crate::{
34        DropManually,
35        SafeManuallyDrop,
36    };
37}
38
39/// The main/whole point of this whole crate and design: to expose _owned_ access to a `FieldTy`
40/// when drop glue is being run.
41///
42///  1. A [`SafeManuallyDrop<FieldTy, ContainingType>`],
43///  1. with a (mandatory)
44///     <code>impl [DropManually\<FieldTy\>][`DropManually`] for ContainingType {</code>,
45///  1. once it gets dropped / during its drop glue (_e.g._, from within a `ContainingType`),
46///  1. shall be running the [`DropManually::drop_manually()`] logic on that _owned_ `FieldTy`.
47///
48/// ```rust
49/// # use drop as stuff;
50/// use ::safe_manually_drop::SafeManuallyDrop;
51///
52/// struct Frobnicator {
53///     // …
54/// }
55///
56/// struct Example {
57///     //    ^
58///     //    +--------------------------------+
59///     //                                     |
60///     string: SafeManuallyDrop<Frobnicator, Self>,
61/// } //                                       |
62/// //                                         +-------------vvvvvvv
63/// impl ::safe_manually_drop::DropManually<Frobnicator> for Example {
64///     fn drop_manually(owned_frobnicator: Frobnicator) {
65///         //  owned access! 👆
66///         stuff(owned_frobnicator)
67///     }
68/// }
69/// ```
70///
71/// In practice, this becomes _the_ handy, 0-runtime-overhead, non-`unsafe`, tool to get owned
72/// access to a `struct`'s field (or group thereof) during drop glue.
73///
74/// Indeed, the recipe then becomes:
75///
76///  1. Use, instead of a `field: FieldTy`, a wrapped
77///     <code>field: [SafeManuallyDrop]\<FieldTy, ContainingType\></code>,
78///
79///       - (Usually `Self` can be used instead of having to spell out, _verbatim_, the
80///         `ContainingType`.)
81///
82///       - (This wrapper type offers transparent
83///         <code>[Deref][`::core::ops::Deref`]{,[Mut][`::core::ops::DerefMut`]}</code>, as well as
84///         [`From::from()`] and ["`.into()`"][`SafeManuallyDrop::into_inner_defusing_impl_Drop()`]
85///         conversions.)
86///
87///  1. then, provide the companion, mandatory,
88///     <code>impl [DropManually\<FieldTy\>][`DropManually`] for ContainingType {</code>
89///
90///  1. Profit™ from the owned access to `FieldTy` inside of [`DropManually::drop_manually()`]'s
91///     body.
92///
93/// ### "`OverrideDropGlue`" rather than `PrependDropGlue`
94///
95/// Note that this new drop glue logic for `FieldTy`, defined in [`DropManually::drop_manually()`],
96/// shall _supersede_ / override its default drop glue.
97///
98/// ```rust
99/// # use drop as stuff;
100/// use ::safe_manually_drop::prelude::*;
101///
102/// pub struct MyType(SafeManuallyDrop<String, Self>);
103///
104/// impl DropManually<String> for MyType {
105///     fn drop_manually(s: String) {
106///         // Notice the fully owned access to `s`.
107///         stuff(s)
108///         // Notably, if `s` is not moved out / "consumed",
109///         // then `s`' own drop glue (e.g., here, that of `String`) will be automagically
110///         // *implicitly* invoked when `s` goes out of scope at the end of the block.
111///         //
112///         // This may appear rather similar to the classic `Drop` trait, but there is
113///         // a huge difference: this function body had to *allow* for the implicit
114///         // drop and fall-out-of-scope to happen, by not having *consumed* the owned
115///         // `s: String` in some other way.
116///         //
117///         // To illustrate, the body could very well, for instance, `mem::forget(s)`,
118///         // and no `drop` of the `string` would happen, which is not something
119///         // *directly* doable with the `Drop` trait.
120///     }
121/// }
122///
123/// fn example(it: MyType) {
124///     drop(it); // invokes the drop glue of `MyType`,
125///               // including the `Drop` impl `for SafeManuallyDrop<String, MyType>`
126///               // i.e., `<MyType as DropManually<String>>::drop_manually()`.
127/// }
128/// ```
129///
130/// For instance: if, inside of [`DropManually::drop_manually()`], the `FieldTy` is
131/// [`::core::mem::forget()`]ten, then `FieldTy`'s own drop glue shall never actually run, much like
132/// when a [`ManuallyDrop<FieldTy>`] is [`drop()`]-ped/discarded.
133///
134/// With that being said, precisely because [`DropManually::drop_manually()`] receives an owned
135/// instance of `FieldTy`, this behavior is rather "opt-out": that `FieldTy` owned instance runs
136/// out of scope when the function completes, so it will almost always get "dropped" / have its own
137/// drop glue being invoked.
138///
139/// The only exceptions are then when other, ownership-consuming, functions, get called on this
140/// value.
141///
142/// Typically:
143///
144///   - [`::core::mem::forget()`] to skip/bypass all of the drop glue altogether.
145///       - note that a direct [`ManuallyDrop<FieldTy>`] would probably be better in this instance;
146///   - an `impl FnOnce()` getting called (the `()`-call consumes ownership);
147///   - an owned argument `S` is fed to a function, such as `S` in an `impl FnOnce(S)`;
148///   - types using owned type-state patterns, most notably `Transaction::{commit,roll_back}()`.
149#[diagnostic::on_unimplemented(
150    note = "\
151In order for a struct/enum to contain a `SafeManuallyDrop<FieldTy, …>` field:
152
153 1. `…`, the second type parameter, ought to be `Self`, i.e., the containing `struct/enum` \
154    wherein the provided `DropManually` logic makes sense.
155
156    For instance:
157
158    ```rust
159    field: SafeManuallyDrop<FieldTy, Self>,
160    ```
161
162 2. you then have to provide an \
163    `impl<…> DropManually<FieldTy> for <the containing struct/enum> {{`.
164
165    For instance:
166
167    ```rust
168    impl<…> DropManually<FieldTy> for StructName<…> {{
169    ```
170\
171    ",
172)]
173pub
174trait DropManually<FieldTy> {
175    fn drop_manually(_: FieldTy);
176}
177
178/// [`SafeManuallyDrop<FieldTy>`] is the safe counterpart of [`ManuallyDrop<FieldTy>`], and the
179/// zero-runtime-overhead counterpart of [`Option<FieldTy>`].
180///
181///   - A [`SafeManuallyDrop<FieldTy, ContainingType>`],
182///   - with a (mandatory)
183///     <code>impl [DropManually\<FieldTy\>][`DropManually`] for ContainingType {</code>,
184///   - once it gets dropped / during its drop glue (_e.g._, from within a `ContainingType`),
185///   - shall be running the [`DropManually::drop_manually()`] logic on that _owned_ `FieldTy`.
186///
187/// ```rust
188/// # use drop as stuff;
189/// use ::safe_manually_drop::SafeManuallyDrop;
190///
191/// struct Frobnicator {
192///     // …
193/// }
194///
195/// struct Example {
196///     //    ^
197///     //    +--------------------------------+
198///     //                                     |
199///     string: SafeManuallyDrop<Frobnicator, Self>,
200/// } //                                       |
201/// //                                         +-------------vvvvvvv
202/// impl ::safe_manually_drop::DropManually<Frobnicator> for Example {
203///     fn drop_manually(owned_frobnicator: Frobnicator) {
204///         //  owned access! 👆
205///         stuff(owned_frobnicator)
206///     }
207/// }
208/// ```
209///
210/// ## Examples
211///
212///   - Using [`Option<FieldTy>`]: [`.unwrap()`][`Option::unwrap()`]s everywhere 🤢
213///
214///     <details class="custom"><summary><span class="summary-box"><span>Click to show</span></span></summary>
215///
216///     ```rust
217///     #![forbid(unsafe_code)]
218///
219///     struct DeferGuardFields<T, F : FnOnce(T)> {
220///         value: T,
221///         on_drop: F,
222///     }
223///
224///     pub
225///     struct DeferGuard<T, F : FnOnce(T)>(
226///         Option<DeferGuardFields<T, F>>,
227///     );
228///
229///     impl<T, F : FnOnce(T)> Drop for DeferGuard<T, F> {
230///         fn drop(&mut self) {
231///             let DeferGuardFields {
232///                 value,
233///                 on_drop,
234///             } = self.0.take().unwrap(); // 🤢
235///             on_drop(value);
236///         }
237///     }
238///
239///     impl<T, F : FnOnce(T)> ::core::ops::Deref for DeferGuard<T, F> {
240///         type Target = T;
241///
242///         fn deref(&self) -> &T {
243///             &self
244///                 .0
245///                 .as_ref()
246///                 .unwrap() // 🤮
247///                 .value
248///         }
249///     }
250///     // And `DerefMut`
251///     ```
252///
253///     </details>
254///
255///   - Using [`ManuallyDrop<FieldTy>`]: `unsafe`! 😱
256///
257///     <details class="custom"><summary><span class="summary-box"><span>Click to show</span></span></summary>
258///
259///     ```rust
260///     #![deny(unsafe_code)] // require visible `#[allow()]`s in subtle functions.
261///
262///     use ::core::mem::ManuallyDrop;
263///
264///     pub
265///     struct DeferGuard<T, F : FnOnce(T)> {
266///         value: ManuallyDrop<T>,
267///         on_drop: ManuallyDrop<F>,
268///     }
269///
270///     impl<T, F : FnOnce(T)> Drop for DeferGuard<T, F> {
271///         fn drop(&mut self) {
272///             #[allow(unsafe_code)] {
273///                 let value = unsafe { // 😰
274///                     ManuallyDrop::take(&mut self.value)
275///                 };
276///                 let on_drop = unsafe { // 😰
277///                     ManuallyDrop::take(&mut self.on_drop)
278///                 };
279///                 on_drop(value);
280///             }
281///         }
282///     }
283///
284///     impl<T, F : FnOnce(T)> ::core::ops::Deref for DeferGuard<T, F> {
285///         type Target = T;
286///
287///         fn deref(&self) -> &T {
288///             &self.value
289///         }
290///     }
291///     // And `DerefMut`
292///     ```
293///
294///     </details>
295///
296///   - Using [`SafeManuallyDrop<FieldTy, …>`][`SafeManuallyDrop`]: no `unsafe`, no `.unwrap()`s!
297///
298///     ```rust
299///     #![forbid(unsafe_code)]
300///
301///     use ::safe_manually_drop::{DropManually, SafeManuallyDrop};
302///
303///     struct DeferGuardFields<T, F : FnOnce(T)> {
304///         value: T,
305///         on_drop: F,
306///     }
307///
308///     pub
309///     struct DeferGuard<T, F : FnOnce(T)>(
310///      // rather than `Option<DeferGuardFields<T, F>>`,
311///      // or `ManuallyDrop<DeferGuardFields<T, F>>`, use:
312///         SafeManuallyDrop<DeferGuardFields<T, F>, Self>,
313///     );
314///
315///     impl<T, F : FnOnce(T)>
316///         DropManually<DeferGuardFields<T, F>>
317///     for
318///         DeferGuard<T, F>
319///     {
320///         fn drop_manually(
321///             DeferGuardFields { value, on_drop }: DeferGuardFields<T, F>,
322///         )
323///         {
324///             on_drop(value);
325///         }
326///     }
327///
328///     impl<T, F : FnOnce(T)> ::core::ops::Deref for DeferGuard<T, F> {
329///         type Target = T;
330///
331///         fn deref(&self) -> &T {
332///             &self.0.value
333///         }
334///     }
335///     // And `DerefMut`
336///     ```
337///
338/// ## Explanation
339///
340/// It manages to be non-`unsafe`, w.r.t. [`ManuallyDrop<FieldTy>`], by virtue of having a
341/// significantly more restricted use case: that of being used as a `struct`[^or_enum]'s field,
342/// and merely **exposing _owned_ access to the `FieldTy` on _drop_**.
343///
344/// [^or_enum]: (or `enum`, but for the remainder of the explanation, I will stick to talking of
345/// `struct`s exclusively, since it's simpler.)
346///
347/// Such owned access, and _drop_ logic, is exposed and defined in the companion
348/// [`DropManually<FieldTy>`] trait.
349///
350/// In such an `impl`, you shall only have access to that `FieldTy`:
351///
352///   - no access to sibling field types,
353///
354///     (this can be trivially worked around by bundling all the necessary fields together inside
355///     the [`SafeManuallyDrop<_>`]; _c.f._ the example above with the `DeferGuardFields` helper
356///     definition;)
357///
358///   - nor to the encompassing `struct` altogether.
359///
360/// The latter is kind of problematic, since the desired drop glue logic is probably strongly tied
361/// to such encompassing `struct`.
362///
363/// Hence that second generic type parameter on [`SafeManuallyDrop<FieldTy, ContainingType>`].
364///
365/// As its name indicates, it is expected to be the containing/encompassing `struct`:
366///
367/// ```rust
368/// use ::safe_manually_drop::SafeManuallyDrop;
369///
370/// struct Example {
371///     //       ^
372///     //       +-----------------------+
373///     //                               |
374///     string: SafeManuallyDrop<String, Self>,
375/// }
376/// #
377/// # impl ::safe_manually_drop::DropManually<String> for Example {
378/// #     fn drop_manually(_: String) {}
379/// # }
380/// ```
381///
382/// That way, this containing `struct` can be used as the `Self`/`impl`ementor type for the drop
383/// glue:
384///
385/// ```rust
386/// use ::safe_manually_drop::DropManually;
387///
388/// # struct Example {
389/// #    //       ^
390/// #    //       +-----------------------+
391/// #    //                               |
392/// #    string: ::safe_manually_drop::SafeManuallyDrop<String, Self>,
393/// # }
394/// #
395/// impl DropManually<String> for Example {
396///     fn drop_manually(s: String) {
397///         // owned access to `s` here!
398///         # let random = || true; // determined by faire dice roll.
399///         if random() {
400///             drop(s);
401///         } else {
402///             ::core::mem::forget(s);
403///         }
404///     }
405/// }
406/// ```
407///
408/// ## Going further
409///
410/// ### `repr()` guarantee.
411///
412/// This type is guaranteed to be a mere `#[repr(transparent)]` wrapper around its `FieldTy`.
413///
414/// ### The second type parameter is an orphan rules "named `impl` identifier"
415///
416/// This section may be a bit of a "brain fuck", and it is safe to skip.
417///
418/// <details class="custom"><summary><span class="summary-box"><span>Click to show</span></span></summary>
419///
420/// In practice, neither the API of this crate, nor that of any non-macro API for that matter, can
421/// ever hope to check, impose, nor control that the `ContainingType` used for a
422/// [`SafeManuallyDrop<FieldTy, ContainingType>`] do match that of the containing `struct`.
423///
424/// And, as a matter of fact, there may even be legitimate cases where you may do so on purpose.
425///
426/// Indeed, this extra type parameter is, at the end of the day, a mere `impl DropManually`
427/// "identifier" / "named impl" / type-level discriminant for it to be possible for anybody to write
428/// such impls for arbitrary `FieldTy` types, even when the `FieldTy` is a fully
429/// unconstrained/blanket `<T>/<F>` generic type, and/or when it stems from an upstream crate,
430/// or even when wanting to repeat `SafeManuallyDrop<FieldTy, …>` multiple types within the same
431/// `struct`, _&&without running afoul the orphan rules**_.
432///
433/// In such a case, you may want distinct drop logic for one field _vs._ another.
434///
435/// If so, then consider/notice how what that `ContainingType` _actually_ is, is rather a
436/// `DropImplIdentifier/DropImplDiscriminant/DropStrategy` mere `PhantomData`-like type parameter.
437///
438/// Which means that in this context, you will likely want to involve dedicated phantom types for
439/// the `ContainingType, FieldIdentifier` pair:
440///
441/// ```rust
442/// use ::safe_manually_drop::prelude::*;
443///
444/// use some_lib::Transaction;
445/// // where `some_lib` has the following API, say:
446/// mod some_lib {
447///     pub struct Transaction(());
448///
449///     // Owned `self` receivers for stronger type-level guarantees.
450///     impl Transaction {
451///         pub fn commit(self) {}
452///         pub fn roll_back(self) {}
453///     }
454/// }
455///
456/// enum MyType {
457///     AutoCommitOnDrop {
458///         txn: SafeManuallyDrop<Transaction, CommitOnDropStrategy>,
459///     },
460///
461///     AutoRollBackOnDrop {
462///         txn: SafeManuallyDrop<Transaction, RollBackOnDropStrategy>,
463///     },
464/// }
465///
466/// enum CommitOnDropStrategy {}
467/// impl DropManually<Transaction> for CommitOnDropStrategy {
468///     fn drop_manually(txn: Transaction) {
469///         txn.commit();
470///     }
471/// }
472///
473/// enum RollBackOnDropStrategy {}
474/// impl DropManually<Transaction> for RollBackOnDropStrategy {
475///     fn drop_manually(txn: Transaction) {
476///         txn.roll_back();
477///     }
478/// }
479/// ```
480///
481/// </details>
482///
483/// ### A silly, but interesting example: DIY-ing our own `ManuallyDrop<T>`
484///
485/// ```rust
486/// use ::safe_manually_drop::prelude::*;
487///
488/// pub
489/// enum ForgetOnDropStrategy {}
490///
491/// impl<T> DropManually<T> for ForgetOnDropStrategy {
492///     fn drop_manually(value: T) {
493///         ::core::mem::forget(value);
494///     }
495/// }
496///
497/// pub
498/// type ManuallyDrop<T> = SafeManuallyDrop<T, ForgetOnDropStrategy>;
499/// ```
500///
501///   - Note: do not do this in actual code, since calling `forget()` temporarily asserts validity
502///     of the `value`, which means the resulting type is completey unable to offer
503///     [`ManuallyDrop::take()`]-like APIs of any sort, and whatnot.
504#[repr(transparent)]
505pub
506struct SafeManuallyDrop<FieldTy, ContainingType = diagnostics::MissingSecondTypeParam>
507where
508    ContainingType : DropManually<FieldTy>,
509{
510    _phantom: PD<fn() -> ContainingType>,
511    field: ManuallyDrop<FieldTy>,
512}
513
514/// The impl tying everything together.
515///
516/// The main reason why an <code>impl [DropManually]</code> Just Works™, thanks to the following
517/// blanket `impl`:
518///
519/// <code>impl\<FieldTy\> Drop for SafeManuallyDrop\<FieldTy, …\> where … : DropManually\<FieldTy\> { </code>
520impl<FieldTy, ContainingType : DropManually<FieldTy>>
521    Drop
522for
523    SafeManuallyDrop<FieldTy, ContainingType>
524{
525    #[inline]
526    fn drop(&mut self) {
527        let owned: FieldTy = unsafe {
528            MD::take(&mut self.field)
529        };
530        ContainingType::drop_manually(owned)
531    }
532}
533
534impl<FieldTy, ContainingType : DropManually<FieldTy>> SafeManuallyDrop<FieldTy, ContainingType> {
535    /// Main, `const`-friendly, way to construct a [`SafeManuallyDrop<FieldTy, _>`] instance.
536    ///
537    /// Alternatively, there is a <code>[From]\<FieldTy> impl</code> as well.
538    ///
539    /// Tangentially, there shall also be <code>[Deref] \& [DerefMut] impls</code> with
540    /// `Target = FieldTy`.
541    ///
542    /// [Deref]: `::core::ops::Deref`
543    /// [DerefMut]: `::core::ops::DerefMut`
544    #[inline]
545    pub
546    const
547    fn new(value: FieldTy) -> Self {
548        Self {
549            _phantom: PD,
550            field: MD::new(value),
551        }
552    }
553
554    /// The inverse / reverse operation of the [`Self::new()`] constructor: _deconstructs_ a
555    /// [`SafeManuallyDrop<FieldTy, …>`][`SafeManuallyDrop`] back into a bare `FieldTy` type, which,
556    /// by virtue of this operation, shall go back to its default drop glue (rather than the
557    /// _overridden_ one of <code>impl [DropManually]\<FieldTy\> for … {</code>).
558    ///
559    /// Such a process is typically called _defusing_ the (extra or special) drop glue.
560    #[inline]
561    #[allow(nonstandard_style)]
562    pub
563    const
564    fn into_inner_defusing_impl_Drop(self) -> FieldTy {
565        union ConstUncheckedTransmuter<Src, Dst> {
566            src: MD<Src>,
567            dst: MD<Dst>,
568        }
569        unsafe {
570            // Safety: `repr(transparent)`, and no extra validity nor safety invariants at play.
571            MD::into_inner(
572                ConstUncheckedTransmuter::<
573                    SafeManuallyDrop<FieldTy, ContainingType>,
574                    FieldTy,
575                >
576                {
577                    src: MD::new(self),
578                }
579                .dst
580            )
581        }
582    }
583}
584
585impl<FieldTy, ContainingType : DropManually<FieldTy>>
586    ::core::ops::Deref
587for
588    SafeManuallyDrop<FieldTy, ContainingType>
589{
590    type Target = FieldTy;
591
592    #[inline]
593    fn deref(&self) -> &FieldTy {
594        &self.field
595    }
596}
597
598impl<FieldTy, ContainingType : DropManually<FieldTy>>
599    ::core::ops::DerefMut
600for
601    SafeManuallyDrop<FieldTy, ContainingType>
602{
603    #[inline]
604    fn deref_mut(&mut self) -> &mut FieldTy {
605        &mut self.field
606    }
607}
608
609impl<FieldTy, ContainingType : DropManually<FieldTy>>
610    From<FieldTy>
611for
612    SafeManuallyDrop<FieldTy, ContainingType>
613{
614    fn from(field: FieldTy) -> Self {
615        Self::new(field)
616    }
617}
618
619impl<FieldTy : Default, ContainingType : DropManually<FieldTy>>
620    Default
621for
622    SafeManuallyDrop<FieldTy, ContainingType>
623{
624    #[inline]
625    fn default() -> Self {
626        FieldTy::default().into()
627    }
628}
629
630mod deref_impls {
631    #![deny(unconditional_recursion)]
632
633    use ::core::{
634        cmp,
635        fmt,
636        hash,
637    };
638    use super::*;
639
640    JustDerefTM!(
641        impl[..: fmt::Debug] fmt::Debug ,for SafeManuallyDrop<..> {
642            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
643        }
644
645        impl[..: hash::Hash] hash::Hash ,for SafeManuallyDrop<..> {
646            fn hash[H: hash::Hasher](&self, state: &mut H);
647        }
648
649        impl[..: PartialEq] PartialEq ,for SafeManuallyDrop<..> {
650            fn eq(&self, other: &Self) -> bool;
651        }
652
653        impl[..: Eq] Eq ,for SafeManuallyDrop<..> {}
654
655        impl[..: PartialOrd] PartialOrd ,for SafeManuallyDrop<..> {
656            fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering>;
657        }
658
659        impl[..: Ord] Ord ,for SafeManuallyDrop<..> {
660            fn cmp(&self, other: &Self) -> cmp::Ordering;
661        }
662    );
663    // where:
664    macro_rules! JustDerefTM {(
665        $(
666            impl[..: $($Bounds:tt)*] $Trait:path ,for SafeManuallyDrop<..> {
667                $(
668                    fn $fname:ident $([$($generics:tt)*])? (
669                        &$self:ident $(,
670                        $rest:ident: $Rest:ty)* $(,)?
671                    ) $(-> $Ret:ty)?;
672                )*
673            }
674        )*
675    ) => (
676        $(
677            impl<FieldTy: $($Bounds)*, ContainingType : DropManually<FieldTy>>
678                $Trait
679            for
680                SafeManuallyDrop<FieldTy, ContainingType>
681            {
682                $(
683                    #[inline]
684                    fn $fname $(<$($generics)*>)? (
685                        &$self $(,
686                        $rest: $Rest )*
687                    ) $(-> $Ret)?
688                    {
689                        FieldTy::$fname($self $(, $rest)*)
690                    }
691                )*
692            }
693        )*
694    )} use JustDerefTM;
695}
696
697#[cfg(feature = "better-docs")]
698/// Deliberately not implemented
699impl<FieldTy, ContainingType : DropManually<FieldTy>>
700    !Clone
701for
702    SafeManuallyDrop<FieldTy, ContainingType>
703{}
704
705#[cfg(not(feature = "better-docs"))]
706#[doc(hidden)]
707#[allow(warnings, clippy::all)]
708impl<FieldTy, ContainingType : DropManually<FieldTy>>
709    /* !*/Clone // deliberately not implemented
710for
711    SafeManuallyDrop<FieldTy, ContainingType>
712where
713    for<'never> dyn Drop : Clone,
714{
715    fn clone(&self) -> Self {
716        const { unreachable!() }
717    }
718}
719
720/// Some helper for a nicer diagnostic suggestion/nudge in case of a forgotten second type
721/// parameter.
722mod diagnostics {
723    use super::*;
724
725    pub enum MissingSecondTypeParam {}
726
727    impl<FieldTy> DropManually<FieldTy> for MissingSecondTypeParam
728    where
729        for<'never_true> MissingSecondTypeParam : ExplicitlyProvided,
730    {
731        fn drop_manually(_: FieldTy) {
732            unreachable!()
733        }
734    }
735
736    #[diagnostic::on_unimplemented(
737        message = "\
738            missing second type parameter for `SafeManuallyDrop<FieldTy, …>`. \
739            Please use the containing `struct/enum` for it, such as: `Self`.\
740        ",
741        label = "help: use `SafeManuallyDrop<FieldTy, Self>` instead.",
742    )]
743    pub trait ExplicitlyProvided {}
744}
745
746#[doc = include_str!("compile_fail_tests.md")]
747mod _compile_fail_tests {}