-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Analyzer and compiler should check type mismatch error for if null operator #34710
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
Comments
The missing analyzer error is caused by a "zigzag cast" from You can avoid this issue by taking away the permission to do a downcast at all (e.g., passing |
Why does a zigzag cast need to occur at all? I would expect "T t = a ?? b" to be shorthand for "T t = a != null ? a : b", which in turn would be shorthand for this: T t;
if (a != null)
t = a;
else
t = b; The first two idioms involve this zigzag cast and the resulting lack of an analyzer error, but the third does not. This language idiosyncrasy encourages developers to always use the more elaborate longhand structure, which is truly unfortunate. (I'm currently in the middle of a lengthy refactoring effort, and it has become significantly more complicated because I can't rely on the analyzer to help me with type mismatches of this nature.) |
As you mention, You can't eliminate the type of an expression like This means that the idea you mention (which is to eliminate the conditional expression by transforming one assignment into several statements) may work in some contexts, but not all, and it would surely introduce a surprising and inhomogeneous static analysis if we were to treat conditional expressions like a shorthand for several statements in some cases, and like an expression in its own right in others. |
I don't think I'm suggesting the type of an expression be eliminated. I had a bit of an insight while reading your response though. Perhaps this will explain my thinking more clearly, and maybe help me understand your response better. In the last transformation I introduced above, the type of T is determined not by the types of the contents of the expression, but by the context in which the expression is evaluated. Taking your example of T result;
if (b)
result = e1;
else
result = e2;
return result; Here both e1 and e2 need to match the return type Equivalently, in the third example above, the type If I understand correctly, what Dart does instead is find the common supertype of My suggestion is that the type analysis be done on each branch of the expression independently rather than on the combination. I grant that it will get complicated with more complex expressions, but I believe it is deterministic, and seems strictly better than the current behavior that appears to me to be throwing away type safety for a very common language idiom. (It would also be an API breaking change, but my suspicion is that any code affected by this represents a bug anyway.) While I was playing around with these concepts I ran into what seems like a similar issue. The following code gives no analyzer warnings but throws at runtime: print(1 as String); Does this behavior have the same underlying cause or is it a separate issue? |
I think this is the core issue, and it's also what I referred to when I said that it will be complex (and, on top of that, we'll have to give up on that approach at some point, which makes the static analysis inhomogeneous in this respect). So the exploration of this idea might be useful (and I do admit that we'd get better typings in some cases), but I tend to be sceptical about its scalability. Also, I do think that developers will pay for language complexity in the sense that they'll have to understand more arcane rules and exceptions for every single expression or statement that they are writing, so even if we get better typings here and there it might not be a net positive if it makes the whole language more difficult to work with everywhere else.
Cf. #25368 and #34058: The case where a conditional expression involves a least upper bound that yields a top type (like
This, being an explicit cast, is exclusively the responsibility of the developer who wrote it. We could use exact types (#33307) to determine that this particular cast will definitely fail at run time. But I think it makes sense, as a general rule, to trust developers when they make the choice to explicitly claim that they know a certain expression has a certain type. After all, we know that no type system can understand the actual semantics of a program in any non-trivial language. |
analyzer should show type mismatch error since it has enough type information.
already checked for two versions:
The text was updated successfully, but these errors were encountered: