linter: collection_methods_unrelated_type: Null not related to non-nullable

Fixes https://github.com/dart-lang/sdk/issues/57101

This change affects collection_methods_unrelated_type and
unrelated_type_equality_checks. For example these are now reported:

```dart
void f(Set<String> p1, int p2) {
  p1.contains(null);
  p2 == null;
}
```

Change-Id: Ib58bad2beb6b9df8fe7c71f27213055e9b8d5cb9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/489481
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
Sam Rawlins
2026-05-13 07:03:42 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent e09282c8f2
commit 57da93ad4f
2 changed files with 38 additions and 1 deletions
@@ -182,6 +182,12 @@ bool typesAreUnrelated(
}
var promotedLeftType = typeSystem.promoteToNonNull(leftType);
var promotedRightType = typeSystem.promoteToNonNull(rightType);
if (leftType.isDartCoreNull && typeSystem.isNonNullable(rightType)) {
return true;
}
if (rightType.isDartCoreNull && typeSystem.isNonNullable(leftType)) {
return true;
}
if (promotedLeftType == promotedRightType ||
typeSystem.isSubtypeOf(promotedLeftType, promotedRightType) ||
typeSystem.isSubtypeOf(promotedRightType, promotedLeftType)) {
@@ -65,7 +65,23 @@ var x = <M>[].contains(C());
}
test_contains_related_null() async {
await assertNoDiagnostics('var x = <num>[].contains(null);');
await assertNoDiagnostics('var x = <num?>[].contains(null);');
}
test_contains_related_null_genericNullable() async {
await assertNoDiagnostics('''
bool f<T extends Object?>() {
return <T>[].contains(null);
}
''');
}
test_contains_related_null_genericNullable2() async {
await assertNoDiagnostics('''
bool f<T extends Object>() {
return <T?>[].contains(null);
}
''');
}
test_contains_related_Object() async {
@@ -164,6 +180,21 @@ abstract class C implements List<num> {
);
}
test_contains_unrelated_null() async {
await assertDiagnostics('var x = <num>[].contains(null);', [lint(25, 4)]);
}
test_contains_unrelated_null_generic() async {
await assertDiagnostics(
'''
bool f<T extends Object>() {
return <T>[].contains(null);
}
''',
[lint(53, 4)],
);
}
test_contains_unrelated_recordAndNonRecord() async {
await assertDiagnostics("var x = <(int, int)>[].contains('hi');", [
lint(32, 4),