[cfe] Use argument original order for downcasts from dynamic

Closes https://github.com/dart-lang/sdk/issues/54935

Change-Id: Id9e579ba015d19a5fab709e60dfbae77b0980dd5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/353402
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Chloe Stefantsova 2024-02-21 11:27:23 +00:00 committed by Commit Queue
parent cccde729eb
commit 1f299666e9
10 changed files with 81 additions and 5 deletions

View file

@ -2075,7 +2075,8 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
} else {
// Argument counts and names match. Compare types.
int positionalShift = isImplicitExtensionMember ? 1 : 0;
int numPositionalArgs = arguments.positional.length - positionalShift;
int positionalIndex = 0;
int namedIndex = 0;
for (int i = 0; i < formalTypes.length; i++) {
DartType formalType = formalTypes[i];
DartType expectedType = instantiator != null
@ -2085,11 +2086,14 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
Expression expression;
NamedExpression? namedExpression;
bool coerceExpression;
if (i < numPositionalArgs) {
expression = arguments.positional[positionalShift + i];
Object? argumentInEvaluationOrder =
argumentsEvaluationOrder[i + positionalShift];
if (argumentInEvaluationOrder is Expression) {
expression =
arguments.positional[positionalShift + positionalIndex];
coerceExpression = !arguments.positionalAreSuperParameters;
} else {
namedExpression = arguments.named[i - numPositionalArgs];
namedExpression = arguments.named[namedIndex];
expression = namedExpression.value;
coerceExpression = !(arguments.namedSuperParameterNames
?.contains(namedExpression.name) ??
@ -2110,10 +2114,12 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
nullabilityNullTypeErrorTemplate:
templateArgumentTypeNotAssignableNullabilityNullType);
if (namedExpression == null) {
arguments.positional[positionalShift + i] = expression
arguments.positional[positionalShift + positionalIndex] = expression
..parent = arguments;
positionalIndex++;
} else {
namedExpression.value = expression..parent = namedExpression;
namedIndex++;
}
}
}

View file

@ -0,0 +1,11 @@
// 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.
void foo(String x, {required bool y, required num z}) {
}
void main() {
final v = <String, dynamic>{'y': true, 'x': '', 'z': 1.0};
foo(z: v['z'], y: v['y'], v['x']);
}

View file

@ -0,0 +1,9 @@
library;
import self as self;
import "dart:core" as core;
static method foo(core::String x, {required core::bool y, required core::num z}) → void {}
static method main() → void {
final core::Map<core::String, dynamic> v = <core::String, dynamic>{"y": true, "x": "", "z": 1.0};
let final dynamic #t1 = v.{core::Map::[]}("z"){(core::Object?) → dynamic} in let final dynamic #t2 = v.{core::Map::[]}("y"){(core::Object?) → dynamic} in self::foo(v.{core::Map::[]}("x"){(core::Object?) → dynamic} as{TypeError,ForDynamic} core::String, z: #t1 as{TypeError,ForDynamic} core::num, y: #t2 as{TypeError,ForDynamic} core::bool);
}

View file

@ -0,0 +1,9 @@
library;
import self as self;
import "dart:core" as core;
static method foo(core::String x, {required core::bool y, required core::num z}) → void {}
static method main() → void {
final core::Map<core::String, dynamic> v = <core::String, dynamic>{"y": true, "x": "", "z": 1.0};
let final dynamic #t1 = v.{core::Map::[]}("z"){(core::Object?) → dynamic} in let final dynamic #t2 = v.{core::Map::[]}("y"){(core::Object?) → dynamic} in self::foo(v.{core::Map::[]}("x"){(core::Object?) → dynamic} as{TypeError,ForDynamic} core::String, z: #t1 as{TypeError,ForDynamic} core::num, y: #t2 as{TypeError,ForDynamic} core::bool);
}

View file

@ -0,0 +1,3 @@
void foo(String x, {required bool y, required num z}) {}
void main() {}

View file

@ -0,0 +1,3 @@
void foo(String x, {required bool y, required num z}) {}
void main() {}

View file

@ -0,0 +1,9 @@
library;
import self as self;
import "dart:core" as core;
static method foo(core::String x, {required core::bool y, required core::num z}) → void {}
static method main() → void {
final core::Map<core::String, dynamic> v = <core::String, dynamic>{"y": true, "x": "", "z": 1.0};
let final dynamic #t1 = v.{core::Map::[]}("z"){(core::Object?) → dynamic} in let final dynamic #t2 = v.{core::Map::[]}("y"){(core::Object?) → dynamic} in self::foo(v.{core::Map::[]}("x"){(core::Object?) → dynamic} as{TypeError,ForDynamic} core::String, z: #t1 as{TypeError,ForDynamic} core::num, y: #t2 as{TypeError,ForDynamic} core::bool);
}

View file

@ -0,0 +1,9 @@
library;
import self as self;
import "dart:core" as core;
static method foo(core::String x, {required core::bool y, required core::num z}) → void {}
static method main() → void {
final core::Map<core::String, dynamic> v = <core::String, dynamic>{"y": true, "x": "", "z": 1.0};
let final dynamic #t1 = v.{core::Map::[]}("z"){(core::Object?) → dynamic} in let final dynamic #t2 = v.{core::Map::[]}("y"){(core::Object?) → dynamic} in self::foo(v.{core::Map::[]}("x"){(core::Object?) → dynamic} as{TypeError,ForDynamic} core::String, z: #t1 as{TypeError,ForDynamic} core::num, y: #t2 as{TypeError,ForDynamic} core::bool);
}

View file

@ -0,0 +1,8 @@
library;
import self as self;
import "dart:core" as core;
static method foo(core::String x, {required core::bool y, required core::num z}) → void
;
static method main() → void
;

View file

@ -0,0 +1,9 @@
library;
import self as self;
import "dart:core" as core;
static method foo(core::String x, {required core::bool y, required core::num z}) → void {}
static method main() → void {
final core::Map<core::String, dynamic> v = <core::String, dynamic>{"y": true, "x": "", "z": 1.0};
let final dynamic #t1 = v.{core::Map::[]}("z"){(core::Object?) → dynamic} in let final dynamic #t2 = v.{core::Map::[]}("y"){(core::Object?) → dynamic} in self::foo(v.{core::Map::[]}("x"){(core::Object?) → dynamic} as{TypeError,ForDynamic} core::String, z: #t1 as{TypeError,ForDynamic} core::num, y: #t2 as{TypeError,ForDynamic} core::bool);
}