diff --git a/pkg/compiler/lib/src/inferrer/typemasks/masks.dart b/pkg/compiler/lib/src/inferrer/typemasks/masks.dart index 13327c055df3..d1c39be3f2ab 100644 --- a/pkg/compiler/lib/src/inferrer/typemasks/masks.dart +++ b/pkg/compiler/lib/src/inferrer/typemasks/masks.dart @@ -917,10 +917,15 @@ class CommonMasks with AbstractValueDomain { @override AbstractValue getGetterTypeInRecord(AbstractValue value, String getterName) { - final type = value is RecordTypeMask - ? value.types[value.shape.indexOfGetterName(getterName)] - : null; - return type ?? dynamicType; + if (value is RecordTypeMask) { + final getterIndex = value.shape.indexOfGetterName(getterName); + // Generated code can sometimes contain record accesses for invalid + // getters. + if (getterIndex >= 0) { + return value.types[getterIndex]; + } + } + return dynamicType; } @override diff --git a/tests/web/regress/issue/52438_test.dart b/tests/web/regress/issue/52438_test.dart new file mode 100644 index 000000000000..4ea98cc3eafe --- /dev/null +++ b/tests/web/regress/issue/52438_test.dart @@ -0,0 +1,15 @@ +// Copyright (c) 2023, 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. + +// Switches geenrate record accesses on non-existent fields. These accesses +// should be guarded by a type check but Dart2JS does not always promote +// correctly after the type check. + +void main() { + Object r = (1, 2); + switch (r) { + case (int _, int _, int c): + print('Skip, no match'); + } +}