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

View file

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

View file

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

View file

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

View file

@ -32,7 +32,7 @@ static method test() → dynamic {
core::int a1; core::int a1;
{ {
final synthesized dynamic #0#0 = self::foo(); 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(); 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. 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; core::int a1;
{ {
final synthesized dynamic #0#0 = self::foo(); 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(); 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. 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; core::int a1;
{ {
final synthesized dynamic #0#0 = self::foo(); 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(); 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. 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; core::int a1;
{ {
final synthesized dynamic #0#0 = self::foo(); 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(); 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. 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; core::int a1;
{ {
final synthesized dynamic #0#0 = self::foo(); 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(); 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. 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; Expression expression;
/// Static type of the expression as computed during inference. /// Static type of the expression as computed during inference.
// TODO(johnniwinther): Initialize this to `InvalidType.unsetType`. DartType expressionType = InvalidType.unsetType;
DartType expressionType = const DynamicType();
/// Reference to the `operator ==` procedure on [expression]. /// Reference to the `operator ==` procedure on [expression].
/// ///
@ -1435,8 +1434,7 @@ class MapPatternEntry extends TreeNode {
Expression key; Expression key;
Pattern value; Pattern value;
// TODO(johnniwinther): Initialize this to `InvalidType.unsetType`. DartType keyType = InvalidType.unsetType;
DartType keyType = const DynamicType();
MapPatternEntry(this.key, this.value) { MapPatternEntry(this.key, this.value) {
key.parent = this; key.parent = this;