Does the Self
type include T
, or is there some type erasure going on?
- Addendum: looking at your docs, it does seem to be the former:
KMutex<T>
, which is good.
While it is true that <T>
genericity can encompass the T = *{const,mut} U
case(s), by doing so the user ought to end up with YourWrapper<*{const,mut} U>
rather than YourWrapper<U>
, so hopefully that severly limits the "damage" of such a mistake.
If what you're worried about are lifetimes, then you probably want is a T : 'static
clause/bound.
Indeed, this literally means T : UsableFor<'forever>
, as in, any (owned) instance of the type T
is safe to use/handle (e.g., move around!) for the duration 'static = 'forever
-
note that this is a weaker property than witnessing a &'forever T
reference, since that one means that the pointee/referee behind that reference:
- is not only of a type which is
: UsableFor<'forever>
,
- but also that that specific pointee will remain there, "without moving or getting deällocated",
'forever
.
The typical example being String
, which is indeed : 'static
i.e. : UsableFor<'forever>
, since any (owned) instance of type String
is safe to use/handle 'forever
. It is "independent" from other lifetimes. This is different from T = &'short str
, which is not safely usable beyond the 'short
duration. It is also weaker than T = &'static String = &'forever String
, which would mean having a specific String
instance located somewhere in memory, 'forever
, thus kind of "pinned down" there (thus very likely to stem from leaked memory).
Philosophical questions aside, a type T
is : 'static
if and only if any lifetime parameter appearing within T
is itself 'static
. So either the type has no lifetime parameters whatsoever inside, such as T = String
, or if it does, they must be 'static
, such as Cow<'static, str>
or &'static str
itself (a &'forever
reference is itself : UsableFor<'forever>
).
You may still be worried about the case of T = *const i32
, for instance, which is : [Safely]UsableFor<'forever>
, because:
- in practical terms, there are indeed no lifetime parameters occuring within the type
*const i32
;
- from the PoV of safe API usage, there is no non-
unsafe
API with which you can do anything dangerous when having a *const i32
instance around: if you do want to do something (useful but) dangerous with such a value, such as dereferencing that pointer, then unsafe { … }
is to be used, thereby waiving any liability from the compiler's type system safety guarantees.
Which, as a library author, also waives any liability in your regard: if a user wants to shoot themself in the foot by storing a *const i32
inside your KMutex<*const i32>
type, to later try to fetch it, dereference it, and end up triggering UB from a user-after-free, then that's on them, not on you (you are free to try to document lifetime invariants/properties or lack thereof in the docs, but cannot be held accountable for such mistakes).
However, you are dealing with kernel drivers, which is a rather unusual/exotic situation, not all unlike dynamically loading libraries and whatnot. So maybe you'll have to be even stricter than just : 'static
, since maybe a &'static i32
or &'static str
, alone, can trigger memory unsafety in your API.
If that's the case, do tell us so, because more effort will be needed. But be aware that in this area Rust is quite bad / has a rather poor type system, because Rust assumes that static
memory of the process, or leaked memory (including the backing memory of an allocator), both get to live 'forever
(which is witnessed, from instance, by that amalgamation of static
and 'forever
notions in the poorly named 'static
keyword).
And I know that at least for dynamic library loading, this is not true. "We" may be a dynamically loaded plugin which may end up unloaded before the end of the life-time of the whole process (the "host").
In such situations, the inadequacy of 'static
makes the whole type system unsound. This is known, and the current cop-out is just to say that unloading a dynamic library is unsafe
(or, in an even more convoluted and contrived manner, that loading it is, because of it ultimately ending up unloaded), and that any non-type-system-checked use-after-frees resulting from using 'static
memory from the to-be-unloaded library is the fault of whoever called that unsafe
API.