Skip to content

Remove obsolete null checks from style guide#181703

Merged
auto-submit[bot] merged 2 commits intoflutter:masterfrom
nate-thegrate:pre-null-safety-snippet
Mar 18, 2026
Merged

Remove obsolete null checks from style guide#181703
auto-submit[bot] merged 2 commits intoflutter:masterfrom
nate-thegrate:pre-null-safety-snippet

Conversation

@nate-thegrate
Copy link
Contributor

A couple of the style guide examples were written prior to Dart's null safety era, so this PR aims to update those examples.

Test-exempt because it only affects the .md file.

@github-actions github-actions bot added c: contributor-productivity Team-specific productivity, code health, technical debt. framework flutter/packages/flutter repository. See also f: labels. d: docs/ flutter/flutter/docs, for contributors labels Jan 30, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates code examples in the style guide to remove obsolete null checks, aligning them with modern null-safe Dart. The changes are generally good, but one of the examples is left in a state that is not valid under null safety. I've provided a suggestion to correct the example by using the required keyword for non-nullable named parameters, which makes the code valid and achieves the goal of removing the explicit null check.

@justinmc justinmc requested a review from Piinks February 3, 2026 23:38
Copy link
Contributor

@Piinks Piinks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for contributing some tweaks here.

Comment on lines 918 to 919
TheType get theProperty => _theProperty;
TheType _theProperty;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could see how TheType could be a nullable property. Maybe we should make it explicit as TheType?? I think it's a good example to have the assertion in the setter body.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this example _theProperty is non-nullable, but you're right that the property could just as easily have been created as a nullable one.

However, I don't think it's good to have the assertion in the setter body; based on how this example is currently written, there's no way for the non-nullable value to be null.

Copy link
Contributor

@Piinks Piinks Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. What I was suggesting was that you update this to be an explicitly nullable type to remove the ambiguity and keep the assertion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, so then it would look like this:

TheType? get theProperty => _theProperty;
TheType? _theProperty;
void set theProperty(TheType? value) {
  assert(value != null);
  if (_theProperty == value) {
    return;
  }
  _theProperty = value;
  markNeedsWhatever(); // the method to mark the object dirty
}

This would work, though it has the downside of being a bit more verbose. (In my opinion, being concise & readable is even more important in the style guide than anywhere else in this repo.)

Is there a downside to how I have it currently?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the other example, I would consider the intention of the guidance here. This is about providing guidelines for performing dirty checks in setters. Does this change improve on that guidance? IMO, I don't think verbosity is a bad thing in docs meant to educate for working on the framework.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, I don't think verbosity is a bad thing in docs meant to educate for working on the framework.

I suppose we could agree to disagree here. There's a good reason "TL;DR" is so prevalent throughout the internet: if something is more verbose, the opportunity cost of reading & understanding is higher, ergo people become less likely to do it. In the case of this example, removing irrelevant code is a straight improvement IMO.

I really appreciate the time you've spent helping me out here. Since this PR would require two approvals to merge, maybe now would be a good time for another reviewer to step in with a fresh perspective.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a good reason "TL;DR" is so prevalent throughout the internet: if something is more verbose, the opportunity cost of reading & understanding is higher, ergo people become less likely to do it. In the case of this example, removing irrelevant code is a straight improvement IMO.

I am not sure this is really relevant. This is a change specifically within the context of the Flutter org. Not the internet at large. :)

I will leave this to another reviewer to make a pass. Honestly, I don't know this change is worth this much debate.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that this example should change one way or another, because the assertion is no longer necessary and could confuse people. Also, the assertion is not important to this section of the style guide. My interpretation of the two options are:

Option 1:

TheType _theProperty;
void set theProperty(TheType value) {
-   assert(value != null);
  if (_theProperty == value) {
    return;
  }
  _theProperty = value;
  markNeedsWhatever(); // the method to mark the object dirty
}

Option 2:

-TheType _theProperty;
+TheType? _theProperty;
-void set theProperty(TheType value) {
+void set theProperty(TheType? value) {
  assert(value != null);
  if (_theProperty == value) {
    return;
  }
  _theProperty = value;
  markNeedsWhatever(); // the method to mark the object dirty
}

I like option 1. Option 2 is oddly specific and could distract from the point of this section. You might do something like it if _theProperty was supposed to be null during initialization or something and then never nonnull again... but then why assert instead of making the setter nonnullable? These are questions that the reader shouldn't be thinking about :)

/// The [bar] argument allows the baz to quux.
///
/// The `baz` argument must be greater than zero.
Foo({ this.bar, int baz }) : assert(bar != null), assert(baz > 0);
Copy link
Contributor

@Piinks Piinks Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These could also be nullable, the sample code here does not provide enough information to determine if they are or not. IMO, I think this one is ok as is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree here as well: the best practice is to avoid null-asserts in constructors.

class Foo {
  Foo({this.bar}) : assert(bar != null); // BAD

  Object? bar;
}

Let's say that bar is a nullable field but you still want the constructor argument to be non-nullable. You could do it like so:

class Foo {
  Foo({required Object this.bar}); // GOOD

  Object? bar;
}

It's much better for null-safety to be enforced by a type annotation than by using an assert, since the latter makes it much easier for mistakes to go unnoticed until runtime.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I think we might be over-indexing on code that lacks enough context to actually suggest this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough haha

But the point I was trying to make is: validating a constructor argument with an assert(bar != null) is never a good practice, so I'd like this example to be changed to reflect that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I appreciate you want to make the code snippet as accurate as possible. Given that this code snippet is meant to facilitate guidance around documenting parameters, and not to illustrate best practices around unnecessary null-asserts, does this change improve on the intended guidance?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it does!

Originally, this example documentation said:

  /// The [bar] argument must not be null.

At the time it was written, there wasn't a good way to enforce that a non-null argument is passed into a class constructor, so the best practice was to include this advice where applicable.

But thanks to null safety, this advice is no longer warranted: setting the class member as non-nullable means that static analysis will enforce it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that assert(bar != null) should go since it is not best practice. I don't want to confuse users or LLMs that might read it.

nate-thegrate

This comment was marked as resolved.

@justinmc justinmc requested review from Piinks and justinmc February 17, 2026 23:58
github-merge-queue bot pushed a commit that referenced this pull request Feb 25, 2026
The conversation in #181703 got me thinking about whether there were any
`assert(value != null)` statements in our codebase that were written
prior to Dart's null safety era and could be factored out.

It turns out that there are!

This PR updates a few setters so that incorrect `null` assignments are
caught by static analysis instead of potentially going unnoticed until
runtime.

Co-authored-by: Victor Sanni <[email protected]>
Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍 . I say let's update these to modern Dart and move on, no need to debate these too much. Even if the examples aren't perfect they will now avoid being outdated.

Comment on lines 918 to 919
TheType get theProperty => _theProperty;
TheType _theProperty;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that this example should change one way or another, because the assertion is no longer necessary and could confuse people. Also, the assertion is not important to this section of the style guide. My interpretation of the two options are:

Option 1:

TheType _theProperty;
void set theProperty(TheType value) {
-   assert(value != null);
  if (_theProperty == value) {
    return;
  }
  _theProperty = value;
  markNeedsWhatever(); // the method to mark the object dirty
}

Option 2:

-TheType _theProperty;
+TheType? _theProperty;
-void set theProperty(TheType value) {
+void set theProperty(TheType? value) {
  assert(value != null);
  if (_theProperty == value) {
    return;
  }
  _theProperty = value;
  markNeedsWhatever(); // the method to mark the object dirty
}

I like option 1. Option 2 is oddly specific and could distract from the point of this section. You might do something like it if _theProperty was supposed to be null during initialization or something and then never nonnull again... but then why assert instead of making the setter nonnullable? These are questions that the reader shouldn't be thinking about :)

/// The [bar] argument allows the baz to quux.
///
/// The `baz` argument must be greater than zero.
Foo({ this.bar, int baz }) : assert(bar != null), assert(baz > 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that assert(bar != null) should go since it is not best practice. I don't want to confuse users or LLMs that might read it.

ahmedsameha1 pushed a commit to ahmedsameha1/flutter that referenced this pull request Feb 27, 2026
The conversation in flutter#181703 got me thinking about whether there were any
`assert(value != null)` statements in our codebase that were written
prior to Dart's null safety era and could be factored out.

It turns out that there are!

This PR updates a few setters so that incorrect `null` assignments are
caught by static analysis instead of potentially going unnoticed until
runtime.

Co-authored-by: Victor Sanni <[email protected]>
xxxOVALxxx pushed a commit to xxxOVALxxx/flutter that referenced this pull request Mar 10, 2026
The conversation in flutter#181703 got me thinking about whether there were any
`assert(value != null)` statements in our codebase that were written
prior to Dart's null safety era and could be factored out.

It turns out that there are!

This PR updates a few setters so that incorrect `null` assignments are
caught by static analysis instead of potentially going unnoticed until
runtime.

Co-authored-by: Victor Sanni <[email protected]>
@AbdeMohlbi AbdeMohlbi self-requested a review March 11, 2026 17:19
@nate-thegrate nate-thegrate force-pushed the pre-null-safety-snippet branch from 04cd59e to c0ab8ae Compare March 12, 2026 00:08
nate-thegrate and others added 2 commits March 17, 2026 18:01
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@Piinks Piinks force-pushed the pre-null-safety-snippet branch from c0ab8ae to 38ce8f7 Compare March 17, 2026 23:01
@Piinks Piinks added CICD Run CI/CD autosubmit Merge PR when tree becomes green via auto submit App labels Mar 17, 2026
@auto-submit auto-submit bot added this pull request to the merge queue Mar 17, 2026
Merged via the queue into flutter:master with commit 668514e Mar 18, 2026
14 checks passed
@flutter-dashboard flutter-dashboard bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Mar 18, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 18, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 18, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 18, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 18, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 18, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 18, 2026
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Mar 19, 2026
flutter/flutter@d117642...dd64978

2026-03-18 [email protected] Roll Skia from 2fb5fa71eb12 to f0a13e5efbad (2 revisions) (flutter/flutter#183830)
2026-03-18 [email protected] Roll Skia from ae3d36cb9e29 to 2fb5fa71eb12 (3 revisions) (flutter/flutter#183823)
2026-03-18 [email protected] Linux reuse sibling (flutter/flutter#183653)
2026-03-18 [email protected] Roll Skia from 84a180a1fa80 to ae3d36cb9e29 (4 revisions) (flutter/flutter#183812)
2026-03-18 [email protected] fix(web): handle asynchronously disposed platform views (flutter/flutter#183666)
2026-03-17 [email protected] (Test cross-imports) Remove legacy Material import from sliver_constraints_test (flutter/flutter#183351)
2026-03-17 [email protected] Fix Android Studio pluginsPath when version is unknown (do not use 0.0) (flutter/flutter#182681)
2026-03-17 [email protected] Fixes animation glitch into bottom sheet (flutter/flutter#183303)
2026-03-17 [email protected] Handle#6537 second grouped test (flutter/flutter#182529)
2026-03-17 [email protected] Add a Clarification for the docs of suggestionsBuilder of SearchAnchor (flutter/flutter#183106)
2026-03-17 [email protected] Remove obsolete null checks from style guide (flutter/flutter#181703)
2026-03-17 [email protected] [Impeller] Do not delete the GL object in a HandleGLES if the handle has a cleanup callback (flutter/flutter#183561)
2026-03-17 [email protected] Encode source file patches as UTF-8 in the code formatter script (flutter/flutter#183761)
2026-03-17 [email protected] Fix widget inspector control layout and add safe area regression test (flutter/flutter#180789)
2026-03-17 [email protected] Reland "[Android] Add mechanism for setting Android engine flags via Android manifest (take 2)" (flutter/flutter#182522)
2026-03-17 [email protected] fix(web): fix crash in Skwasm when transferring non-transferable texture sources (flutter/flutter#183799)
2026-03-17 [email protected] Roll Skia from dba893a44d7a to 84a180a1fa80 (7 revisions) (flutter/flutter#183803)
2026-03-17 [email protected] Framework: Improve DropdownButton selectedItemBuilder assertion (flutter/flutter#183732)
2026-03-17 [email protected] Add mainAxisAlignment to NavigationRail (flutter/flutter#183514)
2026-03-17 [email protected] Update android triage process to not look at unassigned p1s every week (flutter/flutter#183805)
2026-03-17 [email protected] Adds macos impeller new gallery transition perf test. (flutter/flutter#183802)
2026-03-17 [email protected] fix(web_ui): move prepareToDraw after raster to improve concurrency and stability (flutter/flutter#183791)
2026-03-17 [email protected] [build] Generate debug info for assembly. (flutter/flutter#183425)
2026-03-17 [email protected] [web] Fix occasional failure to find Chrome tab (flutter/flutter#183737)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC [email protected],[email protected] on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c: contributor-productivity Team-specific productivity, code health, technical debt. CICD Run CI/CD d: docs/ flutter/flutter/docs, for contributors framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants