Skip to content

Null Safety requires an explicit cast when casting a num to an int #971

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

Closed
a-siva opened this issue Jan 28, 2020 · 8 comments
Closed

Null Safety requires an explicit cast when casting a num to an int #971

a-siva opened this issue Jan 28, 2020 · 8 comments

Comments

@a-siva
Copy link

a-siva commented Jan 28, 2020

When migrating the below code to NNBD using pkg/dev_compiler/tool/check_nnbd_sdk.dart tool, the analyzer produces a warning (requires an explicit cast)

const int DAYS_IN_4_YEARS = 4 * 365 + 1;	
const int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1;
const int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1;
const int DAYS_IN_400_YEARS = 4 * DAYS_IN_100_YEARS + 1;
const int daysSince1970 = 200;
const in DAYS_IN_400_YEARS
int days = daysSince1970;
days = days.remainder(DAYS_IN_400_YEARS);

ERROR|STATIC_TYPE_WARNING|INVALID_ASSIGNMENT|lib/core/core.dart|2092|12|33|A value of type 'num' can't be assigned to a variable of type 'int'.

It requires the user to do an explicit cast which can be inefficient.

We need a mechanism that would not require the user to make an explicit cast here.

@stereotype441
Copy link
Member

I believe the analyzer is correctly implementing the language specification here, since the declared return type of remainder is num, and implicit downcasts are not allowed with NNBD. So I'm reclassifying as a language issue. @leafpetersen FYI

@a-siva
Copy link
Author

a-siva commented Jan 28, 2020

Yes the analyzer is following the spec here, the issue of no implicit downcasts with NNBD makes code that was clean before to start issuing warnings and people might go and fix their code by adding explicit casts that could potentially have performance implications.

@srawlins srawlins changed the title Analyzer warnings when using the remainder function Null Safety requires an explicit cast when casting a num to an int May 13, 2020
@srawlins
Copy link
Member

I'll move this to the language repo since the "area-language" tag is marked deprecated; new issues should go to that repo.

@srawlins srawlins transferred this issue from dart-lang/sdk May 18, 2020
@leafpetersen
Copy link
Member

@lrhn I know you had some thoughts about this. Do you think it's worth trying to specify something better here? I'm pretty maxed out at the moment.

@natebosch
Copy link
Member

I know that implicit vs explicit casts have a difference in dart2js depending on the flags, my understanding is that omitting implicit casts is a performance optimization that introduces potential unsoundness. Is there any documentation that expresses why an implicit cast has better performance than an explicit cast on the VM? Does it introduce potential unsoundness there?

@leafpetersen
Copy link
Member

Whether there's a performance issue or not, it's definitely a pain point. And if we can soundly eliminate the need for the cast (e.g by encoding into static analysis the fact that int.remainder(int) is in fact an int), then there's an overall win.

@eernstg
Copy link
Member

eernstg commented May 19, 2020

We have actually discussed some ideas for features of that nature, for instance case functions (#148):

class int implements num {
  ...
  num remainder(num other) {
    int case(int i) => ...;
    double case(double d) => ...;
    default => ...; // Implicitly gets signature `num Function(num n)`.
  }
}

The point is that the cases are part of the signature of the function, and a call site can commit to a specific case, so if we call remainder with an int on an int, we can commit to int case(int i) at compile-time for that call site.

@lrhn
Copy link
Member

lrhn commented Aug 5, 2020

We have decided that remainder will also be special-cased in the language specifiction, along with the other binary operators on num which return num.

@lrhn lrhn closed this as completed Aug 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants