diff --git a/pkg/compiler/lib/src/ir/impact_data.dart b/pkg/compiler/lib/src/ir/impact_data.dart index 314e42cae45..df94d215add 100644 --- a/pkg/compiler/lib/src/ir/impact_data.dart +++ b/pkg/compiler/lib/src/ir/impact_data.dart @@ -222,8 +222,8 @@ class ImpactBuilder extends StaticTypeVisitor implements ImpactRegistry { void handleAsExpression(ir.AsExpression node, ir.DartType operandType, {bool? isCalculatedTypeSubtype}) { if (isCalculatedTypeSubtype ?? - typeEnvironment.isSubtypeOf(operandType, node.type, - ir.SubtypeCheckMode.ignoringNullabilities)) { + typeEnvironment.isSubtypeOf( + operandType, node.type, ir.SubtypeCheckMode.withNullabilities)) { // Skip unneeded casts. return; } diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart index 2269da9d477..3b4040e1881 100644 --- a/pkg/compiler/lib/src/ir/static_type.dart +++ b/pkg/compiler/lib/src/ir/static_type.dart @@ -1320,7 +1320,7 @@ abstract class StaticTypeVisitor extends StaticTypeBase { // Check if the calculated operandType is a subtype of the type specified // in the `as` expression. final isCalculatedTypeSubtype = typeEnvironment.isSubtypeOf( - operandType, node.type, ir.SubtypeCheckMode.ignoringNullabilities); + operandType, node.type, ir.SubtypeCheckMode.withNullabilities); if (!isCalculatedTypeSubtype && operand is ir.VariableGet && !_invalidatedVariables.contains(operand.variable)) { diff --git a/pkg/compiler/test/closure/data/generic.dart b/pkg/compiler/test/closure/data/generic.dart index 3fd1f774574..354f8f828f8 100644 --- a/pkg/compiler/test/closure/data/generic.dart +++ b/pkg/compiler/test/closure/data/generic.dart @@ -56,12 +56,10 @@ class Class1 { } var local2 = - /*prod.hasThis*/ - /*spec.fields=[S,this],free=[S,this],hasThis*/ + /*fields=[S,this],free=[S,this],hasThis*/ (o) { return - /*prod.hasThis*/ - /*spec.fields=[S,this],free=[S,this],hasThis*/ + /*fields=[S,this],free=[S,this],hasThis*/ () => Map(); }; return local2(local()); diff --git a/pkg/compiler/test/closure/data/list_literal_untested_class.dart b/pkg/compiler/test/closure/data/list_literal_untested_class.dart index c4019598237..26f724c0d55 100644 --- a/pkg/compiler/test/closure/data/list_literal_untested_class.dart +++ b/pkg/compiler/test/closure/data/list_literal_untested_class.dart @@ -9,8 +9,7 @@ class A { /*member: A.method:hasThis*/ @pragma('dart2js:noInline') method() { - /*spec.fields=[this],free=[this],hasThis*/ - /*prod.hasThis*/ + /*fields=[this],free=[this],hasThis*/ dynamic local() => []; return local; } diff --git a/pkg/compiler/test/closure/data/list_literal_untested_method.dart b/pkg/compiler/test/closure/data/list_literal_untested_method.dart index 57a4c3d4cb3..cc4e8ecd936 100644 --- a/pkg/compiler/test/closure/data/list_literal_untested_method.dart +++ b/pkg/compiler/test/closure/data/list_literal_untested_method.dart @@ -6,7 +6,7 @@ import 'package:expect/expect.dart'; @pragma('dart2js:noInline') method() { - /*spec.fields=[T],free=[T]*/ + /*fields=[T],free=[T]*/ dynamic local() => []; return local; } diff --git a/pkg/compiler/test/closure/data/map_literal_untested_class.dart b/pkg/compiler/test/closure/data/map_literal_untested_class.dart index 7cd568bdf73..6b17fa5ab57 100644 --- a/pkg/compiler/test/closure/data/map_literal_untested_class.dart +++ b/pkg/compiler/test/closure/data/map_literal_untested_class.dart @@ -9,8 +9,7 @@ class A { /*member: A.method:hasThis*/ @pragma('dart2js:noInline') method() { - /*spec.fields=[this],free=[this],hasThis*/ - /*prod.hasThis*/ + /*fields=[this],free=[this],hasThis*/ dynamic local() => {}; return local; } diff --git a/pkg/compiler/test/closure/data/map_literal_untested_method.dart b/pkg/compiler/test/closure/data/map_literal_untested_method.dart index 3ddf2c3bad7..050351c48ef 100644 --- a/pkg/compiler/test/closure/data/map_literal_untested_method.dart +++ b/pkg/compiler/test/closure/data/map_literal_untested_method.dart @@ -6,7 +6,7 @@ import 'package:expect/expect.dart'; @pragma('dart2js:noInline') method() { - /*spec.fields=[T],free=[T]*/ + /*fields=[T],free=[T]*/ dynamic local() => {}; return local; } diff --git a/pkg/compiler/test/codegen/data/array_add.dart b/pkg/compiler/test/codegen/data/array_add.dart index 81ecb407710..e2f7e01c325 100644 --- a/pkg/compiler/test/codegen/data/array_add.dart +++ b/pkg/compiler/test/codegen/data/array_add.dart @@ -12,7 +12,7 @@ return t1; }*/ /*prod.member: test1:function() { - var t1 = []; + var t1 = A._setArrayType([], type$.JSArray_int); t1.push(1); return t1; }*/ diff --git a/pkg/compiler/test/codegen/literal_list_test.dart b/pkg/compiler/test/codegen/literal_list_test.dart index ae346c3c1de..96eb94005e4 100644 --- a/pkg/compiler/test/codegen/literal_list_test.dart +++ b/pkg/compiler/test/codegen/literal_list_test.dart @@ -18,12 +18,18 @@ foo() { main() { runTest() async { await compile(TEST_ONE, entry: 'foo', check: (String generated) { - Expect.isTrue(generated.contains('print([1, 2]);'), - "Code pattern 'print([1, 2]);' not found in\n$generated"); - Expect.isTrue(generated.contains('print([3]);'), - "Code pattern 'print([3]);' not found in\n$generated"); - Expect.isTrue(generated.contains('print([4, 5]);'), - "Code pattern 'print([4, 5]);' not found in\n$generated"); + Expect.isTrue( + generated.contains('A.print(A._setArrayType([1, 2], t1));'), + "Code pattern 'A.print(A._setArrayType([1, 2], t1));' " + "not found in\n$generated"); + Expect.isTrue( + generated.contains('A.print(A._setArrayType([3], t1));'), + "Code pattern 'A.print(A._setArrayType([3], t1));' " + "not found in\n$generated"); + Expect.isTrue( + generated.contains('A.print(A._setArrayType([4, 5], t1));'), + "Code pattern 'A.print(A._setArrayType([4, 5], t1));' " + "not found in\n$generated"); }); } diff --git a/pkg/compiler/test/rti/data/async_foreach.dart b/pkg/compiler/test/rti/data/async_foreach.dart index 09f4c482906..7dfaa8754ea 100644 --- a/pkg/compiler/test/rti/data/async_foreach.dart +++ b/pkg/compiler/test/rti/data/async_foreach.dart @@ -7,7 +7,7 @@ import 'package:compiler/src/util/testing.dart'; /*spec.class: Class:explicit=[Class.T*],implicit=[Class.T],needsArgs,test*/ -/*prod.class: Class:needsArgs*/ +/*prod.class: Class:implicit=[Class.T],needsArgs,test*/ class Class { method() { var list = []; diff --git a/pkg/compiler/test/rti/data/async_foreach_nonasync.dart b/pkg/compiler/test/rti/data/async_foreach_nonasync.dart index 99cb53702e2..a464e0d6187 100644 --- a/pkg/compiler/test/rti/data/async_foreach_nonasync.dart +++ b/pkg/compiler/test/rti/data/async_foreach_nonasync.dart @@ -7,6 +7,7 @@ import 'package:compiler/src/util/testing.dart'; /*spec.class: Class:explicit=[Class.T*],implicit=[Class.T],needsArgs,test*/ +/*prod.class: Class:implicit=[Class.T],needsArgs,test*/ class Class { method() { var list = []; diff --git a/pkg/compiler/test/rti/data/generic_class_is2.dart b/pkg/compiler/test/rti/data/generic_class_is2.dart index 029adc68972..00be9eef201 100644 --- a/pkg/compiler/test/rti/data/generic_class_is2.dart +++ b/pkg/compiler/test/rti/data/generic_class_is2.dart @@ -9,7 +9,7 @@ import 'package:compiler/src/util/testing.dart'; /*class: A:implicit=[List*>,List*>]*/ class A {} -/*spec.class: A1:implicit=[A1]*/ +/*class: A1:implicit=[A1]*/ class A1 implements A {} /*class: B:explicit=[B.T*],needsArgs,test*/ diff --git a/pkg/compiler/test/rti/data/generic_methods_dynamic_05.dart b/pkg/compiler/test/rti/data/generic_methods_dynamic_05.dart index 0cb12423a19..0d30b72892d 100644 --- a/pkg/compiler/test/rti/data/generic_methods_dynamic_05.dart +++ b/pkg/compiler/test/rti/data/generic_methods_dynamic_05.dart @@ -9,20 +9,19 @@ import 'package:compiler/src/util/testing.dart'; // Test derived from language_2/generic_methods_dynamic_test/05 /*spec.class: global#JSArray:deps=[ArrayIterator,List],explicit=[JSArray,JSArray.E,JSArray],implicit=[JSArray.E],needsArgs,test*/ -/*prod.class: global#JSArray:deps=[List],needsArgs*/ +/*prod.class: global#JSArray:deps=[List],implicit=[JSArray.E],needsArgs,test*/ /*spec.class: global#List:deps=[C.bar,JSArray.markFixedList],explicit=[List*,List,List,List?,List],needsArgs,test*/ -/*prod.class: global#List:deps=[C.bar],explicit=[List*],needsArgs*/ +/*prod.class: global#List:deps=[C.bar],explicit=[List*],needsArgs,test*/ class A {} -/*spec.class: B:explicit=[List*],implicit=[B]*/ -/*prod.class: B:explicit=[List*]*/ +/*class: B:explicit=[List*],implicit=[B]*/ class B {} class C { /*spec.member: C.bar:explicit=[Iterable*],implicit=[bar.T],needsArgs,selectors=[Selector(call, bar, arity=1, types=1)],test*/ - /*prod.member: C.bar:needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/ + /*prod.member: C.bar:implicit=[bar.T],needsArgs,selectors=[Selector(call, bar, arity=1, types=1)],test*/ List bar(Iterable t) => [t.first]; } diff --git a/pkg/compiler/test/rti/data/local_function_list_literal.dart b/pkg/compiler/test/rti/data/local_function_list_literal.dart index 0af6116dd2f..2ef3666582f 100644 --- a/pkg/compiler/test/rti/data/local_function_list_literal.dart +++ b/pkg/compiler/test/rti/data/local_function_list_literal.dart @@ -7,11 +7,10 @@ import 'package:compiler/src/util/testing.dart'; /*spec.class: global#JSArray:deps=[ArrayIterator,List],explicit=[JSArray,JSArray.E,JSArray],implicit=[JSArray.E],needsArgs,test*/ -/*prod.class: global#JSArray:deps=[List],needsArgs*/ +/*prod.class: global#JSArray:deps=[List],implicit=[JSArray.E],needsArgs,test*/ @pragma('dart2js:noInline') -/*spec.member: method:implicit=[method.T],needsArgs,test*/ -/*prod.member: method:needsArgs*/ +/*member: method:implicit=[method.T],needsArgs,test*/ method() { return /*spec.*/ () => []; } diff --git a/pkg/compiler/test/rti/data/local_function_map_literal.dart b/pkg/compiler/test/rti/data/local_function_map_literal.dart index 7130d699f57..32b5694c6db 100644 --- a/pkg/compiler/test/rti/data/local_function_map_literal.dart +++ b/pkg/compiler/test/rti/data/local_function_map_literal.dart @@ -7,7 +7,7 @@ import 'package:compiler/src/util/testing.dart'; /*spec.class: global#LinkedHashMap:deps=[Map],explicit=[LinkedHashMap],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs,test*/ -/*prod.class: global#LinkedHashMap:deps=[Map],needsArgs*/ +/*prod.class: global#LinkedHashMap:deps=[Map],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/ @pragma('dart2js:noInline') /*spec.member: method:implicit=[method.T],needsArgs,test*/ diff --git a/pkg/compiler/test/rti/data/map_literal.dart b/pkg/compiler/test/rti/data/map_literal.dart index 60568fd0d15..4d4f0d64e72 100644 --- a/pkg/compiler/test/rti/data/map_literal.dart +++ b/pkg/compiler/test/rti/data/map_literal.dart @@ -4,13 +4,13 @@ // @dart = 2.7 -/*prod.class: global#Map:*/ +/*prod.class: global#Map:needsArgs*/ /*spec.class: global#Map:explicit=[Map,Map],needsArgs,test*/ -/*prod.class: global#LinkedHashMap:deps=[Map]*/ +/*prod.class: global#LinkedHashMap:deps=[Map],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/ /*spec.class: global#LinkedHashMap:deps=[Map],explicit=[LinkedHashMap],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs,test*/ -/*prod.class: global#JsLinkedHashMap:deps=[LinkedHashMap]*/ +/*prod.class: global#JsLinkedHashMap:deps=[LinkedHashMap],needsArgs*/ /*spec.class: global#JsLinkedHashMap:deps=[LinkedHashMap],explicit=[JsLinkedHashMap,JsLinkedHashMap.K,JsLinkedHashMap.V,void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.K],needsArgs,test*/ /*prod.class: global#double:*/ diff --git a/pkg/compiler/test/rti/data/map_to_set.dart b/pkg/compiler/test/rti/data/map_to_set.dart index 5aa278f2f03..d33788bac4d 100644 --- a/pkg/compiler/test/rti/data/map_to_set.dart +++ b/pkg/compiler/test/rti/data/map_to_set.dart @@ -7,7 +7,7 @@ /*prod.class: global#Map:deps=[Class],needsArgs*/ /*spec.class: global#Map:deps=[Class],explicit=[Map,Map],needsArgs,test*/ -/*prod.class: global#LinkedHashMap:deps=[Map],implicit=[LinkedHashMap.K],needsArgs*/ +/*prod.class: global#LinkedHashMap:deps=[Map],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/ /*spec.class: global#LinkedHashMap:deps=[Map],explicit=[LinkedHashMap],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs,test*/ /*prod.class: global#JsLinkedHashMap:deps=[LinkedHashMap],implicit=[JsLinkedHashMap.K],needsArgs*/ diff --git a/tests/web/regress/issue/54419_test.dart b/tests/web/regress/issue/54419_test.dart new file mode 100644 index 00000000000..854d6823960 --- /dev/null +++ b/tests/web/regress/issue/54419_test.dart @@ -0,0 +1,17 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; + +// Ensure we don't omit as checks based on a subtype check ignoring nullability. + +void foo(T? x) { + print(x as T); +} + +void main() { + if (hasSoundNullSafety) { + Expect.throws(() => foo(null)); + } +}