Don't lint on raw types in constant patterns if the matched type is of type Type.

The issue does not have total consensus but I do feel strongly and the
fix was trivial and so I am just sending this out.

Feel free to push back if you feel strongly, or I should go through some
formal process.

Bug: https://github.com/dart-lang/sdk/issues/59334
Change-Id: I7c5e25e9754c4cebd427b8dc9ccfbe8daa57e71a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/510460
Auto-Submit: Jake Macdonald <jakemac@google.com>
Commit-Queue: Jake Macdonald <jakemac@google.com>
Reviewed-by: Phil Quitslund <pquitslund@google.com>
This commit is contained in:
Jake Macdonald
2026-06-10 08:23:43 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent 7d126dc14f
commit 7c3c71ae4d
4 changed files with 27 additions and 34 deletions
@@ -32,34 +32,6 @@ void f(Object x) {
void f(Object x) {
if (x case const (int)) {}
}
''');
}
Future<void> test_constType_matchType() async {
await resolveTestCode('''
void f(Type x) {
if (x case int) {}
}
''');
await assertHasFix('''
void f(Type x) {
if (x case const (int)) {}
}
''');
}
Future<void> test_constType_matchType_withImportPrefix() async {
await resolveTestCode('''
import 'dart:math' as math;
void f(Type x) {
if (x case math.Random) {}
}
''');
await assertHasFix('''
import 'dart:math' as math;
void f(Type x) {
if (x case const (math.Random)) {}
}
''');
}
}
+2
View File
@@ -3,6 +3,8 @@
- new lint: `unnecessary_const_in_enum_constructor`
- new lint: `unnecessary_type_name_in_constructor`
- stable: `unnecessary_null_checks`
- update `type_literal_in_constant_pattern` to ignore cases where the matched
pattern is of type `Type`.
# 3.12.0
@@ -47,6 +47,17 @@ class _Visitor extends SimpleAstVisitor<void> {
return;
}
// OK to use raw types if the matched value is of type Type.
var matchedValueType = node.matchedValueType;
if (matchedValueType != null &&
// Have to use `isSubtypeOf` to catch generic type parameters.
context.typeSystem.isSubtypeOf(
matchedValueType,
context.typeProvider.typeType,
)) {
return;
}
var expressionType = node.expression.staticType;
if (expressionType != null && expressionType.isDartCoreType) {
rule.reportAtNode(node);
@@ -62,9 +62,9 @@ void f(Object? x) {
}
test_constType_matchType() async {
await assertDiagnosticsFromMarkdown(r'''
await assertNoDiagnostics(r'''
void f(Type x) {
if (x case [!int!]) {}
if (x case int) {}
}
''');
}
@@ -78,9 +78,9 @@ void f(Type x) {
}
test_constType_matchType_nested() async {
await assertDiagnosticsFromMarkdown(r'''
await assertNoDiagnostics(r'''
void f(A x) {
if (x case A(type: [!int!])) {}
if (x case A(type: int)) {}
}
class A {
@@ -100,9 +100,17 @@ void f<T extends Object?>(T x) {
/// Nobody will write such code, but just in case.
test_constType_matchTypeParameter_boundType() async {
await assertDiagnosticsFromMarkdown(r'''
await assertNoDiagnostics(r'''
void f<T extends Type>(T x) {
if (x case [!int!]) {}
if (x case int) {}
}
''');
}
test_constType_matchTypeParameter_variable() async {
await assertNoDiagnostics(r'''
void f<T>() {
if (T case int) {}
}
''');
}