Skip to content

Commit

Permalink
Version 2.19.0-226.0.dev
Browse files Browse the repository at this point in the history
Merge 3e6050a into dev
  • Loading branch information
Dart CI committed Sep 21, 2022
2 parents 48fdf8d + 3e6050a commit 66b1c83
Show file tree
Hide file tree
Showing 29 changed files with 380 additions and 72 deletions.
67 changes: 59 additions & 8 deletions pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -803,8 +803,42 @@ class ConstantsTransformer extends RemovingTransformer {
TreeNode visitRecordLiteral(RecordLiteral node, TreeNode? removalSentinel) {
if (node.isConst) {
return evaluateAndTransformWithContext(node, node);
} else {
// A record literal is a compile-time constant expression if and only
// if all its field expressions are compile-time constant expressions.

bool allConstant = true;

List<Constant> positional = [];

for (int i = 0; i < node.positional.length; i++) {
Expression result = transform(node.positional[i]);
node.positional[i] = result..parent = node;
if (allConstant && result is ConstantExpression) {
positional.add(result.constant);
} else {
allConstant = false;
}
}

Map<String, Constant> named = {};
for (NamedExpression expression in node.named) {
Expression result = transform(expression.value);
expression.value = result..parent = expression;
if (allConstant && result is ConstantExpression) {
named[expression.name] = result.constant;
} else {
allConstant = false;
}
}

if (allConstant) {
Constant constant = constantEvaluator.canonicalize(
new RecordConstant(positional, named, node.recordType));
return makeConstantExpression(constant, node);
}
return node;
}
return super.visitRecordLiteral(node, removalSentinel);
}

@override
Expand Down Expand Up @@ -1505,12 +1539,12 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {

@override
Constant visitRecordLiteral(RecordLiteral node) {
if (!node.isConst) {
return createExpressionErrorConstant(
node,
templateNotConstantExpression
.withArguments('Non-constant record literal'));
}
// A record literal is a compile-time constant expression if and only
// if all its field expressions are compile-time constant expressions.
//
// This visitor is called when the context requires the literal to be
// constant, so we report an error on the expressions when these are not
// constants.

List<Constant>? positional = _evaluatePositionalArguments(node.positional);
if (positional == null) {
Expand Down Expand Up @@ -4679,7 +4713,7 @@ bool isInstantiated(DartType type) {
return type.accept(new IsInstantiatedVisitor());
}

class IsInstantiatedVisitor extends DartTypeVisitor<bool> {
class IsInstantiatedVisitor implements DartTypeVisitor<bool> {
final _availableVariables = new Set<TypeParameter>();

bool isInstantiated(DartType type) {
Expand Down Expand Up @@ -4739,6 +4773,23 @@ class IsInstantiatedVisitor extends DartTypeVisitor<bool> {

@override
bool visitNeverType(NeverType node) => true;

@override
bool visitRecordType(RecordType node) {
return node.positional.every((p) => p.accept(this)) &&
node.named.every((p) => p.type.accept(this));
}

@override
bool visitExtensionType(ExtensionType node) {
return node.typeArguments
.every((DartType typeArgument) => typeArgument.accept(this));
}

@override
bool visitIntersectionType(IntersectionType node) {
return node.left.accept(this) && node.right.accept(this);
}
}

bool _isFormalParameter(VariableDeclaration variable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ constants {
#C1 = 42
#C2 = <core::int>[#C1]
}

Extra constant evaluation status:
Evaluated: RecordLiteral @ org-dartlang-testcase:///issue50004.dart:6:7 -> RecordConstant(const (1, const <int>[42]))
Extra constant evaluation: evaluated: 1, effectively constant: 1
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ constants {
#C1 = 42
#C2 = <core::int*>[#C1]
}

Extra constant evaluation status:
Evaluated: RecordLiteral @ org-dartlang-testcase:///issue50004.dart:6:7 -> RecordConstant(const (1, const <int*>[42]))
Extra constant evaluation: evaluated: 1, effectively constant: 1
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,12 @@ static method method() → dynamic {
(0, {a: "", b: true}).a{core::String};
(0, {a: "", b: true}).b{core::bool};
}


Extra constant evaluation status:
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:6:11 -> RecordConstant(const (0, ""))
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:7:11 -> RecordConstant(const (0, ""))
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:8:23 -> RecordConstant(const (0, {a: "", b: true}))
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:9:23 -> RecordConstant(const (0, {a: "", b: true}))
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:10:23 -> RecordConstant(const (0, {a: "", b: true}))
Extra constant evaluation: evaluated: 10, effectively constant: 5
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,12 @@ static method method() → dynamic {
(0, {a: "", b: true}).a{core::String};
(0, {a: "", b: true}).b{core::bool};
}


Extra constant evaluation status:
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:6:11 -> RecordConstant(const (0, ""))
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:7:11 -> RecordConstant(const (0, ""))
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:8:23 -> RecordConstant(const (0, {a: "", b: true}))
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:9:23 -> RecordConstant(const (0, {a: "", b: true}))
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_get.dart:10:23 -> RecordConstant(const (0, {a: "", b: true}))
Extra constant evaluation: evaluated: 10, effectively constant: 5
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static method method() → dynamic {
(0, {b: 1});
({a: 0, b: 1});
let final core::int #t1 = 0 in (1, {a: #t1});
(#C1, #C2);
#C3;
}
static method sorting() → dynamic {
({a: 0, b: 1, c: 2, d: 3});
Expand All @@ -44,4 +44,5 @@ static method sorting() → dynamic {
constants {
#C1 = TypeLiteralConstant(core::int)
#C2 = TypeLiteralConstant(core::String)
const (#C1, #C2)
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static method method() → dynamic {
(0, {b: 1});
({a: 0, b: 1});
let final core::int #t1 = 0 in (1, {a: #t1});
(#C1, #C2);
#C3;
}
static method sorting() → dynamic {
({a: 0, b: 1, c: 2, d: 3});
Expand All @@ -44,35 +44,22 @@ static method sorting() → dynamic {
constants {
#C1 = TypeLiteralConstant(core::int)
#C2 = TypeLiteralConstant(core::String)
const (#C1, #C2)
}

Extra constant evaluation status:
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:10:7 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:16:7 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:16:13 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:16:19 -> IntConstant(2)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:17:7 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:17:19 -> IntConstant(2)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:17:13 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:18:13 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:18:19 -> IntConstant(2)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:18:7 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:20:4 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:20:7 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:20:13 -> IntConstant(2)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:21:4 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:21:7 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:21:13 -> IntConstant(2)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:21:19 -> IntConstant(3)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:4 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:7 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:13 -> IntConstant(2)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:19 -> IntConstant(3)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:25 -> IntConstant(4)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:23:4 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:23:13 -> IntConstant(2)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:23:10 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:24:10 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:24:13 -> IntConstant(2)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:24:7 -> IntConstant(0)
Extra constant evaluation: evaluated: 73, effectively constant: 28
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:7:9 -> RecordConstant(const (0, 1))
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:8:12 -> RecordConstant(const (0, {b: 1}))
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:9:15 -> RecordConstant(const ({a: 0, b: 1}))
Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:10:7 -> RecordConstant(const (1, {a: 0}))
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:15:27 -> RecordConstant(const ({a: 0, b: 1, c: 2, d: 3}))
Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:16:7 -> RecordConstant(const ({a: 0, b: 1, c: 3, d: 2}))
Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:17:7 -> RecordConstant(const ({a: 0, b: 2, c: 3, d: 1}))
Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:18:7 -> RecordConstant(const ({a: 1, b: 2, c: 3, d: 0}))
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:19:30 -> RecordConstant(const (0, 1, 2, {a: 3, b: 4, c: 5}))
Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:20:4 -> RecordConstant(const (0, 1, 3, {a: 2, b: 4, c: 5}))
Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:21:4 -> RecordConstant(const (0, 1, 4, {a: 2, b: 3, c: 5}))
Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:22:4 -> RecordConstant(const (0, 1, 5, {a: 2, b: 3, c: 4}))
Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:23:4 -> RecordConstant(const (0, 2, 3, {a: 1, b: 4, c: 5}))
Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:24:7 -> RecordConstant(const (1, 2, 3, {a: 0, b: 4, c: 5}))
Extra constant evaluation: evaluated: 16, effectively constant: 14
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static method method() → dynamic {
(0, {b: 1});
({a: 0, b: 1});
let final core::int #t1 = 0 in (1, {a: #t1});
(#C1, #C2);
#C3;
}
static method sorting() → dynamic {
({a: 0, b: 1, c: 2, d: 3});
Expand All @@ -44,4 +44,5 @@ static method sorting() → dynamic {
constants {
#C1 = TypeLiteralConstant(core::int*)
#C2 = TypeLiteralConstant(core::String*)
const (#C1, #C2)
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static method method() → dynamic {
(0, {b: 1});
({a: 0, b: 1});
let final core::int #t1 = 0 in (1, {a: #t1});
(#C1, #C2);
#C3;
}
static method sorting() → dynamic {
({a: 0, b: 1, c: 2, d: 3});
Expand All @@ -44,4 +44,5 @@ static method sorting() → dynamic {
constants {
#C1 = TypeLiteralConstant(core::int*)
#C2 = TypeLiteralConstant(core::String*)
const (#C1, #C2)
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static method method() → dynamic {
(0, {b: 1});
({a: 0, b: 1});
let final core::int #t1 = 0 in (1, {a: #t1});
(#C1, #C2);
#C3;
}
static method sorting() → dynamic {
({a: 0, b: 1, c: 2, d: 3});
Expand All @@ -44,35 +44,22 @@ static method sorting() → dynamic {
constants {
#C1 = TypeLiteralConstant(core::int*)
#C2 = TypeLiteralConstant(core::String*)
const (#C1, #C2)
}

Extra constant evaluation status:
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:10:7 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:16:7 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:16:13 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:16:19 -> IntConstant(2)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:17:7 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:17:19 -> IntConstant(2)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:17:13 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:18:13 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:18:19 -> IntConstant(2)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:18:7 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:20:4 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:20:7 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:20:13 -> IntConstant(2)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:21:4 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:21:7 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:21:13 -> IntConstant(2)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:21:19 -> IntConstant(3)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:4 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:7 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:13 -> IntConstant(2)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:19 -> IntConstant(3)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:22:25 -> IntConstant(4)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:23:4 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:23:13 -> IntConstant(2)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:23:10 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:24:10 -> IntConstant(1)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:24:13 -> IntConstant(2)
Evaluated: VariableGet @ org-dartlang-testcase:///record_literal.dart:24:7 -> IntConstant(0)
Extra constant evaluation: evaluated: 73, effectively constant: 28
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:7:9 -> RecordConstant(const (0, 1))
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:8:12 -> RecordConstant(const (0, {b: 1}))
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:9:15 -> RecordConstant(const ({a: 0, b: 1}))
Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:10:7 -> RecordConstant(const (1, {a: 0}))
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:15:27 -> RecordConstant(const ({a: 0, b: 1, c: 2, d: 3}))
Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:16:7 -> RecordConstant(const ({a: 0, b: 1, c: 3, d: 2}))
Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:17:7 -> RecordConstant(const ({a: 0, b: 2, c: 3, d: 1}))
Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:18:7 -> RecordConstant(const ({a: 1, b: 2, c: 3, d: 0}))
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_literal.dart:19:30 -> RecordConstant(const (0, 1, 2, {a: 3, b: 4, c: 5}))
Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:20:4 -> RecordConstant(const (0, 1, 3, {a: 2, b: 4, c: 5}))
Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:21:4 -> RecordConstant(const (0, 1, 4, {a: 2, b: 3, c: 5}))
Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:22:4 -> RecordConstant(const (0, 1, 5, {a: 2, b: 3, c: 4}))
Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:23:4 -> RecordConstant(const (0, 2, 3, {a: 1, b: 4, c: 5}))
Evaluated: Let @ org-dartlang-testcase:///record_literal.dart:24:7 -> RecordConstant(const (1, 2, 3, {a: 0, b: 4, c: 5}))
Extra constant evaluation: evaluated: 16, effectively constant: 14
12 changes: 12 additions & 0 deletions pkg/front_end/testcases/records/structurally_constant.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) 2022, 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 method1([a = (0, 1), b = (const <String>[], c: 'foo')]) {
(0, 1); // Const
(const <String>[], c: 'foo'); // Const
}

void method2({a = (0, 1), b = (const <String>[], c: 'foo')}) {
(<String>[], c: 'foo'); // Non-const
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;

static method method1([dynamic a = #C3, dynamic b = #C6]) → void {
(0, 1);
(#C4, {c: "foo"});
}
static method method2({dynamic a = #C3, dynamic b = #C6}) → void {
(<core::String>[], {c: "foo"});
}

constants {
#C1 = 0
#C2 = 1
const (#C1, #C2)
#C4 = <core::String>[]
#C5 = "foo"
const (#C4, {c:#C5})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;

static method method1([dynamic a = #C3, dynamic b = #C6]) → void {
(0, 1);
(#C4, {c: "foo"});
}
static method method2({dynamic a = #C3, dynamic b = #C6}) → void {
(core::_GrowableList::•<core::String>(0), {c: "foo"});
}

constants {
#C1 = 0
#C2 = 1
const (#C1, #C2)
#C4 = <core::String>[]
#C5 = "foo"
const (#C4, {c:#C5})
}

Extra constant evaluation status:
Evaluated: RecordLiteral @ org-dartlang-testcase:///structurally_constant.dart:6:9 -> RecordConstant(const (0, 1))
Evaluated: RecordLiteral @ org-dartlang-testcase:///structurally_constant.dart:7:31 -> RecordConstant(const (const <String>[], {c: "foo"}))
Extra constant evaluation: evaluated: 4, effectively constant: 2
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
void method1([a = (0, 1), b = (const <String>[], c: 'foo')]) {}
void method2({a = (0, 1), b = (const <String>[], c: 'foo')}) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;

static method method1([dynamic a = #C3, dynamic b = #C6]) → void {
(0, 1);
(#C4, {c: "foo"});
}
static method method2({dynamic a = #C3, dynamic b = #C6}) → void {
(<core::String>[], {c: "foo"});
}

constants {
#C1 = 0
#C2 = 1
const (#C1, #C2)
#C4 = <core::String*>[]
#C5 = "foo"
const (#C4, {c:#C5})
}
Loading

0 comments on commit 66b1c83

Please sign in to comment.