projecture/
lib.rs

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/// Support for atomic types projection
23#[cfg(feature = "atomic")]
24pub mod atomic;
25
26// #[doc(inline)]
27pub use pin::*;
28/// Pin projection support
29pub mod pin;
30
31// #[doc(hidden)]
32// pub use memoffset::*;
33
34pub use option::OptionMarker;
35mod option;
36mod refcell;
37
38pub mod generic;
39
40// helper to wrap `T` `&T` and `&mut T` to prevent conflicting implementations when doing autoderef specialization
41#[doc(hidden)]
42pub unsafe trait Preprocess {
43    type Output;
44    fn preprocess(&self) -> Self::Output;
45}
46
47// ///Implement this on your reference type that you want to work with this crate (like `Pin` or `std::cell:Ref`)
48// pub unsafe trait MarkerNonOwned {}
49
50// wrapper to prevent overlapping implementations
51#[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// unsafe impl<T: MarkerNonOwned> Preprocess for &ManuallyDrop<T> {
63//     // unsafe impl<T: Reborrow> Preprocess for &ManuallyDrop<T> {
64//     // type Output = T::Reborrowed;
65//     type Output = T;
66//
67//     fn preprocess(&self) -> Self::Output {
68//         unsafe { transmute_copy(self) }
69//     }
70// }
71
72// wrapper to prevent overlapping implementations
73#[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
99///Trait to, if necessary, transparently wrap type to prevent conflicting implementations
100pub unsafe trait CustomWrapper {
101    /// `Self` but wrapped in `#[repr(transparent)]` wrapper,
102    /// or just `Self` if there is no problems with conflicting implementations
103    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
133//-----------------
134// ///Implement this if you want your pointer type to be reborrowed on `->` operation in `project` macro
135// pub unsafe trait Reborrow<'a> {
136//     type Reborrowed;
137//     fn reborrow(&'a mut self) -> Self::Reborrowed;
138// }
139// unsafe impl<'a, T: 'a> Reborrow<'a> for &mut T {
140//     type Reborrowed = &'a mut T;
141//
142//     fn reborrow(&'a mut self) -> Self::Reborrowed {
143//         &mut *self
144//     }
145// }
146// unsafe impl<'a, T: 'a> Reborrow<'a> for &T {
147//     type Reborrowed = &'a T;
148//
149//     fn reborrow(&'a mut self) -> Self::Reborrowed {
150//         &mut *self
151//     }
152// }
153// unsafe impl<'a, T: 'a> Reborrow<'a> for Pin<&mut T> {
154//     type Reborrowed = Pin<&'a mut T>;
155//
156//     fn reborrow(&'a mut self) -> Self::Reborrowed {
157//         self.as_mut()
158//     }
159// }
160// unsafe impl<'a, T: 'a> Reborrow<'a> for Pin<&T> {
161//     type Reborrowed = Pin<&'a T>;
162//
163//     fn reborrow(&'a mut self) -> Self::Reborrowed {
164//         self.as_ref()
165//     }
166// }
167// #[doc(hidden)]
168// pub unsafe trait DoReborrow {
169//     type Reborrowed;
170//     unsafe fn do_reborrow(&self) -> Self::Reborrowed;
171// }
172// unsafe impl<'a, T> DoReborrow for ManuallyDrop<&'a mut T> {
173//     type Reborrowed = &'a mut T;
174//
175//     unsafe fn do_reborrow(&self) -> Self::Reborrowed {
176//         transmute_copy(self)
177//     }
178// }
179// unsafe impl<'a, T: Reborrow<'a>> DoReborrow for &ManuallyDrop<&'a mut T> {
180//     type Reborrowed = T::Reborrowed;
181//
182//     unsafe fn do_reborrow(&self) -> Self::Reborrowed {
183//         transmute_copy(*self)
184//     }
185// }
186//-----------------
187/// Trait to get raw pointer to underlying struct
188pub unsafe trait Projectable {
189    /// Inner type to which projection will be applied
190    type Target;
191    /// Marker type to track information about the type of projection being done
192    /// Should implement `ProjectableMarker`
193    type Marker;
194
195    /// Get raw pointer to underlying struct
196    fn get_raw(&self) -> (*mut Self::Target, Self::Marker);
197}
198
199/// Trait to wrap raw pointer to a field with a type that corresponds to a projection being done.
200///
201/// Marker also must have an inherent empty `pub fn check(&self){}` function which is used to check that `project!`
202/// macro works on concrete types, and not on generics, you can look at [`Marker::check`] as an example.
203pub trait ProjectableMarker<T: ?Sized> {
204    /// Wrapped pointer type
205    type Output;
206    /// Wraps raw pointer to a field with a type that corresponds to a projection being done
207    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
215/// Implement it if your projection can meaningfully project through a deref operation
216pub 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
228// #[doc(hidden)]
229/// Marker type for the projections used in this crate.
230/// You can use that if you need to reuse existing projections.
231// #[derive(Copy,Clone)]
232pub 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// #[doc(hidden)]
255// pub struct DerefMarkerWrapper<T>(PhantomData<T>);
256// impl<T> DerefMarkerWrapper<T> {
257//     #[doc(hidden)]
258//     pub unsafe fn new(_value: &T) -> Self {
259//         Self(PhantomData)
260//     }
261// }
262
263#[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
334//--------------
335unsafe 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
357/// Version of `Deref` trait that allows moving out `Self::Target` from `Self` by value.
358pub trait DerefOwned: DerefMut {
359    /// Drops what's left of `Self` when `Self::Target` was moved out
360    ///
361    /// Safety requirements: must not be called twice on the same instance,
362    /// implementation must not access `Self::Target`
363    unsafe fn drop_leftovers(_leftovers: &mut ManuallyDrop<Self>) {}
364    // /// Safety requirements: must not be called twice on the same instance
365    // unsafe fn move_out_target(md: &mut ManuallyDrop<Self>) -> Self::Target
366    // where
367    //     Self::Target: Sized,
368    // {
369    //     /// need to go through `deref_mut` because we need to ensure that we have unique access to `Self::Target`
370    //     /// otherwise it would be possible to move out from `Rc`
371    //     ptr::read(&*(**md).deref_mut())
372    // }
373
374    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>);
403// impl<T: DerefOwned> OwnedDropMarker<T> {
404//     pub fn check() {}
405// }
406impl<'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
431//---------------------
432unsafe 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
478// impl<'a, T: DerefMut + 'a> ProjectableMarker<Pin<T>> for &DerefMarkerWrapper<Marker<&'a mut ()>> {
479//     type Output = Pin<&'a mut T::Target>;
480//
481//     unsafe fn from_raw(&self, raw: *mut Pin<T>) -> Self::Output {
482//         (&mut *raw).as_mut() // todo idea, deref should happen in finalize
483//     }
484// }
485
486//---------------------
487unsafe 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}
521// impl<'a, T: Deref + 'a> ProjectableMarker<T> for DerefMarkerWrapper<Marker<&'a ()>> {
522//     type Output = &'a T::Target;
523//
524//     unsafe fn from_raw(&self, raw: *mut T) -> Self::Output {
525//         &**raw
526//     }
527// }
528//---------------------
529unsafe 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}
553//---------------------
554unsafe 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}
572//---------------------
573unsafe 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
592//---------------------
593unsafe 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
612//---------------------
613unsafe 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
632//---------------------
633/// Implement that if you need to do some kind of post processing like unwrap something
634/// or panic if some soundness requirements are not satisfied
635pub trait FinalizeProjection {
636    type Output;
637    unsafe fn finalize(&self) -> Self::Output;
638}
639//---------------------
640#[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//----------------
690
691#[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
712//----------------
713
714/// Implement this only if your projection can work with `#[repr(packed)]` structs.
715pub unsafe trait SupportsPacked {
716    type Result;
717    fn select(&self) -> *mut Self::Result {
718        NonNull::dangling().as_ptr()
719    }
720}
721
722// todo figure out how to make that implementable by downstream crates
723unsafe 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 to do all kinds of projections
743///
744/// Has two modes:
745///  - `let` syntax very similar to regular rust's `let <pattern> = <expr>`.
746///    Basically it is exactly the same but also has additional support for deref patterns and does not yet supports bindings via `@`.
747///  - single field projection `project!(<variable> -> <field>)` or `project!((<expression>) -> <field>)`.
748///     Basically same as doing `let` option with one field, but this one is an expression while `let` one is a statement.
749///     Also this variant additionally tries to do an implicit deref projection if possible.
750///     Note though that you will get an error if inner type of projection implements `Deref`.
751///     This is caused by the fact that Rust's `.` operator(which is used by this macro) can go through an implicit deref call
752///     which would ruin all unsafe logic.
753///
754/// ```rust
755/// #   use std::cell::Cell;
756/// #   use std::mem::MaybeUninit;
757/// #   use projecture::project;
758///     struct Foo {
759///         x: usize,
760///         y: usize,
761///     }
762///     let cell = Cell::new(Foo { x: 0, y: 0 });
763///     let mut cell_ref = &cell;
764///     // project only one field
765///     project!(cell_ref -> x).set(1);
766///     // do a full let destructuring matching
767///     project!(let Foo { x, y } = &cell);
768///     x.set(1);
769///     y.set(1);
770///
771///     let foo = Foo { x: 0, y: 0 };
772///     project!(let Foo { x, y } = &foo);
773///     let x: &usize = x;
774///     let y: &usize = y;
775///
776///     project!(let Foo { x: x, y: ref mut y } = foo);
777///     let x: usize = x;
778///     let y: &mut usize = y;
779///
780///     let mut foo = Foo { x: 0, y: 0 };
781///     project!(let Foo { x, y } = &mut foo);
782///     *x = 1;
783///     *y = 1;
784///
785///     let mut mu = MaybeUninit::<Foo>::uninit();
786///     project!(let Foo { x:x, y:y } = &mut mu);
787///     let x: &mut MaybeUninit<usize> = x;
788///     let y: &mut MaybeUninit<usize> = y;
789///
790///     struct Bar(usize, usize);
791///     let mut foo = Bar(1, 2);
792///     project! { let Bar(x,y) = &mut foo }
793///     project! { let Bar{ 0: x, 1: y } = &mut foo }
794///     let mut foo_mut = &mut foo;
795///     *project!(foo_mut -> 0) = 1;
796///     *project!((&mut foo) -> 0) = 1;
797/// ```
798/// It supports dereferencing during pattern matching
799/// ```rust
800/// #    use projecture::project;
801///     struct Foo {
802///         x: Box<usize>,
803///         y: Box<usize>,
804///     }
805///     let mut foo = Foo {
806///         x: Box::new(0),
807///         y: Box::new(0),
808///     };
809///     project!( let Foo{ x: *x, y: *y }  = &mut foo );
810///     let x: &mut usize = x;
811///     project!( let Foo{ x: * x, y: * ref mut y }  = foo );
812///     let x: usize = x;
813///     let y: &mut usize = y;
814/// ```
815/// Also `Pin` projection:
816/// ```rust
817/// #    use std::marker::PhantomPinned;
818/// #    use std::pin::Pin;
819/// #    use projecture::{project, Unpinned,PinProjectable};
820///     #[macro_rules_attribute::derive(PinProjectable!)]
821///     struct Foo<T, U: Unpin, V> {
822///         a: usize,
823///         b: T,
824///         c: U,
825///         d: Unpinned<V>,
826///         e: PhantomPinned,
827///     }
828///
829///     fn test<T, U: Unpin, V>(foo: Pin<&mut Foo<T, U, V>>) {
830///         project!(let Foo{ a,b,c,d,e } = foo);
831///         let a: &mut usize = a;
832///         let b: Pin<&mut T> = b;
833///         let c: &mut U = c;
834///         let d: &mut V = d;
835///         let e: Pin<&mut PhantomPinned> = e;
836///     }
837/// ```
838/// `Option` projection, which also works together with other projections
839/// ```rust
840/// # use std::marker::PhantomPinned;
841/// # use std::pin::Pin;
842/// # use projecture::{project,PinProjectable};
843/// #[macro_rules_attribute::derive(Default,PinProjectable!)]
844/// struct Foo{
845///     x: Box<usize>,
846///     y: usize,
847///     p: PhantomPinned
848/// }
849/// let mut arg = Some(Foo::default());
850/// project!(let Foo { x: *x, y } = arg.as_mut());
851/// let x: Option<&mut usize> = x;
852/// let y: Option<&mut usize> = y;
853///
854/// project!(let Foo { x, y } = arg);
855/// let x: Option<Box<usize>> = x;
856/// let y: Option<usize> = y;
857///
858/// # // todo
859/// # // fn test_pin(arg: Option<Pin<&mut Foo>>){
860/// # //     project!(let Foo { p, ..} = arg );
861/// # //     let p: Option<Pin<&mut PhantomPinned>> = p;
862/// # // }
863/// ```
864/// `Ref`/`RefMut` projection
865/// ```rust
866/// # use std::cell::{Ref, RefCell, RefMut};
867/// # use projecture::project;
868/// #[derive(Default)]
869/// struct Foo(String,String);
870/// let arg = RefCell::new(Foo::default());
871/// project!(let Foo(x,_) = arg.borrow());
872/// let x: Ref<String> = x;
873/// # drop(x);
874///
875/// project!(let Foo(x, ..) = arg.borrow_mut());
876/// let x: RefMut<String> = x;
877/// ```
878/// Raw pointer projection (`*const T`, `*mut T`, `NonNull<T>`).
879/// Note that it is safe because it behaves like a [`pointer::wrapping_offset`](https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_offset).
880/// If you want unsafe [`pointer::offset`](https://doc.rust-lang.org/std/primitive.pointer.html#method.offset) like behavior you can still enable that by doing `.add(0)` on a resulting pointer
881/// ```rust
882/// use std::ptr::NonNull;
883/// use projecture::project;
884/// #[repr(C,packed)]
885/// struct Packed(u8,usize);
886/// let mut x = Packed(1,2);
887/// let ptr = &x as *const Packed;
888/// let val = unsafe { project!(ptr -> 1).read_unaligned() };
889/// assert_eq!(val,2);
890///
891/// let ptr:Option<NonNull<Packed>> = NonNull::new(&mut x);
892/// let field_ptr: Option<NonNull<usize>> = project!(ptr -> 1);
893/// let val = field_ptr.map(|ptr|unsafe { ptr.as_ptr().read_unaligned() } );
894/// assert_eq!(val,Some(2));
895/// ```
896#[macro_export]
897macro_rules! project {
898    // ( { $($field:ident),+  } = $target:expr) => {};
899    (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        // if false{
911        //     use $crate::AmbiguityCheck;
912        //     let _:() = marker.check();
913        //     // let $struct { .. } = unsafe { &*ptr };
914        // }
915        $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        // if false{
929        //     use $crate::AmbiguityCheck;
930        //     let _:() = marker.check();
931        //     // let $struct { .. } = unsafe{ &*ptr };
932        // }
933
934        $crate::project_tuple_fields! { [ptr marker $struct] [] [] $($fields)+ }
935        drop(marker);
936    };
937    (let * $($tail:tt)+) => {
938        $crate::project_deref!{ [] $($tail)+ }
939    };
940    // why the f `let _ = x;` does not drop `x` ?!!
941    // and at the same time `let _ = Foo;` does drop `Foo` ... , like wtf?!!
942    (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          //todo
952    };
953    (( $var:expr ) -> $field:tt $($tail:tt)*) => {
954        {
955            $crate::project_deref!( ? [ var ] = $var);
956            // use $crate::DoReborrow;
957            let var = core::mem::ManuallyDrop::new(var);
958            // let var = unsafe { core::mem::ManuallyDrop::new((&&var).do_reborrow()) };
959            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::AmbiguityCheck;
970                // let _:() = marker.check();
971                use $crate::CheckNoDeref;
972                // check that (*ptr).field would not go through a deref
973                (&&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/// ```rust,compile_fail
1066/// use projecture::project;
1067/// #[repr(packed)]
1068/// struct Test{
1069///     x:u8,
1070///     y: usize,
1071/// }
1072/// fn test(arg:&Test){
1073///     project!(let Test { x, y } = arg);
1074/// }
1075/// ```
1076///
1077/// ```rust,compile_fail
1078///     use projecture::project;
1079///     use core::cell::Cell;
1080///     struct Foo(usize, usize);
1081///     let tmp = Cell::new(Box::new(Foo(1, 2)));
1082///     let x = project!((&tmp) -> 1);
1083/// ```
1084///
1085/// ```rust,compile_fail
1086/// use std::marker::PhantomPinned;
1087/// use std::pin::Pin;
1088/// use projecture::project;
1089/// struct Foo(usize,PhantomPinned);
1090/// impl Drop for Foo{
1091///     fn drop(&mut self) {}
1092/// }
1093/// fn test(arg: Pin<&mut Foo>){
1094///     let _ = project!(arg -> usize);
1095/// }
1096/// ```
1097#[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            // check for #[packed] struct
1157            #[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
1182/// Keeps track of stuff that was left of `T` when we moved out `T::Target` from it.
1183pub struct DropLeftovers<'a, T: DerefOwned>(
1184    // workaround to not require #[may_dangle] on 'a
1185    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//todo:
1266// pattern matching/enums
1267// foldable trait
1268//
1269
1270#[cfg(any())]
1271mod experiments;