2
use core::marker::PhantomData;

fn main() {
    struct Inspector<'a>(&'a u8);

    impl<'a> Drop for Inspector<'a> {
        fn drop(&mut self) {
            println!("I was only {} days from retirement!", self.0);
        }
    }
    
    struct Uniqu<T> {
        ptr: *mut T,
        marker: PhantomData<T>,  
    }
    
    struct World<'a> {
        ptr: Option<Uniqu<Inspector<'a>>>,
        days: u8,
    }

    
    let mut world = World{ptr: None, days:1};

    let mut inspector = Inspector(&world.days);
    let mut uniqu = Uniqu::<Inspector>{ptr: &mut inspector, marker: PhantomData};
    world.ptr = Some(uniqu);

}

By refer to drop check rule, It can't compiles successfully. But successfully. And if i use such code:

use core::marker::PhantomData;

fn main() {
    struct Inspector<'a>(&'a u8);

    impl<'a> Drop for Inspector<'a> {
        fn drop(&mut self) {
            println!("I was only {} days from retirement!", self.0);
        }
    }
    
    
     struct World<'a> {
         ptr: Option<Box<Inspector<'a>>>,
         days: u8,
     }
    
    
    let mut world = World{ptr: None, days:1};
    let mut inspector = Inspector(&world.days);

    world.ptr = Some(Box::new(inspector));

}

Just use Box instead of Uniqu In World struct, it compiles unsuccessfully:

error[E0597]: `world.days` does not live long enough
  --> src/main.rs:21:35
   |
21 |     let mut inspector = Inspector(&world.days);
   |                                   ^^^^^^^^^^^ borrowed value does not live long enough
...
26 | }
   | -
   | |
   | `world.days` dropped here while still borrowed
   | borrow might be used here, when `world` is dropped and runs the destructor for type `World<'_>`

In this situation, drop checker have checked it. This is what I need.

In first situation, drop checker haven't checked it. PhantomData seems not work, why?

dd.ho
  • 79
  • 4
  • I don't have time for deep inspection now, and I never truly understood dropck, but it looks like you're missing a `Drop` impl in `Uniqu`. – Chayim Friedman Nov 03 '22 at 11:08

1 Answers1

0

In your first example, Uniqu does not implement Drop, so it has no potentially-unsafe drop code to check for.

Box however does implement Drop - so that it can free the memory it has allocated - which is why it does not pass the drop checker.

Adding a trivial Drop implementation to Uniqu in your first code section does cause the compiler to reject the code, as seen in the playground.

Colonel Thirty Two
  • 23,953
  • 8
  • 45
  • 85