-
Notifications
You must be signed in to change notification settings - Fork 208
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
Detect the following situation during compile time - not during runtime #3385
Comments
It would be better, but it's not possible in the current language. The only real solution to that would be to disallow such a field entirely. The real solution would be variance annotations on type parameters, so that |
OK, thanks for your answer. It pointed me to the following issue where this problem is discussed since a couple of years... |
@mahop-net, I just saw this again and noticed that I'd like to add a couple of comments: First, the basic issue is, as @lrhn mentioned, that You shouldn't have any of those because they are veritable run-time failure factories. You can vote for dart-lang/sdk#59050 if you want to help indicating that those members should be flagged as problematic at compile time. Next, here's how you can get the compile-time error that you mention: Source code, usable todayimport 'package:flutter/material.dart';
void main() {
runApp(const MainApp());
}
class MainApp extends StatelessWidget {
const MainApp({super.key});
@override
Widget build(BuildContext context) {
var anyClass = AnyClass<AnyItem>(
myFunction: (item) => item.getDouble(),
);
var d = anyClass.anyClass2.getValue(anyClass, AnyItem(value: 5.0));
return MaterialApp(
home: Scaffold(
body: Center(
child: Text("Hello $d"),
),
),
);
}
}
typedef Inv<X> = X Function(X);
typedef AnyClass<T> = _AnyClass<T, Inv<T>>;
class _AnyClass<T, Invariance extends Inv<T>> {
final double Function(T item) myFunction;
late AnyClass2<T> anyClass2;
_AnyClass({required this.myFunction}) {
anyClass2 = AnyClass2();
}
}
typedef AnyClass2<T> = _AnyClass2<T, Inv<T>>;
class _AnyClass2<T, Invariance extends Inv<T>> {
double getValue(AnyClass<T> c, T item) {
return c.myFunction(item);
}
}
class AnyItem {
double value;
AnyItem({required this.value});
double getDouble() {
return value;
}
} I put the working source code first because it's more actionable. However, some gnarly details in the source code above are just there in order to emulate invariance. If we get the feature statically checked variance that you also mention then it can be expressed as follows: Source code using statically checked variance// Using `--enable-experiment=variance`
import 'package:flutter/material.dart';
void main() {
runApp(const MainApp());
}
class MainApp extends StatelessWidget {
const MainApp({super.key});
@override
Widget build(BuildContext context) {
var anyClass = AnyClass<AnyItem>(
myFunction: (item) => item.getDouble(),
);
var d = anyClass.anyClass2.getValue(anyClass, AnyItem(value: 5.0));
return MaterialApp(
home: Scaffold(
body: Center(
child: Text("Hello $d"),
),
),
);
}
}
class AnyClass<inout T> {
final double Function(T item) myFunction;
late AnyClass2<T> anyClass2;
AnyClass({required this.myFunction}) {
anyClass2 = AnyClass2();
}
}
class AnyClass2<T> {
double getValue(AnyClass<T> c, T item) {
return c.myFunction(item);
}
}
class AnyItem {
double value;
AnyItem({required this.value});
double getDouble() {
return value;
}
} |
The code below throws the following runtime error on line 38:
Runtime Exception
_Exception has occurred.
TypeError (type '(AnyItem) => double' is not a subtype of type '(dynamic) => double')
It would be better, if the dart compiler detects this problem.
Problem can be solved by changeing line 37 to:
double getValue(AnyClass<T> c, T item) {
(Change parameter type
AnyClass
toAnyClass<T>
)Sample Code
Screenshot of Exception
The text was updated successfully, but these errors were encountered: