Skip to content
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

Ternary operator type checking #35283

Closed
blackmenthor opened this issue Nov 29, 2018 · 1 comment
Closed

Ternary operator type checking #35283

blackmenthor opened this issue Nov 29, 2018 · 1 comment
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). type-enhancement A request for a change that isn't a bug

Comments

@blackmenthor
Copy link

Thank you for taking the time to file an issue!

In order to route, prioritize, and act on this, please include:

  • Dart version 2.1.0-dev.5.0.flutter-a2eb050044
  • MacOSX
  • on Flutter version 0.9.4

So i accidentally wrote this code

int point = snapshot.hasData ? snapshot.data < 0 ? "-" : snapshot.data : "-";

and somehow i able to insert a string value to the int variable and it produced no error whatsoever. But, when it ran on the users phone it produce error

_TypeError
type '_OneByteString' is not a subtype of type 'int'

I think somehow dart think that this expression will not produced an error so it compiles successfully.

But in fact it will produced an error because i inserted a string value to an int.

Or maybe the problem lies on Android studio that i used?


@lrhn lrhn added area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). type-enhancement A request for a change that isn't a bug labels Nov 29, 2018
@eernstg
Copy link
Member

eernstg commented Nov 30, 2018

This is a known issue with (1) the typing of a conditional expression (it's a least-upper-bound-ish result of combining the types of the two branches) and (2) an implicit downcast.

Given that you're using snapshot.data < 0 to make a decision it seems likely that the type of snapshot.data is int (but it could also be dynamic). The static type of the initializing expression is then a top type, that is, a type which is a supertype of all other types (if snapshot.data has type dynamic then that's it, but if data has type int then we get Object). In any case, it is a supertype of int.

Then you're using that expression to initialize a variable of type int, and the compiler notes that there is a downcast and generates code for a dynamic check.

If you had used something like int x = "hello"; then you would have had an error, because that's not a downcast.

If you want to prevent implicit downcasts then you can use option --no-implicit-casts. There's lively debate about making that setting the default (#31410) for Dart.

This particular situation is a well-known worst case for implicit casts, because there's an upcast to a top type like dynamic or Object, and then a downcast. And that downcast is considered viable for all target types, because they are all subtypes thereof. See #25368 and #34058 for earlier issues where this is discussed.

I'll close this one as a duplicate of #25368, such that this discussion can be kept in one place.

@eernstg eernstg closed this as completed Nov 30, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

3 participants