1#![no_std]
2#![doc = include_str!("../README.md")]
3#![cfg_attr(feature = "nightly", feature(dispatch_from_dyn))]
4#![cfg_attr(feature = "nightly", feature(unsize))]
5#![cfg_attr(feature = "nightly", feature(arbitrary_self_types))]
6#![cfg_attr(feature = "nightly", feature(dropck_eyepatch))]
7
8#[cfg(feature = "std")]
9extern crate alloc;
10
11#[cfg(feature = "std")]
12use alloc::boxed::Box;
13use core::cell::{Cell, UnsafeCell};
14use core::convert::Infallible;
15use core::marker::{PhantomData, PhantomPinned};
16use core::mem::{transmute_copy, ManuallyDrop, MaybeUninit};
17use core::ops::{Deref, DerefMut};
18use core::pin::Pin;
19use core::ptr;
20use core::ptr::{drop_in_place, null_mut, NonNull};
21
22#[cfg(feature = "atomic")]
24pub mod atomic;
25
26pub use pin::*;
28pub mod pin;
30
31pub use option::OptionMarker;
35mod option;
36mod refcell;
37
38pub mod generic;
39
40#[doc(hidden)]
42pub unsafe trait Preprocess {
43 type Output;
44 fn preprocess(&self) -> Self::Output;
45}
46
47#[doc(hidden)]
52#[repr(transparent)]
53pub struct Owned<T>(ManuallyDrop<T>);
54unsafe impl<T> Preprocess for ManuallyDrop<T> {
55 type Output = Owned<T>;
56
57 fn preprocess(&self) -> Self::Output {
58 unsafe { transmute_copy(self) }
59 }
60}
61
62#[doc(hidden)]
74#[repr(transparent)]
75pub struct Helper<T>(T);
76impl<T: Deref> Deref for Helper<T> {
77 type Target = T::Target;
78
79 fn deref(&self) -> &Self::Target {
80 self.0.deref()
81 }
82}
83unsafe impl<'a, T> Preprocess for &&ManuallyDrop<&'a T> {
84 type Output = Helper<&'a T>;
85
86 fn preprocess(&self) -> Self::Output {
87 unsafe { transmute_copy(**self) }
88 }
89}
90
91unsafe impl<'a, T> Preprocess for &&ManuallyDrop<&'a mut T> {
92 type Output = Helper<&'a mut T>;
93
94 fn preprocess(&self) -> Self::Output {
95 unsafe { transmute_copy(**self) }
96 }
97}
98
99pub unsafe trait CustomWrapper {
101 type Output;
104}
105unsafe impl<T: CustomWrapper> Preprocess for &&&ManuallyDrop<T> {
106 type Output = T::Output;
107
108 fn preprocess(&self) -> Self::Output {
109 unsafe { transmute_copy(***self) }
110 }
111}
112unsafe impl<'a, T> Preprocess for &&&&'a ManuallyDrop<T>
113where
114 &'a T: CustomWrapper,
115{
116 type Output = <&'a T as CustomWrapper>::Output;
117
118 fn preprocess(&self) -> Self::Output {
119 unsafe { transmute_copy(****self) }
120 }
121}
122unsafe impl<'a, 'b, T> Preprocess for &&&&'a &'b ManuallyDrop<T>
123where
124 &'a &'b T: CustomWrapper,
125{
126 type Output = <&'a &'b T as CustomWrapper>::Output;
127
128 fn preprocess(&self) -> Self::Output {
129 unsafe { transmute_copy(*****self) }
130 }
131}
132
133pub unsafe trait Projectable {
189 type Target;
191 type Marker;
194
195 fn get_raw(&self) -> (*mut Self::Target, Self::Marker);
197}
198
199pub trait ProjectableMarker<T: ?Sized> {
204 type Output;
206 unsafe fn from_raw(&self, raw: *mut T) -> Self::Output;
208
209 #[doc(hidden)]
210 unsafe fn from_raw_option(&self, raw: Option<*mut T>) -> Self::Output {
211 self.from_raw(raw.unwrap())
212 }
213}
214
215pub unsafe trait DerefProjectable {
217 type Target: ?Sized;
218 type Marker;
219
220 fn deref_raw(&self) -> (*mut Self::Target, Self::Marker);
221 #[doc(hidden)]
222 fn maybe_deref_raw(&self) -> (Option<*mut Self::Target>, Self::Marker) {
223 let (a, b) = self.deref_raw();
224 (Some(a), b)
225 }
226}
227
228pub struct Marker<T>(PhantomData<T>);
233impl<T> Marker<T> {
234 pub fn new() -> Self {
235 Self(PhantomData)
236 }
237
238 pub fn check(&self) {}
239}
240impl<T> Clone for Marker<T> {
241 fn clone(&self) -> Self {
242 Marker::new()
243 }
244}
245
246#[doc(hidden)]
247pub trait AmbiguityCheck {
248 fn check(&self) -> usize {
249 unreachable!()
250 }
251}
252impl<T: ?Sized> AmbiguityCheck for T {}
253
254#[repr(transparent)]
264pub struct MaybeDerefProjectable<T>(ManuallyDrop<T>);
265impl<T> MaybeDerefProjectable<T> {
266 pub fn new(from: T) -> Self {
267 Self(ManuallyDrop::new(from))
268 }
269}
270
271unsafe impl<T: Projectable> DerefProjectable for MaybeDerefProjectable<T> {
272 type Target = T::Target;
273 type Marker = T::Marker;
274
275 fn deref_raw(&self) -> (*mut Self::Target, Self::Marker) {
276 self.0.get_raw()
277 }
278}
279unsafe impl<'a, T, Target, Marker> DerefProjectable for &'a MaybeDerefProjectable<T>
280where
281 &'a T: Projectable<Target = Target, Marker = Marker>,
282{
283 type Target = Target;
284 type Marker = Marker;
285
286 fn deref_raw(&self) -> (*mut Self::Target, Self::Marker) {
287 (&*self.0).get_raw()
288 }
289}
290unsafe impl<'a, 'b, T, Target, Marker> DerefProjectable for &'a &'b MaybeDerefProjectable<T>
291where
292 &'a &'b T: Projectable<Target = Target, Marker = Marker>,
293{
294 type Target = Target;
295 type Marker = Marker;
296
297 fn deref_raw(&self) -> (*mut Self::Target, Self::Marker) {
298 unsafe { &*(self as *const _ as *const &&T) }.get_raw()
299 }
300}
301unsafe impl<'a, 'b, 'c, T, Target, Marker> DerefProjectable for &'a &'b &'c MaybeDerefProjectable<T>
302where
303 &'a &'b &'c T: Projectable<Target = Target, Marker = Marker>,
304{
305 type Target = Target;
306 type Marker = Marker;
307
308 fn deref_raw(&self) -> (*mut Self::Target, Self::Marker) {
309 unsafe { &*(self as *const _ as *const &&&T) }.get_raw()
310 }
311}
312
313unsafe impl<T: DerefProjectable> DerefProjectable for &&&&MaybeDerefProjectable<T> {
314 type Target = T::Target;
315 type Marker = T::Marker;
316
317 fn deref_raw(&self) -> (*mut Self::Target, Self::Marker) {
318 self.0.deref_raw()
319 }
320}
321
322unsafe impl<'a, T> DerefProjectable for &&&&&'a MaybeDerefProjectable<T>
323where
324 &'a T: DerefProjectable,
325{
326 type Target = <&'a T as DerefProjectable>::Target;
327 type Marker = <&'a T as DerefProjectable>::Marker;
328
329 fn deref_raw(&self) -> (*mut Self::Target, Self::Marker) {
330 (&*self.0).deref_raw()
331 }
332}
333
334unsafe impl<T> Projectable for Owned<T> {
336 type Target = T;
337 type Marker = Marker<()>;
338
339 fn get_raw(&self) -> (*mut Self::Target, Self::Marker) {
340 (self as *const Self as *mut Self as *mut T, Marker::new())
341 }
342}
343impl<T> ProjectableMarker<T> for Marker<()> {
344 type Output = T;
345
346 unsafe fn from_raw(&self, raw: *mut T) -> Self::Output {
347 ptr::read_unaligned(raw as *const T as *const _)
348 }
349}
350
351unsafe impl<ToCheck, NotPacked> SupportsPacked
352 for &(*mut ToCheck, &Marker<()>, PhantomData<NotPacked>)
353{
354 type Result = NotPacked;
355}
356
357pub trait DerefOwned: DerefMut {
359 unsafe fn drop_leftovers(_leftovers: &mut ManuallyDrop<Self>) {}
364 fn deref_owned(self) -> Self::Target
375 where
376 Self: Sized,
377 Self::Target: Sized,
378 {
379 let mut x = DropLeftovers::new(self);
380 unsafe { ManuallyDrop::new(x.deref_as_owning()).0.read() }
381 }
382}
383
384impl<T> DerefOwned for Pin<T>
385where
386 T::Target: Unpin,
387 T: DerefOwned,
388{
389 unsafe fn drop_leftovers(_leftovers: &mut ManuallyDrop<Self>) {
390 T::drop_leftovers(unsafe { &mut *(_leftovers as *mut _ as *mut ManuallyDrop<T>) })
391 }
392}
393
394#[cfg(feature = "std")]
395impl<T: ?Sized> DerefOwned for Box<T> {
396 unsafe fn drop_leftovers(leftovers: &mut ManuallyDrop<Self>) {
397 ManuallyDrop::drop(&mut *(leftovers as *mut _ as *mut ManuallyDrop<Box<ManuallyDrop<T>>>))
398 }
399}
400
401#[doc(hidden)]
402pub struct OwnedDropMarker<T: DerefOwned>(*const ManuallyDrop<T>);
403impl<'a, T: DerefOwned> Drop for OwnedDropMarker<T> {
407 fn drop(&mut self) {
408 let mut temp = unsafe { ptr::read(self.0) };
409 unsafe { T::drop_leftovers(&mut temp) }
410 }
411}
412
413unsafe impl<T: DerefOwned> DerefProjectable for Owned<T> {
414 type Target = T::Target;
415 type Marker = OwnedDropMarker<T>;
416
417 fn deref_raw(&self) -> (*mut Self::Target, Self::Marker) {
418 let ptr = unsafe { &**self.0 } as *const _ as _;
419 (ptr, OwnedDropMarker(&self.0))
420 }
421}
422
423impl<X: DerefOwned, T> ProjectableMarker<T> for OwnedDropMarker<X> {
424 type Output = T;
425
426 unsafe fn from_raw(&self, raw: *mut T) -> Self::Output {
427 ptr::read(raw as *const T)
428 }
429}
430
431unsafe impl<'a, T> Projectable for Helper<&'a mut T> {
433 type Target = T;
434 type Marker = Marker<&'a mut ()>;
435
436 fn get_raw(&self) -> (*mut Self::Target, Self::Marker) {
437 (
438 unsafe { ptr::read(self as *const _ as *const *mut Self::Target) },
439 Marker::new(),
440 )
441 }
442}
443impl<'a, T: 'a> ProjectableMarker<T> for Marker<&'a mut ()> {
444 type Output = &'a mut T;
445
446 unsafe fn from_raw(&self, raw: *mut T) -> Self::Output {
447 &mut *raw
448 }
449}
450unsafe impl<'a, T: DerefMut> DerefProjectable for &Helper<&'a mut T> {
451 type Target = T::Target;
452 type Marker = Marker<&'a mut ()>;
453
454 fn deref_raw(&self) -> (*mut Self::Target, Self::Marker) {
455 (
456 unsafe { transmute_copy::<_, &mut T>(*self) }.deref_mut(),
457 Marker::new(),
458 )
459 }
460}
461unsafe impl<'a, T: DerefMut> DerefProjectable for Helper<&'a mut Pin<T>> {
462 type Target = T::Target;
463 type Marker = PinMarker<Marker<&'a mut ()>>;
464
465 fn deref_raw(&self) -> (*mut Self::Target, Self::Marker) {
466 (
467 unsafe {
468 transmute_copy::<_, Self>(self)
469 .0
470 .as_mut()
471 .get_unchecked_mut()
472 },
473 PinMarker(Marker::new()),
474 )
475 }
476}
477
478unsafe impl<'a, T> Projectable for Helper<&'a T> {
488 type Target = T;
489 type Marker = Marker<&'a ()>;
490
491 fn get_raw(&self) -> (*mut Self::Target, Self::Marker) {
492 (self.0 as *const _ as _, Marker::new())
493 }
494}
495impl<'a, T: 'a> ProjectableMarker<T> for Marker<&'a ()> {
496 type Output = &'a T;
497
498 unsafe fn from_raw(&self, raw: *mut T) -> Self::Output {
499 &*raw
500 }
501}
502unsafe impl<'a, T: Deref> DerefProjectable for Helper<&'a T> {
503 type Target = T::Target;
504 type Marker = Marker<&'a ()>;
505
506 fn deref_raw(&self) -> (*mut Self::Target, Self::Marker) {
507 (self.0.deref() as *const T::Target as _, Marker::new())
508 }
509}
510unsafe impl<'a, T: Deref> DerefProjectable for &Helper<&'a Pin<T>> {
511 type Target = T::Target;
512 type Marker = PinMarker<Marker<&'a ()>>;
513
514 fn deref_raw(&self) -> (*mut Self::Target, Self::Marker) {
515 (
516 self.0.as_ref().get_ref() as *const _ as _,
517 PinMarker(Marker::new()),
518 )
519 }
520}
521unsafe impl<'a, T> Projectable for &Helper<&'a Cell<T>> {
530 type Target = T;
531 type Marker = Marker<&'a Cell<()>>;
532
533 fn get_raw(&self) -> (*mut Self::Target, Self::Marker) {
534 (unsafe { transmute_copy(*self) }, Marker::new())
535 }
536}
537impl<'a, T: 'a> ProjectableMarker<T> for Marker<&'a Cell<()>> {
538 type Output = &'a Cell<T>;
539
540 unsafe fn from_raw(&self, raw: *mut T) -> Self::Output {
541 &*(raw as *mut Cell<T>)
542 }
543}
544
545unsafe impl<'a, T> Projectable for &Helper<&'a mut Cell<T>> {
546 type Target = T;
547 type Marker = Marker<&'a mut ()>;
548
549 fn get_raw(&self) -> (*mut Self::Target, Self::Marker) {
550 (unsafe { transmute_copy(*self) }, Marker::new())
551 }
552}
553unsafe impl<'a, T> Projectable for &Helper<&'a mut MaybeUninit<T>> {
555 type Target = T;
556 type Marker = Marker<&'a mut MaybeUninit<()>>;
557
558 fn get_raw(&self) -> (*mut Self::Target, Self::Marker) {
559 (
560 unsafe { ptr::read(*self as *const _ as *const *mut Self::Target) },
561 Marker::new(),
562 )
563 }
564}
565impl<'a, T: 'a> ProjectableMarker<T> for Marker<&'a mut MaybeUninit<()>> {
566 type Output = &'a mut MaybeUninit<T>;
567
568 unsafe fn from_raw(&self, raw: *mut T) -> Self::Output {
569 &mut *(raw as *mut MaybeUninit<T>)
570 }
571}
572unsafe impl<T> CustomWrapper for *mut T {
574 type Output = Self;
575}
576unsafe impl<T> Projectable for *mut T {
577 type Target = T;
578 type Marker = Marker<*mut ()>;
579
580 fn get_raw(&self) -> (*mut Self::Target, Self::Marker) {
581 (*self, Marker::new())
582 }
583}
584impl<T> ProjectableMarker<T> for Marker<*mut ()> {
585 type Output = *mut T;
586
587 unsafe fn from_raw(&self, raw: *mut T) -> Self::Output {
588 raw
589 }
590}
591
592unsafe impl<T> CustomWrapper for *const T {
594 type Output = Self;
595}
596unsafe impl<T> Projectable for *const T {
597 type Target = T;
598 type Marker = Marker<*const ()>;
599
600 fn get_raw(&self) -> (*mut Self::Target, Self::Marker) {
601 (*self as _, Marker::new())
602 }
603}
604impl<T> ProjectableMarker<T> for Marker<*const ()> {
605 type Output = *const T;
606
607 unsafe fn from_raw(&self, raw: *mut T) -> Self::Output {
608 raw as _
609 }
610}
611
612unsafe impl<T> CustomWrapper for NonNull<T> {
614 type Output = Self;
615}
616unsafe impl<T> Projectable for NonNull<T> {
617 type Target = T;
618 type Marker = Marker<NonNull<()>>;
619
620 fn get_raw(&self) -> (*mut Self::Target, Self::Marker) {
621 (self.as_ptr(), Marker::new())
622 }
623}
624impl<T> ProjectableMarker<T> for Marker<NonNull<()>> {
625 type Output = NonNull<T>;
626
627 unsafe fn from_raw(&self, raw: *mut T) -> Self::Output {
628 NonNull::new_unchecked(raw)
629 }
630}
631
632pub trait FinalizeProjection {
636 type Output;
637 unsafe fn finalize(&self) -> Self::Output;
638}
639#[doc(hidden)]
641pub trait Finalizer {
642 type Output;
643 unsafe fn call_finalize(&self) -> Self::Output;
644}
645impl<T> Finalizer for ManuallyDrop<T> {
646 type Output = T;
647
648 unsafe fn call_finalize(&self) -> Self::Output {
649 transmute_copy(self)
650 }
651}
652impl<T: FinalizeProjection> Finalizer for &ManuallyDrop<T> {
653 type Output = T::Output;
654
655 unsafe fn call_finalize(&self) -> Self::Output {
656 self.finalize()
657 }
658}
659impl<'a, T> Finalizer for &&'a ManuallyDrop<T>
660where
661 &'a T: FinalizeProjection,
662{
663 type Output = <&'a T as FinalizeProjection>::Output;
664
665 unsafe fn call_finalize(&self) -> Self::Output {
666 transmute_copy::<_, &T>(*self).finalize()
667 }
668}
669impl<'a, 'b, T> Finalizer for &&'a &'b ManuallyDrop<T>
670where
671 &'a &'b T: FinalizeProjection,
672{
673 type Output = <&'a &'b T as FinalizeProjection>::Output;
674
675 unsafe fn call_finalize(&self) -> Self::Output {
676 transmute_copy::<_, &&T>(*self).finalize()
677 }
678}
679impl<'a, 'b, 'c, T> Finalizer for &&'a &'b &'c ManuallyDrop<T>
680where
681 &'a &'b &'c T: FinalizeProjection,
682{
683 type Output = <&'a &'b &'c T as FinalizeProjection>::Output;
684
685 unsafe fn call_finalize(&self) -> Self::Output {
686 transmute_copy::<_, &&&T>(*self).finalize()
687 }
688}
689#[doc(hidden)]
692pub trait CheckNoDeref {
693 type Result;
694 fn check_deref(&self) -> Self::Result;
695}
696
697impl<T> CheckNoDeref for *mut T {
698 type Result = *mut T;
699 fn check_deref(&self) -> Self::Result {
700 *self
701 }
702}
703
704impl<T: Deref> CheckNoDeref for &*mut T {
705 type Result = *mut Infallible;
706
707 fn check_deref(&self) -> *mut Infallible {
708 panic!("can't go through deref here, use more explicit syntax")
709 }
710}
711
712pub unsafe trait SupportsPacked {
716 type Result;
717 fn select(&self) -> *mut Self::Result {
718 NonNull::dangling().as_ptr()
719 }
720}
721
722unsafe impl<ToCheck, NotPacked, M> SupportsPacked for (*mut ToCheck, M, PhantomData<NotPacked>) {
724 type Result = ToCheck;
725}
726unsafe impl<ToCheck, NotPacked> SupportsPacked
727 for &(*mut ToCheck, &Marker<*mut ()>, PhantomData<NotPacked>)
728{
729 type Result = NotPacked;
730}
731unsafe impl<ToCheck, NotPacked> SupportsPacked
732 for &(*mut ToCheck, &Marker<*const ()>, PhantomData<NotPacked>)
733{
734 type Result = NotPacked;
735}
736unsafe impl<ToCheck, NotPacked> SupportsPacked
737 for &(*mut ToCheck, &Marker<NonNull<()>>, PhantomData<NotPacked>)
738{
739 type Result = NotPacked;
740}
741
742#[macro_export]
897macro_rules! project {
898 (let $struct:ident { $($fields:tt)+ } = $val: expr) => {
900 let var = core::mem::ManuallyDrop::new($val);
901 let var = {
902 use $crate::Preprocess;
903 core::mem::ManuallyDrop::new((&&&&&var).preprocess())
904 };
905
906 let (ptr,marker) = {
907 use $crate::Projectable;
908 (&&&&&&& *var).get_raw()
909 };
910 $crate::project_struct_fields! { [ptr marker $struct] [] $($fields)+ }
916 drop(marker);
917 };
918 (let $struct:ident ( $($fields:tt)+ ) = $val: expr) => {
919 let var = core::mem::ManuallyDrop::new($val);
920 let var = {
921 use $crate::Preprocess;
922 core::mem::ManuallyDrop::new((&&&&&var).preprocess())
923 };
924 let (ptr,marker) = {
925 use $crate::Projectable;
926 (&&&&&&& *var).get_raw()
927 };
928 $crate::project_tuple_fields! { [ptr marker $struct] [] [] $($fields)+ }
935 drop(marker);
936 };
937 (let * $($tail:tt)+) => {
938 $crate::project_deref!{ [] $($tail)+ }
939 };
940 (let _ = $val:expr) => {
943 drop($val);
944 };
945 (let $pat:pat = $val:expr) => {
946 let $pat = $val;
947 };
948 ($var:ident ) => { $var };
949 ( $var:ident -> $($tail:tt)+) => { $crate::project! { ($var) -> $($tail)+ } };
950 (( $var:expr ) -> $method:tt ($($args:tt)*) $($tail:tt)*) => {
951 };
953 (( $var:expr ) -> $field:tt $($tail:tt)*) => {
954 {
955 $crate::project_deref!( ? [ var ] = $var);
956 let var = core::mem::ManuallyDrop::new(var);
958 let var = {
960 use $crate::Preprocess;
961 core::mem::ManuallyDrop::new((&&&&&var).preprocess())
962 };
963
964 let (ptr,marker) = {
965 use $crate::Projectable;
966 (&&&&&&& *var).get_raw()
967 };
968 let ptr = {
969 use $crate::CheckNoDeref;
972 (&&ptr).check_deref()
974 };
975
976 $crate::project_field_inner! { [ptr marker] { $field } : temp_name }
977 $crate::project!( temp_name $($tail)*)
978 }
979 };
980
981}
982
983#[doc(hidden)]
984#[macro_export]
985macro_rules! project_deref {
986 ( ? [$($parsed:tt)*] = $($tail:tt)* ) => {
987 let var = core::mem::ManuallyDrop::new($($tail)*);
988 let var = {
989 use $crate::Preprocess;
990 (&&&&&var).preprocess()
991 };
992 let (ptr,marker) = {
993 use $crate::DerefProjectable;
994 (&&&&&& $crate::MaybeDerefProjectable::new(var)).deref_raw()
995 };
996 #[allow(unused_mut)]
997 let mut result = unsafe {
998 use $crate::{ProjectableMarker,Finalizer};
999 let tmp = core::mem::ManuallyDrop::new(marker.from_raw(ptr));
1000 (&&&&& tmp).call_finalize()
1001 };
1002 drop(marker);
1003 $crate::project!(let $($parsed)* = result);
1004 };
1005
1006 ( [$($parsed:tt)*] = $($tail:tt)* ) => {
1007 let var = core::mem::ManuallyDrop::new($($tail)*);
1008 let var = {
1009 use $crate::Preprocess;
1010 core::mem::ManuallyDrop::new((&&&&&var).preprocess())
1011 };
1012 let (ptr,marker) = {
1013 use $crate::DerefProjectable;
1014 (&&&&&&& *var).deref_raw()
1015 };
1016 #[allow(unused_mut)]
1017 let mut result = unsafe {
1018 use $crate::{ProjectableMarker,Finalizer};
1019 let tmp = core::mem::ManuallyDrop::new(marker.from_raw(ptr));
1020 (&&&&& tmp).call_finalize()
1021 };
1022 drop(marker);
1023 $crate::project!(let $($parsed)* = result);
1024 };
1025 ([$($parsed:tt)*] $token:tt $($tail:tt)*) => {
1026 $crate::project_deref!{ [$($parsed)* $token] $($tail)* }
1027 };
1028}
1029
1030#[doc(hidden)]
1031#[macro_export]
1032macro_rules! project_tuple_fields {
1033 ([$ptr:ident $marker:ident $struct:ident] [$($idx:tt)*] [$($pattern:tt)*] , $($tail:tt)* ) => {
1034 $crate::project_field_inner! { [$ptr $marker $struct] { $($idx)* } : $($pattern)* }
1035 $crate::project_tuple_fields! { [$ptr $marker $struct] [$($idx)* !] [] $($tail)* }
1036 };
1037 ([$ptr:ident $marker:ident $struct:ident] [$($idx:tt)*] [] ) => {};
1038 ([$ptr:ident $marker:ident $struct:ident] [$($idx:tt)*] [] .. ) => {};
1039
1040 ([$ptr:ident $marker:ident $struct:ident] [$($idx:tt)*] [$($pattern:tt)*] $next:tt $($tail:tt)* ) => {
1041 $crate::project_tuple_fields! { [$ptr $marker $struct] [$($idx)*] [$($pattern)* $next] $($tail)* }
1042 };
1043 ([$ptr:ident $marker:ident $struct:ident] [$($idx:tt)*] [$($pattern:tt)*] ) => {
1044 $crate::project_field_inner! { [$ptr $marker $struct] { $($idx)* } : $($pattern)* }
1045 };
1046}
1047
1048#[doc(hidden)]
1049#[macro_export]
1050macro_rules! project_struct_fields {
1051 ([$ptr:ident $marker:ident $struct:ident] [$name:tt $($pattern:tt)*] , $($tail:tt)* ) => {
1052 $crate::project_field_inner! { [$ptr $marker $struct] { $name } $($pattern)* }
1053 $crate::project_struct_fields! { [$ptr $marker $struct] [] $($tail)* }
1054 };
1055 ([$ptr:ident $marker:ident $struct:ident] [] ) => {};
1056 ([$ptr:ident $marker:ident $struct:ident] [] ..) => {};
1057 ([$ptr:ident $marker:ident $struct:ident] [$($pattern:tt)*] $next:tt $($tail:tt)* ) => {
1058 $crate::project_struct_fields! { [$ptr $marker $struct] [$($pattern)* $next] $($tail)* }
1059 };
1060 ([$ptr:ident $marker:ident $struct:ident] [$name:tt $($pattern:tt)*] ) => {
1061 $crate::project_field_inner! { [$ptr $marker $struct] { $name } $($pattern)* }
1062 };
1063}
1064
1065#[doc(hidden)]
1098#[macro_export]
1099macro_rules! not_packed {
1100 ($name:ident $field:ident) => {
1101 struct $name {
1102 $field: (),
1103 }
1104 };
1105 ($name:ident $($field:tt)* ) => {
1106 struct $name((), (), (), (), (), (), (), (), (), (), ());
1107 };
1108}
1109
1110#[doc(hidden)]
1111#[macro_export]
1112macro_rules! project_field_inner {
1113 ( [$($args:tt)*] { } : $($pattern:tt)* ) => {
1114 $crate::project_field_inner! { [$($args)*] { 0 } : $($pattern)* }
1115 };
1116 ( [$($args:tt)*] { ! } : $($pattern:tt)* ) => {
1117 $crate::project_field_inner! { [$($args)*] { 1 } : $($pattern)* }
1118 };
1119 ( [$($args:tt)*] { !! } : $($pattern:tt)* ) => {
1120 $crate::project_field_inner! { [$($args)*] { 2 } : $($pattern)* }
1121 };
1122 ( [$($args:tt)*] { !!! } : $($pattern:tt)* ) => {
1123 $crate::project_field_inner! { [$($args)*] { 3 } : $($pattern)* }
1124 };
1125 ( [$($args:tt)*] { !!!! } : $($pattern:tt)* ) => {
1126 $crate::project_field_inner! { [$($args)*] { 4 } : $($pattern)* }
1127 };
1128 ( [$($args:tt)*] { !!!!! } : $($pattern:tt)* ) => {
1129 $crate::project_field_inner! { [$($args)*] { 5 } : $($pattern)* }
1130 };
1131 ( [$($args:tt)*] { !!!!!! } : $($pattern:tt)* ) => {
1132 $crate::project_field_inner! { [$($args)*] { 6 } : $($pattern)* }
1133 };
1134 ( [$($args:tt)*] { !!!!!!! } : $($pattern:tt)* ) => {
1135 $crate::project_field_inner! { [$($args)*] { 7 } : $($pattern)* }
1136 };
1137 ( [$($args:tt)*] { !!!!!!!! } : $($pattern:tt)* ) => {
1138 $crate::project_field_inner! { [$($args)*] { 8 } : $($pattern)* }
1139 };
1140 ( [$($args:tt)*] { !!!!!!!!! } : $($pattern:tt)* ) => {
1141 $crate::project_field_inner! { [$($args)*] { 9 } : $($pattern)* }
1142 };
1143 ( [$($args:tt)*] { !!!!!!!!!! } : $($pattern:tt)* ) => {
1144 $crate::project_field_inner! { [$($args)*] { 10 } : $($pattern)* }
1145 };
1146 ( [$ptr:tt $marker:ident $type:ident] { $field:tt } $($pattern:tt)* ) => {
1147 if false {
1148 let $type { $field : _ , .. } = unsafe { &*$ptr };
1149 }
1150 $crate::project_field_inner! { [$ptr $marker] { $field } $($pattern)* }
1151 };
1152 ( [$ptr:tt $marker:ident] { $field:tt } : $($pattern:tt)* ) => {
1153 #[allow(unused_mut)]
1154 let mut tmp = unsafe {
1155 use $crate::{ProjectableMarker,Finalizer,SupportsPacked};
1156 #[forbid(unaligned_references)]
1158 #[allow(dead_code)]
1159 if false{
1160 $crate::not_packed! { Foo $field }
1161 let check_ptr = ( &&($ptr, &$marker, core::marker::PhantomData::<Foo>) ).select();
1162 let _ = &(*check_ptr). $field;
1163 }
1164 fn create_uninit<T>(_ptr: *mut T) -> core::mem::MaybeUninit<T>{ core::mem::MaybeUninit::uninit() }
1165 let mut mu = create_uninit($ptr);
1166 let mu_ptr = mu.as_mut_ptr();
1167 let mu_field_ptr = core::ptr::addr_of_mut!((*mu_ptr). $field );
1168 let offset = (mu_field_ptr as *mut u8).offset_from(mu_ptr as *mut u8);
1169 fn do_offset<T,U>(ptr:*mut T, _field_ptr_type: *mut U, offset: isize) -> *mut U{
1170 (ptr as *mut u8).wrapping_offset(offset) as *mut U
1171 }
1172 let field_ptr = do_offset($ptr, mu_field_ptr, offset);
1173 let tmp = core::mem::ManuallyDrop::new($marker.from_raw(field_ptr));
1174 (&&&&& tmp).call_finalize()
1175 };
1176 $crate::project!(let $($pattern)* = tmp);
1177
1178 };
1179 ( [$ptr:tt $marker:ident] { $field:ident } ) => { $crate::project_field_inner! { [$ptr $marker] { $field } : $field } };
1180}
1181
1182pub struct DropLeftovers<'a, T: DerefOwned>(
1184 DropLeftoversInner<T>,
1186 PhantomData<fn(&'a ()) -> &'a ()>,
1187);
1188struct DropLeftoversInner<T: DerefOwned>(ManuallyDrop<T>);
1189impl<T: DerefOwned> Drop for DropLeftoversInner<T> {
1190 fn drop(&mut self) {
1191 unsafe { T::drop_leftovers(&mut self.0) }
1192 }
1193}
1194
1195impl<'a, T: DerefOwned> DropLeftovers<'a, T> {
1196 pub fn new(val: T) -> Self {
1197 Self(DropLeftoversInner(ManuallyDrop::new(val)), PhantomData)
1198 }
1199
1200 pub fn deref_as_owning(&'a mut self) -> OwningRef<'a, T::Target> {
1201 OwningRef((*self.0 .0).deref_mut(), PhantomData)
1202 }
1203}
1204
1205#[cfg_attr(
1206 feature = "nightly",
1207 doc = "
1208```rust
1209#![feature(arbitrary_self_types)]
1210# use std::marker::PhantomData;
1211# use std::mem::ManuallyDrop;
1212# use projecture::{DerefOwned, DropLeftovers, OwningRef};
1213trait Trait{
1214 fn test(self: OwningRef<'_,Self>);
1215}
1216
1217impl Trait for String{
1218 fn test(self: OwningRef<'_, Self>) {
1219 assert_eq!(\"test\", self.deref_owned());
1220 }
1221}
1222
1223let x = Box::new(String::from(\"test\")) as Box<dyn Trait>;
1224DropLeftovers::new(x).deref_as_owning().test()
1225```
1226"
1227)]
1228pub struct OwningRef<'a, T: 'a + ?Sized>(*mut T, PhantomData<fn(&'a ()) -> &'a ()>);
1229
1230impl<T: ?Sized> Drop for OwningRef<'_, T> {
1231 fn drop(&mut self) {
1232 unsafe { drop_in_place(self.0) }
1233 }
1234}
1235
1236impl<'a, T: ?Sized + 'a> Deref for OwningRef<'a, T> {
1237 type Target = T;
1238
1239 fn deref(&self) -> &Self::Target {
1240 unsafe { &*self.0 }
1241 }
1242}
1243impl<'a, T: ?Sized + 'a> DerefMut for OwningRef<'a, T> {
1244 fn deref_mut(&mut self) -> &mut Self::Target {
1245 unsafe { &mut *self.0 }
1246 }
1247}
1248impl<'a, T: 'a> DerefOwned for OwningRef<'a, T> {}
1249
1250#[cfg(feature = "nightly")]
1251impl<'a, T: ?Sized, U: ?Sized> core::ops::DispatchFromDyn<OwningRef<'a, U>> for OwningRef<'a, T> where
1252 T: core::marker::Unsize<U>
1253{
1254}
1255
1256pub struct OwningMarker<'a, T>(&'a mut ManuallyDrop<T>);
1257impl<'a, T> ProjectableMarker<T> for OwningMarker<'a, T> {
1258 type Output = T;
1259
1260 unsafe fn from_raw(&self, raw: *mut T) -> Self::Output {
1261 ptr::read(raw as *const T)
1262 }
1263}
1264
1265#[cfg(any())]
1271mod experiments;