-
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
Where is void
allowed in pattern matching?
#2907
Comments
Sounds good! I guess the missing part in the current ruleset is that the matched value type can be I suspect that the following new rule would then suffice:
About the following rules:
As you mention, the first one is already partially covered: It is an error for an expression (including switch expressions, unless we specifically put them on the whitelist) to have type The second bullet should be covered fully (by the rule I mentioned above, and also by the third bullet), because the initial matched value type for the pattern in that if-case will then be Finally, I think |
This isn't going to make it into 3.0, but I also mostly don't think it matters much one way or the other. |
I was just playing around the the new patterns an came across a problem, which I think is related. void main() {
printFeature();
printBugs(1);
}
void printFeature() => print('feature');
void printBugs(int n) => switch (n) {
0 => print('no bugs'),
1 => print('one bug'),
_ => print('$n bugs'),
}; This without the
However the analyzer does not see this as an error and no red lines are shown. So at least the analyzer would have to report the error as well, but I think using a |
@Quijx The analyzer apparently doesn't recognize that it's not allowed. |
There are no analyzer or CFE errors in: void printBugs(int n) => n == 0
? print('no bugs')
: n == 1
? print('one bug')
: print('$n bugs'); Personally, I think it's reasonable to allow void-typed switch case expressions, and it's practically useful in examples like @Quijx's here. Sure, you could argue that a switch statement would be better, but we know empirically that users like using |
From dart-lang/sdk#52191
I assumed, with the same reasoning, that they would be disallowed. That said, tail position is usually where we allow My only worry is whether one switch case result having type So, LGTM allowing "expression switch case result expressions" to be |
I believe that the definition of UP that I cited in one of the issues talking about this guarantees this.
+1 |
🙃 This is a corner of the spec I'm not very familiar with and I didn't realize it was more like an allowlist. |
I think we can do it like this: #3026. |
We currently do not allow a
void
-typed expression to be used in a context where its value is used (only a context of typevoid
ordynamic
, anddynamic
was only allowed to not have to rewrite legacy code).We should consider whether
void
is allowed to flow into pattern matches.We are already doing something on some platforms, but we should be consistent and deliberate about it.
I'd say "hard no", and disallow (aka. make compile-time error):
switch
expression with static typevoid
.if
-case
matched value expression with static typevoid
.void
, unless the pattern is_
(or any other non-checking, non-binding pattern which also wouldn't need to look up the value of a list or map at all). That's needed forvar (x, _, z) = o as (int, void, int);
.The first two are really just expressions-in-position-where-value-is-used, and could be covered by current behavior.
The last one is new, because there is no expression the original program which has static type
void
. It only exists in the desugared version. Still, the is a value with static typevoid
which is pushed into a pattern match, and that pattern match actually looks at the value (it binds it to a new variable, one not typed asvoid
).We an allow a pattern to bind a
void
value to another variable of typevoid
ordynamic
, but you really shouldn't.I'd prefer to make the
void
protection stronger here, since it's new syntax that doesn't have to accommodate existing code.void
as the type of a binding pattern,void v
, to introduce avoid
-typed variable. Just use_
, because you are not supposed to look at the value later anyway.And
void
as the static type of an object pattern. (Also if doing so through a type alias, butT(:var hashCode)
is OK, even ifT
ends up bound tovoid
at runtime. This is just static checking.)Even though the object pattern
void()
is technically not looking at the object, it's also not useful, and you should just use_
.Doing
void(:var runtimeType)
is just plain wrong, you're invoking members on avoid
typed value. So(Now that we have
_
, we no longer need to allow you to assignvoid
values to anything. Or at least, we won't when we allow_
as a parameter name.)Example code:
This was run in dartpad.dev on master branch.
Dart2js rejects two of the cases, but not the third.
The analyzer gives no warnings whatsoever. (Should probably be considered a bug.)
@dart-lang/language-team
The text was updated successfully, but these errors were encountered: