Why the code branch with raw can't been compile?

hi, can anyone explain the following code is different: in feature raw branch, it can't been compiled but can passes compiling in another feature branch.

use std::mem;
use std::ptr;
use std::ptr::NonNull;
use std::alloc::alloc;
use std::alloc::Layout;
use std::alloc::dealloc;

pub trait IsAllocator1 {
    fn alloc<T> () -> NonNull<T>;
    unsafe fn free<T> (_: NonNull<T>);
}

pub enum Allocator1 {
}

impl IsAllocator1 for Allocator1 {
    fn alloc<T> () -> NonNull<T> {
        let ptr = unsafe {
            alloc(Layout::new::<T>()) as *mut T
        };
        NonNull::new(ptr).unwrap_or_else(|| unreachable!())
    }

    unsafe fn free<T> (ptr: NonNull<T>) {
        let ptr =  ptr.cast::<T>().as_ptr();
        dealloc(ptr as *mut u8, Layout::new::<T>());
    }
}

pub trait IsAllocator2 {
    fn alloc<T> () -> *mut T;
    unsafe fn free<T> (_: *mut T);
}

pub enum Allocator2 {
}

impl IsAllocator2 for Allocator2 {
    fn alloc<T> () -> *mut T {
        let ptr = unsafe {
            alloc(Layout::new::<T>()) as *mut T
        };
        ptr
    }

    unsafe fn free<T> (ptr:*mut T) {
        dealloc(ptr as *mut u8, Layout::new::<T>());
    }
}

pub struct Box<T> {
    #[cfg(not(feature = "raw"))]
    ptr: NonNull<T>,

    #[cfg(feature = "raw")]
    ptr: *mut T,

    //_marker: marker::PhantomData<T>
}

impl<T> Drop for Box<T> { fn drop (&mut self) {
     unsafe {
        eprintln!("[Dropping the Box at {:p}]", self);

        if mem::needs_drop::<T>() {
            eprintln!(

                "[Recursively dropping the pointee at {:p}]", self.ptr,

            );

            ptr::drop_in_place::<T>(self.get_mut());

        } else {
            eprintln!("[No need to drop the pointee at {:p}]", self.ptr);

        }

        #[cfg(not(feature = "raw"))]
        Allocator1::free(self.ptr);

        #[cfg(feature = "raw")]
        Allocator2::free(self.ptr);
    }
}}

impl<T> Box<T> {
    pub fn new (value: T) -> Self {
        #[cfg(not(feature = "raw"))]
        {
            let non_null = Allocator1::alloc();
            unsafe { ptr::write(non_null.as_ptr(), value); }
            Self { 
                ptr: non_null,
                //_marker: marker::PhantomData
            }
        }

        #[cfg(feature = "raw")]
        {
            let non_null = Allocator2::alloc();
            unsafe { ptr::write(non_null, value); }
            Self { 
                ptr: non_null,
                //_marker: marker::PhantomData
            }
        }
    }

    pub fn get (&'_ self) -> &'_ T {
        #[cfg(not(feature = "raw"))]
        unsafe { 
            self.ptr.as_ref() 
        }

        #[cfg(feature = "raw")]
        unsafe {
            & *self.ptr
        }
    }

    pub fn get_mut (&'_ mut self) -> &'_ mut T {
        #[cfg(not(feature = "raw"))]
        unsafe { 
            self.ptr.as_mut()
        }

        #[cfg(feature = "raw")]
        unsafe { 
            &mut *self.ptr
        }
    }
}

fn main() {
    let mut p: Box<Option<&String>> = Box::new(None);
    let s = String::from("Hello, World!");

    #[cfg(not(feature = "raw"))]
    let ptr: *mut Option<&String> = p.ptr.as_ptr();

    #[cfg(feature = "raw")]
    let ptr: *mut Option<&String> = p.ptr;

    unsafe { 
        ptr::write(ptr, Some(&s)); 
        println!("{:?}", p.ptr);
    }
    dbg!(p.get());
}

What is the compilation error?

s has been droped while may used in the drop of p, it is not about the error but why *mut T can catches such an error, while NonNull can't.

And ptr::write take raw pointers as argment why drop chrcker analyse such a function

It sounds like it's related to NonNull<T> being covariant in T while *mut T is invariant in T. The nomicon has an article on variance. If your box owns a value of type T, you want a phantomdata with T as the generic parameter.

I don't understand the reason. I assume even it is a *cont T will also cause such an error

I'm not too familiar with the details of this part of Rust, but this page recommends something like the Unique smart pointer.

I see you've posted rather a lot of topics regarding phantomdata and various types of pointers. Are you trying to build something in particular, or just trying to understand the topic?

I want to know the exactly rules of lifetime to predict the rust behavior; currently I don't know when, where and what rust will perform some dropping and checking; I can't make sure which line I wrote has bugs or which line is OK.