Closed Boddlnagg closed 7 years ago
This is mostly solved in https://github.com/contextfree/winrt-rust/pull/3/commits/3e34a34fc23e4289be3796955659f83b3f0b359e by using &T::In
. When T
is a value type, the value is copied within unwrap()
(the trait RtValueType
now implies Copy
).
The only remaining lifetime is for strings: since the input type HStringRef<'a>
requires a lifetime we still use &'a str
as generic parameter. I'm leaving this issue open to find a better solution in that case.
The last remaining lifetime has been removed in https://github.com/contextfree/winrt-rust/pull/11/commits/d79dc38f6ffa15ef5b18dab3475625326174f32e.
Currently lifetimes of generic parameters are set to
'static
in aliases and return types. This requires the "hack" that for interface and class definitionsRtInterface::In
is set to*mut interface
.If possible,*mut
pointers should be avoided (the wrappers are currently defined asunsafe
, but that could be changed as soon as we are more confident, and*mut
pointers probably shouldn't be part of safe signatures). The problem is that generic types can either be value types or references, but only references have a lifetime. Ideally that lifetime should be tied to the lifetime of a given reference to the outermost type.As a example, let's take
DeviceInformationCollection
. It is currently defined as a newtype wrapper aroundIVectorView<&'static DeviceInformation>
. Even if it was defined with a lifetime parameter'a
wrappingIVectorView<&'a DeviceInformation>
instead, that would not be enough, because we would need any reference of type&'x DeviceInformationCollection
to refer to&'x IVectorView<&'x DeviceInformation>
, i.e. the lifetime of the reference itself should be the same as the lifetimes of the generic parameters, with the desired result that whenever the generic parameterT
appears in methods ofIVectorView<T>
and is instantiated with a reference type, its lifetime is always linked to the lifetime of the&mut self
reference.In other words, when a generic interface has a method
foo(&mut self, data: T::In)
and T is a reference to an interface typeISomething
, we want the method to act as if it was defined asfoo(&mut self, data: &ISomething)
which (due to lifetime elision) is equivalent tofoo(&'a mut self, data: &'a ISomething)
.But since
T
can never refer to the'a
of&'a mut self
, we need to find a different solution. We also can't trivially do something likefoo(&mut self, data: &T::In)
, becauseT
(and therefore alsoT::In
) might be a value type that needs to be passed by value.Maybe one could add some lifetime bounds on
T
orT::In
, e.g.foo<'a>(&'a mut self, data: T::In) where T: 'a
, I have not tested this yet.