-
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
Class generic type not resolved for function field using same generics without specification #48108
Comments
@idraper, you need sound variance (e.g., dart-lang/language#524) in order to be able to use an instance variable whose type has an occurrence of a type variable of the enclosing class in a contravariant position. See also dart-lang/language#297 for more information about the situation, and another potential language design take on it. If you do have an instance variable with that property after all then it is potentially a dynamic error to even evaluate the corresponding getter (you don't even have to call the function void main(List<String> arguments) {
FindVisitor<num, num> v = FindVisitor<int, int>(0, (a, int b) => true);
v.matcher; // Throws!
} So, in practice, you want a different design. Perhaps you can use this: // Define each matcher by writing a subtype (`extends` or `implements`)
// and override `matcher`.
abstract class FindVisitor1<F, R extends F> {
FindVisitor(this.find);
final F find;
bool matcher(F a, R b);
}
class FindVisitor2<F, M extends bool Function(F, F)> {
FindVisitor2(this.find, this.matcher);
final F find;
final M matcher;
} The former one relies on the treatment of methods with parameter types where a type variable occurs covariantly, and that treatment is well-known (e.g., it's used by The latter one relies on eliminating the "contravariant instance variable" by using a subtype requirement on the function type. This means that the For the treatment of the example as stated, I see an error with It is not an error to pass the function literal of type void main(List<String> arguments) {
FindVisitor(0, (int a, Function b) => true).matcher(1, 1); // Error: Can't pass an `int` to `Never`.
} I don't see anything here which isn't working as intended (except that we really need sound variance soon! ;-). |
Thank you for the detailed response and references! Closing issue. |
dart version: Dart SDK version: 2.15.1 (stable)
os: windows 10
I have a visitor class that accepts a matcher function as a parameter to enable custom comparison when searching for an object in a tree. Sometimes it is required to return a stricter type than the one it is searching for (but extends from it), and so I have two generics, one for the find type (
F
) and the other is the return type (R
).The issue is best seen with the following example:
When creating the visitor, I expected that the dart analyzer would be able to automatically detect the generic type for the matcher, but it is not. The curious thing is that if I hover over the definition I can see that the analyzer correctly detected the generics, but
a
andb
each have the typeObject?
instead ofint
for#1
. Thus, callinga.abs()
(orb.abs()
) is an error since it doesn't know it is of typeint
.Then, after creating this small example I found
#4
, where the anonymous declaration(int a, Function b)
doesn't throw an error saying thatb
cannot be of typeFunction
.Thus, I am wondering about the issues with
#1
not finding the types (yet they are when hovering...) and#4
not recognizing that the function type is invalid.The text was updated successfully, but these errors were encountered: