-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[vm/ffi] Change Pointer to use sound variance? #38646
Comments
The So the magic must be in the Anyway, given that a With that, However, we could still use use-site variance to specify that we wish to allow a certain kind of variance: Pointer<out Pointer<out T>> p; Use-site variance is an extension of the model that I've described in dart-lang/language#557: It extends use-site invariance (where only This would allow for maintaining the information that we are working on a I'm not sure whether that will precisely preserve the level of static safety that you have currently, but it seems likely to be at least very similar. |
@eernstg with the move to extension methods we get rid of most of the For example: extension PointerPointer<T extends NativeType> on Pointer<Pointer<T>> {
/// Load a Dart value from this location.
///
/// The value is automatically unmarshalled from its native representation.
///
/// Note that [address] needs to be aligned the size of [Pointer].
Pointer<T> get val => _loadPointer(this);
/// Store a Dart value into this location.
///
/// The [value] is automatically marshalled into its native representation.
///
/// Note that [address] needs to be aligned the size of [Pointer].
set val(Pointer<T> val) => _storePointer(this, val);
/// Load a Dart value from this location offset by [index].
///
/// The value is automatically unmarshalled from its native representation.
///
/// Note that [address] needs to be aligned the size of [Pointer].
Pointer<T> operator [](int index) => this.elementAt(index).val;
/// Store a Dart value into this location offset by [index].
///
/// The [value] is automatically marshalled into its native representation.
///
/// Note that [address] needs to be aligned the size of [Pointer].
operator []=(int index, Pointer<T> value) =>
this.elementAt(index).val = value;
} Source: https://dart-review.googlesource.com/c/sdk/+/118992/1/sdk/lib/ffi/ffi.dart#550 Does declaring the type parameter of For use site variance, does use site variance always mean you do not specify definition variance (e.g. we keep Pointer unsound covaraint)? That would mean users of the Pointer API opt-in to more static checks on a per use site basis. |
Yes: When So we know that the static and the dynamic type argument at the call site of the extension method are identical, so the The application of use-site variance that I mentioned was based on the assumption that So it actually means that the users of the Having opted out, actual instance methods would be filtered out when they use the type argument in a non-covariant manner (for a type like An example of this kind of filtering which is based on a well-known class would be that you can't invoke We haven't specified the details at this point, but extension methods could (and presumably should) be filtered in the same way. We have this notion of 'erasure' in the variance feature specification, and there would be a similar concept for the extended version (using |
Ah that clarifies things!
So if we change it to That makes the pros/cons tradeoffs as follows. Unsound covariance (current Dart semantics):
Using
|
Exactly! |
The normal Dart variance is unsound, which will be addressed in a future Dart version: dart-lang/language#524.
In
dart:ffi
we use this unsound covariance when loading from and storing intoPointer
:We could consider changing the type parameter of
Pointer
toinout
to prevent that:However, that would force
dart:ffi
users who do want to write generic code to use.cast()
, which makes them lose runtime type information:Unsound covariance (current Dart semantics):
Using
inout
to declare invariant:Thoughts @sjindel-google @lrhn @eernstg @mkustermann @mraleph ?
If we want to go for invariant, we probably want to lock out generic use before we unmark
dart:ffi
as experimental.The text was updated successfully, but these errors were encountered: