Skip to content

Commit a6edca6

Browse files
srawlinsCommit Queue
authored and
Commit Queue
committed
Only report unnecessary_cast when the cast type is exactly the static type
Fixes #44411 Fixes #48984 Fixes #49269 Fixes #49550 Fixes #52086 The "prefer type annotations on local variables over upcasting" that this used to cover can be covered with a new lint rule: https://github.com/dart-lang/linter/issues/3786 Change-Id: I6a112732269e918a7faacc399bccebe13de8462d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/265420 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Samuel Rawlins <[email protected]>
1 parent 7ba47c6 commit a6edca6

File tree

5 files changed

+19
-85
lines changed

5 files changed

+19
-85
lines changed

pkg/analyzer/lib/src/error/best_practices_verifier.dart

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import 'package:analyzer/dart/ast/token.dart';
1111
import 'package:analyzer/dart/ast/visitor.dart';
1212
import 'package:analyzer/dart/constant/value.dart';
1313
import 'package:analyzer/dart/element/element.dart';
14-
import 'package:analyzer/dart/element/nullability_suffix.dart';
1514
import 'package:analyzer/dart/element/type.dart';
1615
import 'package:analyzer/error/error.dart';
1716
import 'package:analyzer/error/listener.dart';
@@ -1677,39 +1676,10 @@ class BestPracticesVerifier extends RecursiveAstVisitor<void> {
16771676
}
16781677

16791678
// The cast is necessary.
1680-
if (!typeSystem.isSubtypeOf(leftType, rightType)) {
1679+
if (leftType != rightType) {
16811680
return false;
16821681
}
16831682

1684-
// Casting from `T*` to `T?` is a way to force `T?`.
1685-
if (leftType.nullabilitySuffix == NullabilitySuffix.star &&
1686-
rightType.nullabilitySuffix == NullabilitySuffix.question) {
1687-
return false;
1688-
}
1689-
1690-
// For `condition ? then : else` the result type is `LUB`.
1691-
// Casts might be used to consider only a portion of the inheritance tree.
1692-
var parent = node.parent;
1693-
if (parent is ConditionalExpression) {
1694-
var other = node == parent.thenExpression
1695-
? parent.elseExpression
1696-
: parent.thenExpression;
1697-
1698-
var currentType = typeSystem.leastUpperBound(
1699-
node.typeOrThrow,
1700-
other.typeOrThrow,
1701-
);
1702-
1703-
var typeWithoutCast = typeSystem.leastUpperBound(
1704-
node.expression.typeOrThrow,
1705-
other.typeOrThrow,
1706-
);
1707-
1708-
if (typeWithoutCast != currentType) {
1709-
return false;
1710-
}
1711-
}
1712-
17131683
return true;
17141684
}
17151685

pkg/analyzer/test/src/diagnostics/cast_from_null_always_fails_test.dart

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,11 @@ void f<T extends Object>(Null n) {
8383
}
8484

8585
test_Null_nullable() async {
86-
await assertErrorsInCode('''
86+
await assertNoErrorsInCode('''
8787
void f(Null n) {
8888
n as int?;
8989
}
90-
''', [
91-
error(WarningCode.UNNECESSARY_CAST, 19, 9),
92-
]);
90+
''');
9391
}
9492

9593
test_Null_nullableTypeVariable() async {
@@ -102,15 +100,13 @@ void f<T>(Null n) {
102100

103101
test_Null_preNullSafety() async {
104102
noSoundNullSafety = false;
105-
await assertErrorsInCode('''
103+
await assertNoErrorsInCode('''
106104
// @dart=2.9
107105
108106
void f(Null n) {
109107
n as int;
110108
}
111-
''', [
112-
error(WarningCode.UNNECESSARY_CAST, 33, 8),
113-
]);
109+
''');
114110
}
115111

116112
test_nullable_nonNullable() async {

pkg/analyzer/test/src/diagnostics/unnecessary_cast_test.dart

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ class A {}
2525
class B extends A {}
2626
2727
dynamic f(bool c, B x, B y) {
28-
return c ? x as A : y;
28+
var r = c ? x as A : y;
29+
return r;
2930
}
3031
''');
3132
}
@@ -127,23 +128,19 @@ void f(num Function() a) {
127128
}
128129

129130
test_function_toSupertype_viaParameter() async {
130-
await assertErrorsInCode(r'''
131+
await assertNoErrorsInCode(r'''
131132
void f(void Function(num) a) {
132133
(a as void Function(int))(3);
133134
}
134-
''', [
135-
error(WarningCode.UNNECESSARY_CAST, 34, 23),
136-
]);
135+
''');
137136
}
138137

139138
test_function_toSupertype_viaReturnType() async {
140-
await assertErrorsInCode(r'''
139+
await assertNoErrorsInCode(r'''
141140
void f(int Function() a) {
142141
(a as num Function())();
143142
}
144-
''', [
145-
error(WarningCode.UNNECESSARY_CAST, 30, 19),
146-
]);
143+
''');
147144
}
148145

149146
test_function_toUnrelated() async {
@@ -171,13 +168,11 @@ void f() {
171168
}
172169

173170
test_type_supertype() async {
174-
await assertErrorsInCode(r'''
171+
await assertNoErrorsInCode(r'''
175172
void f(int a) {
176173
a as Object;
177174
}
178-
''', [
179-
error(WarningCode.UNNECESSARY_CAST, 18, 11),
180-
]);
175+
''');
181176
}
182177

183178
test_type_type() async {
@@ -191,23 +186,19 @@ void f(num a) {
191186
}
192187

193188
test_typeParameter_hasBound_same() async {
194-
await assertErrorsInCode(r'''
189+
await assertNoErrorsInCode(r'''
195190
void f<T extends num>(T a) {
196191
a as num;
197192
}
198-
''', [
199-
error(WarningCode.UNNECESSARY_CAST, 31, 8),
200-
]);
193+
''');
201194
}
202195

203196
test_typeParameter_hasBound_subtype() async {
204-
await assertErrorsInCode(r'''
197+
await assertNoErrorsInCode(r'''
205198
void f<T extends int>(T a) {
206199
a as num;
207200
}
208-
''', [
209-
error(WarningCode.UNNECESSARY_CAST, 31, 8),
210-
]);
201+
''');
211202
}
212203

213204
test_typeParameter_hasBound_unrelated() async {
@@ -245,7 +236,6 @@ void f() {
245236
}
246237
''', [
247238
error(HintCode.IMPORT_OF_LEGACY_LIBRARY_INTO_NULL_SAFE, 7, 8),
248-
error(WarningCode.UNNECESSARY_CAST, 39, 8),
249239
]);
250240
}
251241

pkg/analyzer/test/src/task/strong/checker_test.dart

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -634,13 +634,11 @@ void main() {
634634
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 1256, 4),
635635
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 1331, 6),
636636
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 1359, 4),
637-
error(WarningCode.UNNECESSARY_CAST, 1526, 11),
638637
error(HintCode.UNUSED_LOCAL_VARIABLE, 1591, 1),
639638
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 1616, 6),
640639
error(CompileTimeErrorCode.INVALID_CAST_FUNCTION, 1644, 4),
641640
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 1735, 6),
642641
error(CompileTimeErrorCode.INVALID_CAST_FUNCTION, 1763, 4),
643-
error(WarningCode.UNNECESSARY_CAST, 1960, 11),
644642
error(HintCode.UNUSED_LOCAL_VARIABLE, 2047, 1),
645643
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 2088, 2),
646644
error(CompileTimeErrorCode.INVALID_CAST_FUNCTION, 2100, 4),
@@ -650,7 +648,6 @@ void main() {
650648
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 2255, 4),
651649
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 2380, 10),
652650
error(CompileTimeErrorCode.INVALID_CAST_FUNCTION_EXPR, 2400, 22),
653-
error(WarningCode.UNNECESSARY_CAST, 2410, 11),
654651
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 2450, 4),
655652
error(HintCode.UNUSED_LOCAL_VARIABLE, 2495, 1),
656653
error(CompileTimeErrorCode.INVALID_CAST_FUNCTION, 2520, 6),
@@ -661,7 +658,6 @@ void main() {
661658
error(CompileTimeErrorCode.INVALID_CAST_FUNCTION, 2741, 4),
662659
error(CompileTimeErrorCode.INVALID_CAST_FUNCTION_EXPR, 2914, 10),
663660
error(CompileTimeErrorCode.INVALID_CAST_FUNCTION_EXPR, 2952, 22),
664-
error(WarningCode.UNNECESSARY_CAST, 2962, 11),
665661
]);
666662
}
667663

@@ -1340,30 +1336,20 @@ void main() {
13401336
error(HintCode.UNUSED_LOCAL_VARIABLE, 192, 1),
13411337
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 222, 7),
13421338
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 254, 3),
1343-
error(WarningCode.UNNECESSARY_CAST, 268, 13),
1344-
error(WarningCode.UNNECESSARY_CAST, 292, 15),
13451339
error(HintCode.UNUSED_LOCAL_VARIABLE, 328, 1),
13461340
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 340, 7),
13471341
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 376, 3),
1348-
error(WarningCode.UNNECESSARY_CAST, 404, 13),
1349-
error(WarningCode.UNNECESSARY_CAST, 428, 15),
13501342
error(HintCode.UNUSED_LOCAL_VARIABLE, 462, 1),
13511343
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 492, 7),
13521344
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 510, 3),
13531345
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 524, 3),
1354-
error(WarningCode.UNNECESSARY_CAST, 538, 13),
1355-
error(WarningCode.UNNECESSARY_CAST, 562, 15),
13561346
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 562, 15),
13571347
error(HintCode.UNUSED_LOCAL_VARIABLE, 596, 1),
13581348
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 608, 7),
13591349
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 644, 3),
13601350
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 658, 3),
1361-
error(WarningCode.UNNECESSARY_CAST, 672, 13),
13621351
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 696, 15),
1363-
error(WarningCode.UNNECESSARY_CAST, 696, 15),
13641352
error(HintCode.UNUSED_LOCAL_VARIABLE, 737, 1),
1365-
error(WarningCode.UNNECESSARY_CAST, 813, 13),
1366-
error(WarningCode.UNNECESSARY_CAST, 837, 15),
13671353
]);
13681354
}
13691355

@@ -2054,9 +2040,7 @@ void main() {
20542040
error(HintCode.UNUSED_LOCAL_VARIABLE, 365, 1),
20552041
error(HintCode.UNUSED_LOCAL_VARIABLE, 665, 1),
20562042
error(WarningCode.UNNECESSARY_CAST, 674, 10),
2057-
error(WarningCode.UNNECESSARY_CAST, 710, 10),
20582043
error(WarningCode.UNNECESSARY_CAST, 747, 11),
2059-
error(WarningCode.UNNECESSARY_CAST, 804, 11),
20602044
]);
20612045
}
20622046

pkg/analyzer/test/src/task/strong/inferred_type_test.dart

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2547,7 +2547,6 @@ $declared foo() => new $declared<int>.value(1);
25472547
error(HintCode.UNUSED_LOCAL_VARIABLE, 309, 2),
25482548
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 314, 1),
25492549
error(HintCode.UNUSED_LOCAL_VARIABLE, 475, 2),
2550-
error(WarningCode.UNNECESSARY_CAST, 480, 47),
25512550
],
25522551
);
25532552
await disposeAnalysisContextCollection();
@@ -3068,7 +3067,6 @@ main() {
30683067
contextMessages: [message('/home/test/lib/test.dart', 12, 1)]),
30693068
error(CompileTimeErrorCode.INVALID_OVERRIDE, 94, 1,
30703069
contextMessages: [message('/home/test/lib/test.dart', 33, 1)]),
3071-
error(WarningCode.UNNECESSARY_CAST, 132, 12),
30723070
]);
30733071
}
30743072

@@ -3601,12 +3599,8 @@ test1() {
36013599
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 171, 1),
36023600
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 201, 1),
36033601
error(CompileTimeErrorCode.UNDEFINED_OPERATOR, 572, 1),
3604-
error(
3605-
isNullSafetyEnabled
3606-
? WarningCode.CAST_FROM_NULL_ALWAYS_FAILS
3607-
: WarningCode.UNNECESSARY_CAST,
3608-
591,
3609-
9),
3602+
if (isNullSafetyEnabled)
3603+
error(WarningCode.CAST_FROM_NULL_ALWAYS_FAILS, 591, 9),
36103604
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 619, 4),
36113605
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 647, 4),
36123606
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 687, 2),

0 commit comments

Comments
 (0)