-
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
Switch expression always needs assignment #60019
Comments
Also, something weird (not actual code, just trying around): final _ = switch (direction) {
Direction.none => animationController.animateTo,
Direction.left => (
v, {
Duration? duration,
Curve curve = Curves.linear,
}) =>
animationController.forward(from: v),
Direction.right => (v, {
Duration? duration,
Curve curve = Curves.linear,
}) => animationController.reverse(from: v),
}(0); This has a warning when passing But when you hover at the closing And at both So the hover must be wrong or the diagnostics should not be there. |
The problem with the first example is that a switch expression is not allowed to appear at the beginning of an expression statement. It will always be interpreted to be a switch statement, hence the requirement for a You can get around the restriction by enclosing the switch expression in parentheses. I'm not entirely certain what the problem is with the second example. I can't reproduce what you're seeing, so it might have something to do with the way the undefined names are defined. |
I've copied the signatures and made a test on pure Dart (no Flutter), so now you can reproduce it. Here is a full example: enum Direction { none, left, right }
void foo(Direction direction) async {
await (switch (direction) {
Direction.none => _doNothing,
Direction.left => (v) => _doThis(from: v),
Direction.right => (v) => _doThat(from: v),
})(0);
}
Future<void> _doThis({ double? from }) async {}
Future<void> _doThat({ double? from }) async {}
Future<void> _doNothing(
double target, {
Duration? duration,
int curve = 0,
}) async {} Even if you add While only one ( Now when all of the above have the full signature this is the expression type: But for some weird reason, inside the expression, on the declarations of |
Here is an easy check: Change I don't see any warnings or error messages, not even when this example is analyzed on the command line with Anyway, the fact that This is the rule that applies when the function literal does not have a context type (that is, the context type is In this case, we have an expression of the form However, the resulting type of So it's all working as intended. Moreover, I don't see an easy way to adjust type inference (in particular, function literal return type inference) such that the type of |
I think not being able to infer the type of Simpler example: void main() {
int id(int x) => x;
var f = (v) => id(v);
print([f].runtimeType); // List<dynamic => int>
} Parameter inference for functions does not try to find hints in the function body. It either gets a type from the context (this doesn't have a useful context type), or it uses Having an argument is not introducing a context. Even simpler example; void main() {
((v) { print([v].runtimeType); }(0)); // List<dynamic>
} Without a context type, function expression parameters need to be typed. The To give a context, you can do: void foo(Direction direction) async {
Future<void> Function(double) todo = switch (direction) {
Direction.none => _doNothing,
Direction.left => (v) => _doThis(from: v),
Direction.right => (v) => _doThat(from: v),
};
await todo(0);
} Or just write |
Oh, I see. I figured it would type the same as the whole expression. Thank you both for the detailed explanations! I didn't realize that the Function literal had nothing to bind the expected type to, so I figured it would infer from the other switch cases, but this makes more sense. |
I'm unsure if this is intended. If you have the following code:
I was expecting the
();
at the end of theswitch
to work as a startingreturn
or assignment would. But as of right now, this is the output:So I can't even use the quick-fix to create any of the functions because it expects a
case
keyword before the firstDirection
. Is this wrong or is specified somewhere? If this is expected, could we change this to allow this case?The text was updated successfully, but these errors were encountered: