Make cast
method produced by implement
macro unsafe
#1753
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #1183
note: this PR originally removed the
cast
method all together, but I then discovered that's not really desirable, so I added it back in.*The
implement
macro creates acast
method for the types usingimplement
macro that allowed users to query for arbitrary interfaces directly from the implementing type. This method, however, is very hard to use properly as it required that not onlyself
be heap allocated and pinned but that it be allocated inside the type's corresponding_Impl
struct. While this is often the case, the compiler does not enforce this being the case. When there are safety invariants the compiler can't enforce,unsafe
is the right tool for informing users to be careful.This PR makes the
cast
methodunsafe
which should at least draw the user's attention to the requirements described above.Additionally, this PR adds an
alloc
method. This method does the dance of placing the type inside the_Impl
struct, heap allocating it, and then callingQueryInterface
to query for the supplied interface. This is essentially the dynamic equivalent of the variousFrom
impls theimplement
macro already creates (which can skip callingQueryInterface
since we know those interfaces are implemented).alloc
still has the issue of consumingself
meaning that oncealloc
is called the user can no longer use the original implementation type. However, if the user needs access to the original type, the user can query for one of the interfaces used in theimplement
macro which will implement theAsImpl
trait allowing the user to retrieve an&
reference to the original type. Unfortunately, if the call toalloc
fails (presumably because the type does not implement the interface being queried for), the user will no longer have any access to the underlying type (and it will be freed).Some questions and thoughts:
cast
unsafe is quite unfortunate, but currently the best thing we can do.self: &Pin<Box<Self>>
which is certainly not pretty._Impl
type. I think, unfortunately, the right thing to do is to make all trait methods for a COM interface unsafe. Then it would be up to the caller to ensure this invariant.alloc
function actually useful? Would it perhaps be a better idea to remove it?alloc
, should we consider returningself
on failure so the user can keep using it?