Getting PhantomData to have a 'static lifetime

I'm trying to implement a generic "id container" struct that is strongly typed. Basically its a struct with a generic parameter to hold the type and a small payload.

Since the generic parameter is unused within the struct, I need to add a PhantomData<T> member. When this parameter's type does not have a 'static lifetime, this affects the entire struct.

The following code that reproduces this issue:

use std::marker::PhantomData;

struct Tag<T>(usize, PhantomData<T>);
struct WithRef<'a>(&'a i32);

trait SomeTrait {}
impl<T> SomeTrait for Tag<T> {}

fn ok() {
    let obj = Tag::<i32>(1, PhantomData);
    let _dyn_obj: &(dyn SomeTrait + 'static) = &obj;
}

fn bad<'b>() {
    let obj = Tag::<WithRef<'b>>(2, PhantomData);
    let _dyn_obj: &(dyn SomeTrait + 'static) = &obj;
}

outputs this compiler error:

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements                                    
  --> src\main.rs:15:15
   |
15 |     let obj = Tag::<WithRef<'b>>(2, PhantomData);
   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the lifetime `'b` as defined on the function body at 14:8...
  --> src\main.rs:14:8
   |
14 | fn bad<'b>() {
   |        ^^
note: ...so that the expression is assignable
  --> src\main.rs:15:15
   |
15 |     let obj = Tag::<WithRef<'b>>(2, PhantomData);
   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: expected  `Tag<WithRef<'_>>`
              found  `Tag<WithRef<'b>>`
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that the expression is assignable
  --> src\main.rs:16:48
   |
16 |     let _dyn_obj: &(dyn SomeTrait + 'static) = &obj;

   |                                                ^^^^
   = note: expected  `&(dyn SomeTrait + 'static)`
              found  `&dyn SomeTrait`

https://doc.rust-lang.org/beta/std/marker/struct.PhantomData.html mentions that:

If your struct does not in fact own the data of type T, it is better to use a reference type, like PhantomData<&'a T> (ideally) or PhantomData<*const T> (if no lifetime applies), so as not to indicate ownership.

But neither PhantomData<&'a T>nor PhantomData<*const T> makes this code compile.

Is there any way to keep the generic parameter without loosing the 'static lifetime?

Thanks!

This forum is for the development of Rust itself. Questions about using Rust are better suited for https://users.rust-lang.org/

My bad!

I reposted the question there.

Thanks for the heads up!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.