Skip to content

Commit

Permalink
[cfe] Handle extension types in *Concatenation nodes
Browse files Browse the repository at this point in the history
Closes #54357

Change-Id: Ie5ff5c6c61c537658dcc6715054ff82c6f8537c4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/341961
Reviewed-by: Jens Johansen <[email protected]>
Commit-Queue: Johnni Winther <[email protected]>
  • Loading branch information
johnniwinther authored and Commit Queue committed Dec 19, 2023
1 parent f49c786 commit 8d8c4c6
Show file tree
Hide file tree
Showing 11 changed files with 453 additions and 3 deletions.
34 changes: 31 additions & 3 deletions pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3089,8 +3089,15 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {

@override
Constant visitListConcatenation(ListConcatenation node) {
DartType? type = _evaluateDartType(node, node.typeArgument);
if (type == null) {
AbortConstant error = _gotError!;
_gotError = null;
return error;
}
assert(_gotError == null);
final ListConstantBuilder builder =
new ListConstantBuilder(node, convertType(node.typeArgument), this);
new ListConstantBuilder(node, convertType(type), this);
for (Expression list in node.lists) {
AbortConstant? error = builder.addSpread(list);
if (error != null) return error;
Expand Down Expand Up @@ -3134,8 +3141,15 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {

@override
Constant visitSetConcatenation(SetConcatenation node) {
DartType? type = _evaluateDartType(node, node.typeArgument);
if (type == null) {
AbortConstant error = _gotError!;
_gotError = null;
return error;
}
assert(_gotError == null);
final SetConstantBuilder builder =
new SetConstantBuilder(node, convertType(node.typeArgument), this);
new SetConstantBuilder(node, convertType(type), this);
for (Expression set_ in node.sets) {
AbortConstant? error = builder.addSpread(set_);
if (error != null) return error;
Expand Down Expand Up @@ -3187,8 +3201,22 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {

@override
Constant visitMapConcatenation(MapConcatenation node) {
DartType? keyType = _evaluateDartType(node, node.keyType);
if (keyType == null) {
AbortConstant error = _gotError!;
_gotError = null;
return error;
}
assert(_gotError == null);
DartType? valueType = _evaluateDartType(node, node.valueType);
if (valueType == null) {
AbortConstant error = _gotError!;
_gotError = null;
return error;
}
assert(_gotError == null);
final MapConstantBuilder builder = new MapConstantBuilder(
node, convertType(node.keyType), convertType(node.valueType), this);
node, convertType(keyType), convertType(valueType), this);
for (Expression map in node.maps) {
AbortConstant? error = builder.addSpread(map);
if (error != null) return error;
Expand Down
2 changes: 2 additions & 0 deletions pkg/front_end/test/spell_checking_list_tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ estat
et
everytime
evicting
ex
examines
exceed
excess
Expand Down Expand Up @@ -705,6 +706,7 @@ splitting
spurious
sqrt
squared
ss
sssp
stacks
stashed
Expand Down
32 changes: 32 additions & 0 deletions pkg/front_end/testcases/extension_types/issue54357.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// 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.

const ex3 = ExInt(3);
const ex4 = ExInt(4);

const l3 = [ex3];
const l4 = [ex4];
const l34i = [ex3 as int, ... l4 as List<int>];
const l43 = [ex4, ex3];
const l3s4 = [ex3, ... l4];
const ls43 = [... l4, ex3];
const ls3s4 = [... l3, ... l4];

const s3 = {ex3};
const s4 = {ex4};
const s34i = {ex3 as int, ... s4 as Set<int>};
const s43 = {ex4, ex3};
const s3s4 = {ex3, ... s4};
const ss43 = {... s4, ex3};
const ss3s4 = {... s3, ... s4};

const m3 = {ex3: ex3};
const m4 = {ex4: ex4};
const m34i = {ex3 as int: ex3 as int, ... m4 as Map<int, int>};
const m43 = {ex4: ex4, ex3: ex3};
const m3s4 = {ex3: ex3, ... m4};
const ms43 = {... m4, ex3: ex3};
const ms3s4 = {... m3, ... m4};

extension type const ExInt(int _) implements int {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
library;
import self as self;
import "dart:core" as core;

extension type ExInt(core::int _) implements core::int {
abstract extension-type-member representation-field get _() → core::int;
constructor • = self::ExInt|constructor#;
constructor tearoff • = self::ExInt|constructor#_#new#tearOff;
}
static const field self::ExInt /* = core::int */ ex3 = #C1;
static const field self::ExInt /* = core::int */ ex4 = #C2;
static const field core::List<self::ExInt /* = core::int */> l3 = #C3;
static const field core::List<self::ExInt /* = core::int */> l4 = #C4;
static const field core::List<core::int> l34i = #C5;
static const field core::List<self::ExInt /* = core::int */> l43 = #C6;
static const field core::List<self::ExInt /* = core::int */> l3s4 = #C5;
static const field core::List<self::ExInt /* = core::int */> ls43 = #C6;
static const field core::List<self::ExInt /* = core::int */> ls3s4 = #C5;
static const field core::Set<self::ExInt /* = core::int */> s3 = #C7;
static const field core::Set<self::ExInt /* = core::int */> s4 = #C8;
static const field core::Set<core::int> s34i = #C9;
static const field core::Set<self::ExInt /* = core::int */> s43 = #C10;
static const field core::Set<self::ExInt /* = core::int */> s3s4 = #C9;
static const field core::Set<self::ExInt /* = core::int */> ss43 = #C10;
static const field core::Set<self::ExInt /* = core::int */> ss3s4 = #C9;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> m3 = #C11;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> m4 = #C12;
static const field core::Map<core::int, core::int> m34i = #C13;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> m43 = #C14;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> m3s4 = #C13;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> ms43 = #C14;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> ms3s4 = #C13;
static extension-type-member method ExInt|constructor#(core::int _) → self::ExInt /* = core::int */ {
lowered final self::ExInt /* = core::int */ #this = _;
return #this;
}
static extension-type-member method ExInt|constructor#_#new#tearOff(core::int _) → self::ExInt /* = core::int */
return self::ExInt|constructor#(_);

constants {
#C1 = 3
#C2 = 4
#C3 = <core::int>[#C1]
#C4 = <core::int>[#C2]
#C5 = <core::int>[#C1, #C2]
#C6 = <core::int>[#C2, #C1]
#C7 = <core::int>{#C1}
#C8 = <core::int>{#C2}
#C9 = <core::int>{#C1, #C2}
#C10 = <core::int>{#C2, #C1}
#C11 = <core::int, core::int>{#C1:#C1}
#C12 = <core::int, core::int>{#C2:#C2}
#C13 = <core::int, core::int>{#C1:#C1, #C2:#C2}
#C14 = <core::int, core::int>{#C2:#C2, #C1:#C1}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
library;
import self as self;
import "dart:core" as core;

extension type ExInt(core::int _) implements core::int {
abstract extension-type-member representation-field get _() → core::int;
constructor • = self::ExInt|constructor#;
constructor tearoff • = self::ExInt|constructor#_#new#tearOff;
}
static const field self::ExInt /* = core::int */ ex3 = #C1;
static const field self::ExInt /* = core::int */ ex4 = #C2;
static const field core::List<self::ExInt /* = core::int */> l3 = #C3;
static const field core::List<self::ExInt /* = core::int */> l4 = #C4;
static const field core::List<core::int> l34i = #C5;
static const field core::List<self::ExInt /* = core::int */> l43 = #C6;
static const field core::List<self::ExInt /* = core::int */> l3s4 = #C5;
static const field core::List<self::ExInt /* = core::int */> ls43 = #C6;
static const field core::List<self::ExInt /* = core::int */> ls3s4 = #C5;
static const field core::Set<self::ExInt /* = core::int */> s3 = #C7;
static const field core::Set<self::ExInt /* = core::int */> s4 = #C8;
static const field core::Set<core::int> s34i = #C9;
static const field core::Set<self::ExInt /* = core::int */> s43 = #C10;
static const field core::Set<self::ExInt /* = core::int */> s3s4 = #C9;
static const field core::Set<self::ExInt /* = core::int */> ss43 = #C10;
static const field core::Set<self::ExInt /* = core::int */> ss3s4 = #C9;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> m3 = #C11;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> m4 = #C12;
static const field core::Map<core::int, core::int> m34i = #C13;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> m43 = #C14;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> m3s4 = #C13;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> ms43 = #C14;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> ms3s4 = #C13;
static extension-type-member method ExInt|constructor#(core::int _) → self::ExInt /* = core::int */ {
lowered final self::ExInt /* = core::int */ #this = _;
return #this;
}
static extension-type-member method ExInt|constructor#_#new#tearOff(core::int _) → self::ExInt /* = core::int */
return self::ExInt|constructor#(_);

constants {
#C1 = 3
#C2 = 4
#C3 = <core::int>[#C1]
#C4 = <core::int>[#C2]
#C5 = <core::int>[#C1, #C2]
#C6 = <core::int>[#C2, #C1]
#C7 = <core::int>{#C1}
#C8 = <core::int>{#C2}
#C9 = <core::int>{#C1, #C2}
#C10 = <core::int>{#C2, #C1}
#C11 = <core::int, core::int>{#C1:#C1}
#C12 = <core::int, core::int>{#C2:#C2}
#C13 = <core::int, core::int>{#C1:#C1, #C2:#C2}
#C14 = <core::int, core::int>{#C2:#C2, #C1:#C1}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const ex3 = ExInt(3);
const ex4 = ExInt(4);
const l3 = [ex3];
const l4 = [ex4];
const l34i = [ex3 as int, ...l4 as List<int>];
const l43 = [ex4, ex3];
const l3s4 = [ex3, ...l4];
const ls43 = [...l4, ex3];
const ls3s4 = [...l3, ...l4];
const s3 = {ex3};
const s4 = {ex4};
const s34i = {ex3 as int, ...s4 as Set<int>};
const s43 = {ex4, ex3};
const s3s4 = {ex3, ...s4};
const ss43 = {...s4, ex3};
const ss3s4 = {...s3, ...s4};
const m3 = {ex3: ex3};
const m4 = {ex4: ex4};
const m34i = {ex3 as int: ex3 as int, ...m4 as Map<int, int>};
const m43 = {ex4: ex4, ex3: ex3};
const m3s4 = {ex3: ex3, ...m4};
const ms43 = {...m4, ex3: ex3};
const ms3s4 = {...m3, ...m4};
extension type const ExInt(int _) implements int {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const ex3 = ExInt(3);
const ex4 = ExInt(4);
const l3 = [ex3];
const l34i = [ex3 as int, ...l4 as List<int>];
const l3s4 = [ex3, ...l4];
const l4 = [ex4];
const l43 = [ex4, ex3];
const ls3s4 = [...l3, ...l4];
const ls43 = [...l4, ex3];
const m3 = {ex3: ex3};
const m34i = {ex3 as int: ex3 as int, ...m4 as Map<int, int>};
const m3s4 = {ex3: ex3, ...m4};
const m4 = {ex4: ex4};
const m43 = {ex4: ex4, ex3: ex3};
const ms3s4 = {...m3, ...m4};
const ms43 = {...m4, ex3: ex3};
const s3 = {ex3};
const s34i = {ex3 as int, ...s4 as Set<int>};
const s3s4 = {ex3, ...s4};
const s4 = {ex4};
const s43 = {ex4, ex3};
const ss3s4 = {...s3, ...s4};
const ss43 = {...s4, ex3};
extension type const ExInt(int _) implements int {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
library;
import self as self;
import "dart:core" as core;

extension type ExInt(core::int _) implements core::int {
abstract extension-type-member representation-field get _() → core::int;
constructor • = self::ExInt|constructor#;
constructor tearoff • = self::ExInt|constructor#_#new#tearOff;
}
static const field self::ExInt /* = core::int */ ex3 = #C1;
static const field self::ExInt /* = core::int */ ex4 = #C2;
static const field core::List<self::ExInt /* = core::int */> l3 = #C3;
static const field core::List<self::ExInt /* = core::int */> l4 = #C4;
static const field core::List<core::int> l34i = #C5;
static const field core::List<self::ExInt /* = core::int */> l43 = #C6;
static const field core::List<self::ExInt /* = core::int */> l3s4 = #C5;
static const field core::List<self::ExInt /* = core::int */> ls43 = #C6;
static const field core::List<self::ExInt /* = core::int */> ls3s4 = #C5;
static const field core::Set<self::ExInt /* = core::int */> s3 = #C7;
static const field core::Set<self::ExInt /* = core::int */> s4 = #C8;
static const field core::Set<core::int> s34i = #C9;
static const field core::Set<self::ExInt /* = core::int */> s43 = #C10;
static const field core::Set<self::ExInt /* = core::int */> s3s4 = #C9;
static const field core::Set<self::ExInt /* = core::int */> ss43 = #C10;
static const field core::Set<self::ExInt /* = core::int */> ss3s4 = #C9;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> m3 = #C11;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> m4 = #C12;
static const field core::Map<core::int, core::int> m34i = #C13;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> m43 = #C14;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> m3s4 = #C13;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> ms43 = #C14;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> ms3s4 = #C13;
static extension-type-member method ExInt|constructor#(core::int _) → self::ExInt /* = core::int */ {
lowered final self::ExInt /* = core::int */ #this = _;
return #this;
}
static extension-type-member method ExInt|constructor#_#new#tearOff(core::int _) → self::ExInt /* = core::int */
return self::ExInt|constructor#(_);

constants {
#C1 = 3
#C2 = 4
#C3 = <core::int*>[#C1]
#C4 = <core::int*>[#C2]
#C5 = <core::int*>[#C1, #C2]
#C6 = <core::int*>[#C2, #C1]
#C7 = <core::int*>{#C1}
#C8 = <core::int*>{#C2}
#C9 = <core::int*>{#C1, #C2}
#C10 = <core::int*>{#C2, #C1}
#C11 = <core::int*, core::int*>{#C1:#C1}
#C12 = <core::int*, core::int*>{#C2:#C2}
#C13 = <core::int*, core::int*>{#C1:#C1, #C2:#C2}
#C14 = <core::int*, core::int*>{#C2:#C2, #C1:#C1}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
library;
import self as self;
import "dart:core" as core;

extension type ExInt(core::int _) implements core::int {
abstract extension-type-member representation-field get _() → core::int;
constructor • = self::ExInt|constructor#;
constructor tearoff • = self::ExInt|constructor#_#new#tearOff;
}
static const field self::ExInt /* = core::int */ ex3 = #C1;
static const field self::ExInt /* = core::int */ ex4 = #C2;
static const field core::List<self::ExInt /* = core::int */> l3 = #C3;
static const field core::List<self::ExInt /* = core::int */> l4 = #C4;
static const field core::List<core::int> l34i = #C5;
static const field core::List<self::ExInt /* = core::int */> l43 = #C6;
static const field core::List<self::ExInt /* = core::int */> l3s4 = #C5;
static const field core::List<self::ExInt /* = core::int */> ls43 = #C6;
static const field core::List<self::ExInt /* = core::int */> ls3s4 = #C5;
static const field core::Set<self::ExInt /* = core::int */> s3 = #C7;
static const field core::Set<self::ExInt /* = core::int */> s4 = #C8;
static const field core::Set<core::int> s34i = #C9;
static const field core::Set<self::ExInt /* = core::int */> s43 = #C10;
static const field core::Set<self::ExInt /* = core::int */> s3s4 = #C9;
static const field core::Set<self::ExInt /* = core::int */> ss43 = #C10;
static const field core::Set<self::ExInt /* = core::int */> ss3s4 = #C9;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> m3 = #C11;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> m4 = #C12;
static const field core::Map<core::int, core::int> m34i = #C13;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> m43 = #C14;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> m3s4 = #C13;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> ms43 = #C14;
static const field core::Map<self::ExInt /* = core::int */, self::ExInt /* = core::int */> ms3s4 = #C13;
static extension-type-member method ExInt|constructor#(core::int _) → self::ExInt /* = core::int */ {
lowered final self::ExInt /* = core::int */ #this = _;
return #this;
}
static extension-type-member method ExInt|constructor#_#new#tearOff(core::int _) → self::ExInt /* = core::int */
return self::ExInt|constructor#(_);

constants {
#C1 = 3
#C2 = 4
#C3 = <core::int*>[#C1]
#C4 = <core::int*>[#C2]
#C5 = <core::int*>[#C1, #C2]
#C6 = <core::int*>[#C2, #C1]
#C7 = <core::int*>{#C1}
#C8 = <core::int*>{#C2}
#C9 = <core::int*>{#C1, #C2}
#C10 = <core::int*>{#C2, #C1}
#C11 = <core::int*, core::int*>{#C1:#C1}
#C12 = <core::int*, core::int*>{#C2:#C2}
#C13 = <core::int*, core::int*>{#C1:#C1, #C2:#C2}
#C14 = <core::int*, core::int*>{#C2:#C2, #C1:#C1}
}
Loading

0 comments on commit 8d8c4c6

Please sign in to comment.