-
Notifications
You must be signed in to change notification settings - Fork 205
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
Use sound approximations for non-covariant types #296
Labels
request
Requests to resolve a particular developer problem
Comments
This was referenced Apr 3, 2019
5 tasks
copybara-service bot
pushed a commit
to dart-lang/sdk
that referenced
this issue
Nov 15, 2024
This CL implements a new lint, `unsafe_variance`. This lint emits a warning whenever an instance member declaration has a signature where a type variable declared by the enclosing class/mixin/enum occurs in a non-covariant position in the return type (including the type of an instance variable). Issues: https://github.com/dart-lang/linter/issues/4111, with goals related to dart-lang/language#296 and dart-lang/language#524. Change-Id: I1352d71d61fece03a432ccf0d98825a69e3a457f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/384700 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Erik Ernst <eernst@google.com>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Cf. dart-lang/sdk#33697, dart-lang/site-www#1017, and more than a dozen issues linked from the latter.
Consider the following example:
In this example, the class
C
has a member whose type is not covariant in the type parameters of the enclosing class: If the type ofc
isC<num>
orC<int>
then the type ofc.f
isvoid Function(num)
respectivelyvoid Function(int)
, and the latter is not a subtype of the former.This means that it is not a sound assumption that if the static type of the receiver
c
isC<num>
then the dynamic type ofc.f
will be a subtype of its "statically known" typevoid Function(num)
.In order to preserve soundness (in particular, to prevent that any run-time entity—like a variable, parameter, returned value, or expression result—can ever have a type which is not a subtype of its static type), we must prevent that
foo
returns the function of typevoid Function(int)
which is the value ofc.f
during the invocation offoo
inmain
.However, there would not be any such problem if we were to add the following to the class
C
as an instance method:The difference is that the contravariant occurrence of
X
in the type of the fieldf
is no problem when the actual type can be denoted (becauseX
is in scope), but when viewing an instance ofC<T>
from outside the class, we have a clash between the covariance of the class and the contravariance of the field type. Or, in general, a clash between the covariance of the class and any non-covariant occurrence of a type variable in the signature of a member of the enclosing class. As a convenient abbreviation, we have referred to such members as "contravariant" in many discussions about this topic.We have one obvious remedy for this category of problems: Explicitly declared variance, cf. #214, #229, #524.
However, the use of invariance makes every usage of a class less flexible (declaration-site invariance, #214) or each declaration of a variable or similar entity of such a type (use-site invariance, #229).
This issue is a request to make the use of such contravariant members statically safe, even in the case where one or more of the relevant type parameters of the receiver type is covariant.
The text was updated successfully, but these errors were encountered: