Skip to content

Migration tool improperly propagates non-nullability back via type-inferred variables. #38341

Description

@stereotype441

Consider the following code:

class C {
  int v;
  C(this.v);
}
f(C c) {
  var x = c.v;
  print(x + 1);
}
main() {
  C(null);
}

The migration tool currently migrates this to:

class C {
  int v; // (1)
  C(this.v);
}
f(C c) {
  var x = c.v; // (2)
  print(x + 1); // (3)
}
main() {
  C(null!); // (4)
}

What's happening is that since the use of x at (3) is guaranteed to fail if x is null, and that use post-dominates the declaration of x at (2), the tool infers that the type of x should be non-nullable. But since the type of x is inferred from the type of C.v, it propagates this non-nullability back to the declaration of C.v (at (1)). Which in turn means that null can't be validly passed to the C constructor at (4).

What should happen instead is that the back-propagation of non-nullability should stop at (2), allowing C.v to be nullable, so the migration would be:

class C {
  int? v; // (1)
  C(this.v);
}
f(C c) {
  var x = c.v!; // (2)
  print(x + 1); // (3)
}
main() {
  C(null); // (4)
}

Metadata

Metadata

Assignees

Labels

NNBDIssues related to NNBD Releasearea-migration (deprecated)Deprecated: this label is no longer actively used (was: issues with the `dart migrate` tool).

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions