[cfe] Change MapPattern.key to Expression

The key can only be an Expression but was unneedingly wrapped in
a ConstantPattern. Since the shared type analysis only handles
map pattern keys as expressions, the expected properties of
ConstantPattern were not set. Amongst these were the static type
of the key expression, which is know passed directly to the
handleMapPatternEntry method.

Change-Id: I705fc655e440d534ccc442c9c1359c377955b3b1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/288282
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
This commit is contained in:
Johnni Winther 2023-03-13 10:05:16 +00:00 committed by Commit Queue
parent f17cf33c6d
commit a811db5bc6
11 changed files with 20 additions and 18 deletions

View file

@ -1082,13 +1082,13 @@ mixin TypeAnalyzer<
Node element = elements[i];
MapPatternEntry<Expression, Pattern>? entry = getMapPatternEntry(element);
if (entry != null) {
analyzeExpression(entry.key, keyContext);
Type keyType = analyzeExpression(entry.key, keyContext);
flow.pushSubpattern(valueType);
dispatchPattern(
context.withUnnecessaryWildcardKind(null),
entry.value,
);
handleMapPatternEntry(node, element);
handleMapPatternEntry(node, element, keyType);
flow.popSubpattern();
} else {
assert(isRestPatternElement(element));
@ -2171,7 +2171,8 @@ mixin TypeAnalyzer<
/// Called after visiting an entry element in a map pattern.
///
/// Stack effect: pushes (MapPatternElement).
void handleMapPatternEntry(Pattern container, Node entryElement);
void handleMapPatternEntry(
Pattern container, Node entryElement, Type keyType);
/// Called after visiting a rest element in a map pattern.
///

View file

@ -3790,7 +3790,8 @@ class _MiniAstTypeAnalyzer
}
@override
void handleMapPatternEntry(Pattern container, Node entryElement) {
void handleMapPatternEntry(
Pattern container, Node entryElement, Type keyType) {
_irBuilder.apply('mapPatternEntry', [Kind.expression, Kind.pattern],
Kind.mapPatternElement,
location: entryElement.location);

View file

@ -1127,6 +1127,7 @@ class ResolverVisitor extends ThrowingAstVisitor<void>
void handleMapPatternEntry(
DartPattern container,
covariant MapPatternEntryImpl entry,
DartType keyType,
) {
entry.key = popRewrite()!;
}

View file

@ -11339,9 +11339,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase
}
@override
void handleMapPatternEntry(Pattern container, TreeNode entryElement) {
entryElement as MapPatternEntry;
void handleMapPatternEntry(Pattern container,
covariant MapPatternEntry entryElement, DartType keyType) {
Object? rewrite = popRewrite();
if (!identical(rewrite, entryElement.value)) {
entryElement.value = rewrite as Pattern..parent = entryElement;
@ -11352,6 +11351,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase
entryElement.key = (rewrite as Expression)..parent = entryElement;
}
entryElement.keyType = keyType;
pushRewrite(entryElement);
}

View file

@ -32,7 +32,7 @@ static method test() → dynamic {
core::int a1;
{
final synthesized dynamic #0#0 = self::foo();
final const synthesized dynamic #0#4 = invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
final const synthesized invalid-type #0#4 = invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
var {const C(:var t): a1} = foo();
^";
if(!(#0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && #0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::containsKey}(invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.

View file

@ -32,7 +32,7 @@ static method test() → dynamic {
core::int a1;
{
final synthesized dynamic #0#0 = self::foo();
final const synthesized dynamic #0#4 = invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
final const synthesized invalid-type #0#4 = invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
var {const C(:var t): a1} = foo();
^";
if(!(#0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && #0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::containsKey}(invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.

View file

@ -32,7 +32,7 @@ static method test() → dynamic {
core::int a1;
{
final synthesized dynamic #0#0 = self::foo();
final const synthesized dynamic #0#4 = invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
final const synthesized invalid-type #0#4 = invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
var {const C(:var t): a1} = foo();
^";
if(!(#0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && #0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::containsKey}(invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.

View file

@ -32,7 +32,7 @@ static method test() → dynamic {
core::int a1;
{
final synthesized dynamic #0#0 = self::foo();
final const synthesized dynamic #0#4 = invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
final const synthesized invalid-type #0#4 = invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
var {const C(:var t): a1} = foo();
^";
if(!(#0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && #0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::containsKey}(invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.

View file

@ -32,7 +32,7 @@ static method test() → dynamic {
core::int a1;
{
final synthesized dynamic #0#0 = self::foo();
final const synthesized dynamic #0#4 = invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
final const synthesized invalid-type #0#4 = invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.
var {const C(:var t): a1} = foo();
^";
if(!(#0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && #0#0{core::Map<self::C<core::String>, core::int>}.{core::Map::containsKey}(invalid-expression "pkg/front_end/testcases/patterns/parser_recovery_in_pattern_arguments.dart:13:14: Error: This couldn't be parsed.

View file

@ -33,8 +33,7 @@ class ConstantPattern extends Pattern {
Expression expression;
/// Static type of the expression as computed during inference.
// TODO(johnniwinther): Initialize this to `InvalidType.unsetType`.
DartType expressionType = const DynamicType();
DartType expressionType = InvalidType.unsetType;
/// Reference to the `operator ==` procedure on [expression].
///
@ -1435,8 +1434,7 @@ class MapPatternEntry extends TreeNode {
Expression key;
Pattern value;
// TODO(johnniwinther): Initialize this to `InvalidType.unsetType`.
DartType keyType = const DynamicType();
DartType keyType = InvalidType.unsetType;
MapPatternEntry(this.key, this.value) {
key.parent = this;