[vm,aot] Fix parameter type checks in the implicit setters of covariant-by-class fields
Implicit setters of covariant fields (both covariant by declaration and covariant by class aka generic-covariant-impl) need to perform a type check of their argument. It means that inferred type of the field cannot be used as inferred type of parameter of such setter. This change removes such uses of an inferred type of the field, which restores parameter type check which was previously incorrectly optimized out. TEST=runtime/tests/vm/dart/regress_63419_test.dart Fixes https://github.com/dart-lang/sdk/issues/63419 Change-Id: Ie313dbaab51dff15d60ce4390e7e41bdc66ad59d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/509020 Reviewed-by: Slava Egorov <vegorov@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
021068bb3d
commit
6b9aecbe5f
@@ -194,7 +194,7 @@ class UnboxingInfoManager {
|
||||
// Arguments of implicit setters for covariant fields
|
||||
// cannot be unboxed based on the field type as setter
|
||||
// performs a type check before value is assigned to the field.
|
||||
if (member.isCovariantByDeclaration) {
|
||||
if (member.isCovariantByDeclaration || member.isCovariantByClass) {
|
||||
unboxingInfo.argsInfo.length = 0;
|
||||
} else {
|
||||
_applyToArg(member, unboxingInfo, 0, inferredType);
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright (c) 2026, 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.
|
||||
|
||||
// Regression test for https://github.com/dart-lang/sdk/issues/63419.
|
||||
|
||||
// VMOptions=--compiler-passes=-Inlining
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
abstract interface class Box1<T> {
|
||||
T get x;
|
||||
void set x(T value);
|
||||
}
|
||||
|
||||
class StringBox implements Box1<String> {
|
||||
@pragma("vm:never-inline")
|
||||
String x = 'yay';
|
||||
}
|
||||
|
||||
abstract interface class Box2<T> {
|
||||
T get x;
|
||||
void set x(T value);
|
||||
}
|
||||
|
||||
class IntBox implements Box2<int> {
|
||||
@pragma("vm:never-inline")
|
||||
int x = 0;
|
||||
}
|
||||
|
||||
void main() {
|
||||
final Box1<Object> box1 = StringBox();
|
||||
box1.x = 'xyz';
|
||||
Expect.equals('xyz', box1.x);
|
||||
Expect.throws(() {
|
||||
box1.x = 123;
|
||||
});
|
||||
|
||||
final Box2<Object> box2 = IntBox();
|
||||
box2.x = 123;
|
||||
Expect.equals(123, box2.x);
|
||||
Expect.throws(() {
|
||||
box2.x = 'abc';
|
||||
});
|
||||
}
|
||||
@@ -308,7 +308,8 @@ ScopeBuildingResult* ScopeBuilder::BuildScopes() {
|
||||
AbstractType::ZoneHandle(Z, function.ParameterTypeAt(pos)),
|
||||
LocalVariable::kNoKernelOffset, /*is_late=*/false,
|
||||
/*inferred_type_md=*/nullptr,
|
||||
/*inferred_arg_type_md=*/field.is_covariant()
|
||||
/*inferred_arg_type_md=*/
|
||||
(field.is_covariant() || field.is_generic_covariant_impl())
|
||||
? nullptr
|
||||
: &inferred_field_type);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user