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

[breaking change] Discontinue non-null-safe mode #49530

Closed
9 tasks done
mit-mit opened this issue Jul 26, 2022 · 11 comments
Closed
9 tasks done

[breaking change] Discontinue non-null-safe mode #49530

mit-mit opened this issue Jul 26, 2022 · 11 comments
Assignees
Labels
area-meta Cross-cutting, high-level issues (for tracking many other implementation issues, ...). enhancement-breaking-change An enhancement which is breaking.

Comments

@mit-mit
Copy link
Member

mit-mit commented Jul 26, 2022

Dart 3 & discontinuation of support for non-sound null safety

Background

In the Dart 2.12 release, Dart introduced sound null safety. When this was introduced we used an opt-in model: Only code that was opting into language version 2.12 or later was run with null safety. Dart developers could migrate their code in a stepwise fashion.

We are now planning a Dart 3 release -- tentatively slated for release by mid-2023 -- where we plan on only supporting Dart code that uses full sound null safety. This means that the null safety legacy mode will be discontinued, and that all code must run with full sound null safety.`

The reasons for making this change are:

  • Supporting both unsound and sound null safety adds overhead and complexity. Dart developers need to learn and understand both modes. Whenever reading a piece of Dart code, you need to check the language version to see if types are non-null by default (2.12 and later) or nullable by default (versions below 2.12)

  • Having to support both modes in our compilers and runtimes slows us down in terms of evolving the Dart SDK to support new features.

  • Our statistics on both packages on pub.dev and the null safety mode in which Flutter apps run, show that the ecosystem has largely already migrated to full sound null safety, and thus is ready to turn off unsound null safety/legacy mode.

Everything uses sound null safety in Dart 3

In Dart 3, only sound null safety is supported.
Concretely this implies that Dart 3 will not support:

  1. Code using an SDK constraint where the min-constraint isn't at least 2.12 (e.g. sdk: ">=2.7.0" will be disallowed and won't resolve).

  2. Libraries using per-library language version markers selecting versions less than 2.12 (e.g. // @dart=2.9 will be disallowed).

Backwards compatibility for null safe packages

Dart 3 sound null safety will be backwards compatible with with code already migrated to use null safety in language versions 2.12 and later.

This means that a Dart 3.0 SDK will allow SDK constraints where the lower-bound is at least 2.12, even when the SDK upper-bound only allows versions less than 3 (<3.0). For example, a package with the following constraint will be allowed to resolve with a Dart 3.x SDK:

environment:
  sdk: '>=2.12.0 <3.0.0'

This allows developers to use Dart 3 sound null safety with packages that have been migrated to 2.12 null safety.

Note that Dart 3 may contain other breaking changes. For example some core library APIs are discontinued in Dart 3, which may mean that some packages may not be compatible with Dart 3 even if they have migrated to null safety with 2.12. We'll release a Dart 3 alpha release (see below) that can be used to test if code is affected by any of these breaking changes.

Roll out plan

We expect to roll out a Dart 3 alpha release several months prior to Dart 3 stable. This release will allow for testing if a package or app is compatible with Dart 3. The alpha release is not likely to contain other Dart 3 feature work unrelated to sound null safety, but will contain all planned breaking changes.

Later we also plan on releasing a Dart 3 beta release that is more feature complete.

Finally, we'll release the Dart 3.0 stable release, tentatively by mid-2023.

Work item tracking

Dart 2.19 stable, and associated Flutter stable

Dart 3 alpha

Dart 3 beta

@mit-mit mit-mit self-assigned this Jul 26, 2022
@mit-mit mit-mit added enhancement-breaking-change An enhancement which is breaking. area-meta Cross-cutting, high-level issues (for tracking many other implementation issues, ...). labels Jul 26, 2022
@mit-mit mit-mit changed the title Discontinue non-null-safe mode [breaking change] Discontinue non-null-safe mode Jul 26, 2022
@goderbauer
Copy link
Contributor

Once this has happened we want to clean up some null asserts in Flutter that we have kept around to support non-null-safe app code. Please keep us in the loop about Dart's plan in this area :)

@Cat-sushi
Copy link

Should SDK 2.19.0 or later version warn using unsound null safety or null unsafety mode?

@mit-mit
Copy link
Member Author

mit-mit commented Sep 1, 2022

Should SDK 2.19.0 or later version warn using unsound null safety or null unsafety mode?

Hi @Cat-sushi, yes, we were just discussing that yesterday, and we agree it should. The checklist has been updated to include this.

@adrianvintu
Copy link

Can anyone advise? I have two projects, each containing 300+ classes. Just turning on SDK 2.19 more than 3000 compile issues. The work required to fix 3000+ issues per project, and more arising, is waaaaay more than a person can handle in any reasonable time amount.

Do you have any suggestions? Maybe make a migration tool that sets all questionable variables to nullables? And each access to ! ?

Clazz? some nullableDeclaration;

nullableDeclaration = new Clazz();

nullableDeclaration!.accesSomething();

Would this make sense?

I read somewhere there is already a migration tool, but it is buggy, or something like that.

@mit-mit
Copy link
Member Author

mit-mit commented Oct 14, 2022

Can anyone advise? I have two projects, each containing 300+ classes. Just turning on SDK 2.19 more than 3000 compile issues. The work required to fix 3000+ issues per project, and more arising, is waaaaay more than a person can handle in any reasonable time amount.

Please see the steps here in this guide. You are not expected to do this manually.
https://dart.dev/null-safety/migration-guide

This includes instructions on how to use the null safety migration tool. This tool has successfully migrated millions of lines of code by now, so while I can't rule out potentially hitting an issue, it should have a pretty good chance of working.

@adrianvintu
Copy link

@mit-mit Thank you so much for your info. I used the migrations tool, and it changed 90% of the files - an amazing number, imho.

I started fixing the compile issues - hundreds of them.

Then tried to start the app - it crashed a lot because of nulls.

I am now left with 700 warnings and forced to test ALL paths of the app code - a truly gargantuan task.

I found some bugs(?):

  • the migration tool does not really understand the code and adds ? and ! wrongly many times
  • this is no longer possible var widgets = <Widget>[]..length = 1; type 'Null' is not a subtype of type 'Widget' in type cast I understand this is not related to migration
  • some type inference may be gone:
    this used to work
    List<DateTime> dates = _aggregateJsonByLabelGeneric(json, tagDate) as List<DateTime>;
    where _aggregateJsonByLabelGeneric is defined as
List<T>? _aggregateJsonByLabelGeneric<T>(List<Map<String, dynamic>>? json, String label) {
    List<T>? list = [];
    return list; //now  returns List<dynamic> because T is now dynamic, not DateTime

now I have to specify
List<DateTime> dates = _aggregateJsonByLabelGeneric<DateTime>(json, tagDate) as List<DateTime>;
I understand this is not related to migration

To put it short:

  1. small project, 300+ classes
  2. migrated, touched 90% of the files
  3. a lot of automated migration errors ? and !
  4. my own errors when correcting and misunderstand ? and !
  5. a lot of hours getting to compile the code
  6. waaaay more hours trying to test EACH path of the code - crazy
  7. left with 700 warnings to fix - crazy
  8. blocked now, cannot release app for a week until full testing complete
  9. app quality will probably decrease because crashing will probably increase

I cannot even imagine what happens when a really big application is forced to migrate...

Please consider these points when deciding to discontinue support. Maybe move this to 2055? :)

Thank you again for your support!

@Levi-Lesches
Copy link

I personally did not use dart migrate on my project because it was small enough to do it by hand. My suggestions:

  • Avoid ! at almost any cost (except maybe for instances where if (x.y != null) doesn't promote y). ! introduces runtime errors whereas the lack of ! will be a compiler error. This dramatically reduces the need for manual testing. When I do use a !, I make sure to always leave a comment justifying it.
  • Use gradual migration for now, which should help make overall migration go smoother and faster
  • Override the migration tool when needed by adding hint markers. Correcting the tool in one line of code allows it to better reason about the rest of your program

@mit-mit
Copy link
Member Author

mit-mit commented Oct 24, 2022

@adrianvintu if your app passes full analysis (flutter analyze) with no errors or warnings prior to running the migration, I'd very surprised to see hundred of errors. If that is really the case, can you please file a new issue with as many details as possible (preferably with some actual code examples) ?

I think you may have the wrong mental model about the migration based on a comment like "this is no longer possible var widgets = []..length = 1; type 'Null' is not a subtype of type 'Widget' in type cast I understand this is not related to migration".

With null safety, variables are non-nullable by default. So <Widget>[] means "create a list containing non-null Widget objects". When you then call .length on that to expand it beyond its existing length, null entries are added. That is a violation of the type, which is non-null Widget. For details, see the comments in list.length.

@adrianvintu

This comment was marked as off-topic.

@mit-mit
Copy link
Member Author

mit-mit commented Oct 26, 2022

@adrianvintu and others, if you are having migration issues, please file new issues, and we'll see if we can help.

The present issue is meant to track the overall effort for discontinuing non-null-safe mode, which remains planned for 2023.

@mit-mit
Copy link
Member Author

mit-mit commented Jan 31, 2023

Dart 3 alpha is now available, which the non-null-safe mode disabled:
https://dart.dev/get-dart/archive#dart-3-alpha

For instructions regarding testing for Dart 3 compatibility, see:
https://dart.dev/null-safety#dart-3-and-null-safety

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-meta Cross-cutting, high-level issues (for tracking many other implementation issues, ...). enhancement-breaking-change An enhancement which is breaking.
Projects
None yet
Development

No branches or pull requests

6 participants