[cfe] Handle multiple named record fields in constants
This bypasses the hoisting of record elements in constant record literals. The created let variables would otherwise interfere with the constant evaluation. Closes #49915 Change-Id: Ia70387a0f0c435373dc5fcf5cdd526104db8f394 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/258363 Reviewed-by: Chloe Stefantsova <cstefantsova@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
committed by
Commit Bot
parent
51c4e03928
commit
96d52d4e35
@@ -7317,6 +7317,12 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
// Index into [positional] of the positional element we find next.
|
||||
int positionalIndex = positional.length - 1;
|
||||
|
||||
// For const literals we don't hoist to avoid using let variables in
|
||||
// inside constants. Since the elements of the literal must be constant
|
||||
// themselves, we know that there is no side effects of performing
|
||||
// constant evaluation out of order.
|
||||
final bool enableHoisting = !node.isConst;
|
||||
|
||||
// Set to `true` if we need to hoist all preceding elements.
|
||||
bool needsHoisting = false;
|
||||
|
||||
@@ -7355,7 +7361,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
if (!namedNeedsSorting && element.name != sortedNames[nameIndex]) {
|
||||
// Named elements are not sorted, so we need to hoist and sort them.
|
||||
namedNeedsSorting = true;
|
||||
needsHoisting = true;
|
||||
needsHoisting = enableHoisting;
|
||||
}
|
||||
nameIndex--;
|
||||
} else {
|
||||
@@ -7381,7 +7387,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
if (nameIndex >= 0) {
|
||||
// We have not seen all named elements yet, so we must hoist the
|
||||
// remaining named elements and the preceding positional elements.
|
||||
needsHoisting = true;
|
||||
needsHoisting = enableHoisting;
|
||||
}
|
||||
}
|
||||
positionalTypes[positionalIndex] = type;
|
||||
|
||||
@@ -3,11 +3,19 @@
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
const dynamic a = (1, 2);
|
||||
const dynamic b = (a: 1, b: 2);
|
||||
const dynamic c = (a: a, b: b);
|
||||
const dynamic d = (c, (1, 2));
|
||||
const dynamic b1 = (a: 1, b: 2);
|
||||
const dynamic b2 = (b: 2, a: 1);
|
||||
const dynamic b3 = (b: 2, 1);
|
||||
const dynamic c1 = (a: a, b: b1);
|
||||
const dynamic c2 = (b: b2, a: a);
|
||||
const dynamic c3 = (b: b3, a);
|
||||
const dynamic d = (c1, (1, 2));
|
||||
|
||||
dynamic e = const (1, 2);
|
||||
dynamic f = const (a: 1, b: 2);
|
||||
dynamic g = const (a: a, b: b);
|
||||
dynamic h = const (c, (1, 2));
|
||||
dynamic f1 = const (a: 1, b: 2);
|
||||
dynamic f2 = const (b: 2, a: 1);
|
||||
dynamic f3 = const (b: 2, 1);
|
||||
dynamic g1 = const (a: a, b: b1);
|
||||
dynamic g2 = const (b: b2, a: a);
|
||||
dynamic g3 = const (b: b3, a);
|
||||
dynamic h = const (c1, (1, 2));
|
||||
|
||||
@@ -3,19 +3,29 @@ import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
static const field dynamic a = #C3;
|
||||
static const field dynamic b = #C4;
|
||||
static const field dynamic c = #C5;
|
||||
static const field dynamic d = #C6;
|
||||
static const field dynamic b1 = #C4;
|
||||
static const field dynamic b2 = #C4;
|
||||
static const field dynamic b3 = #C5;
|
||||
static const field dynamic c1 = #C6;
|
||||
static const field dynamic c2 = #C6;
|
||||
static const field dynamic c3 = #C7;
|
||||
static const field dynamic d = #C8;
|
||||
static field dynamic e = #C3;
|
||||
static field dynamic f = #C4;
|
||||
static field dynamic g = #C5;
|
||||
static field dynamic h = #C6;
|
||||
static field dynamic f1 = #C4;
|
||||
static field dynamic f2 = #C4;
|
||||
static field dynamic f3 = #C5;
|
||||
static field dynamic g1 = #C6;
|
||||
static field dynamic g2 = #C6;
|
||||
static field dynamic g3 = #C7;
|
||||
static field dynamic h = #C8;
|
||||
|
||||
constants {
|
||||
#C1 = 1
|
||||
#C2 = 2
|
||||
const (#C1, #C2)
|
||||
const ({a:#C1, b:#C2})
|
||||
const (#C1, {b:#C2})
|
||||
const ({a:#C3, b:#C4})
|
||||
const (#C5, #C3)
|
||||
const (#C3, {b:#C5})
|
||||
const (#C6, #C3)
|
||||
}
|
||||
|
||||
+17
-7
@@ -3,19 +3,29 @@ import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
static const field dynamic a = #C3;
|
||||
static const field dynamic b = #C4;
|
||||
static const field dynamic c = #C5;
|
||||
static const field dynamic d = #C6;
|
||||
static const field dynamic b1 = #C4;
|
||||
static const field dynamic b2 = #C4;
|
||||
static const field dynamic b3 = #C5;
|
||||
static const field dynamic c1 = #C6;
|
||||
static const field dynamic c2 = #C6;
|
||||
static const field dynamic c3 = #C7;
|
||||
static const field dynamic d = #C8;
|
||||
static field dynamic e = #C3;
|
||||
static field dynamic f = #C4;
|
||||
static field dynamic g = #C5;
|
||||
static field dynamic h = #C6;
|
||||
static field dynamic f1 = #C4;
|
||||
static field dynamic f2 = #C4;
|
||||
static field dynamic f3 = #C5;
|
||||
static field dynamic g1 = #C6;
|
||||
static field dynamic g2 = #C6;
|
||||
static field dynamic g3 = #C7;
|
||||
static field dynamic h = #C8;
|
||||
|
||||
constants {
|
||||
#C1 = 1
|
||||
#C2 = 2
|
||||
const (#C1, #C2)
|
||||
const ({a:#C1, b:#C2})
|
||||
const (#C1, {b:#C2})
|
||||
const ({a:#C3, b:#C4})
|
||||
const (#C5, #C3)
|
||||
const (#C3, {b:#C5})
|
||||
const (#C6, #C3)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
const dynamic a = (1, 2);
|
||||
const dynamic b = (a: 1, b: 2);
|
||||
const dynamic c = (a: a, b: b);
|
||||
const dynamic d = (c, (1, 2));
|
||||
const dynamic b1 = (a: 1, b: 2);
|
||||
const dynamic b2 = (b: 2, a: 1);
|
||||
const dynamic b3 = (b: 2, 1);
|
||||
const dynamic c1 = (a: a, b: b1);
|
||||
const dynamic c2 = (b: b2, a: a);
|
||||
const dynamic c3 = (b: b3, a);
|
||||
const dynamic d = (c1, (1, 2));
|
||||
dynamic e = const (1, 2);
|
||||
dynamic f = const (a: 1, b: 2);
|
||||
dynamic g = const (a: a, b: b);
|
||||
dynamic h = const (c, (1, 2));
|
||||
dynamic f1 = const (a: 1, b: 2);
|
||||
dynamic f2 = const (b: 2, a: 1);
|
||||
dynamic f3 = const (b: 2, 1);
|
||||
dynamic g1 = const (a: a, b: b1);
|
||||
dynamic g2 = const (b: b2, a: a);
|
||||
dynamic g3 = const (b: b3, a);
|
||||
dynamic h = const (c1, (1, 2));
|
||||
|
||||
@@ -3,19 +3,29 @@ import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
static const field dynamic a = #C3;
|
||||
static const field dynamic b = #C4;
|
||||
static const field dynamic c = #C5;
|
||||
static const field dynamic d = #C6;
|
||||
static const field dynamic b1 = #C4;
|
||||
static const field dynamic b2 = #C4;
|
||||
static const field dynamic b3 = #C5;
|
||||
static const field dynamic c1 = #C6;
|
||||
static const field dynamic c2 = #C6;
|
||||
static const field dynamic c3 = #C7;
|
||||
static const field dynamic d = #C8;
|
||||
static field dynamic e = #C3;
|
||||
static field dynamic f = #C4;
|
||||
static field dynamic g = #C5;
|
||||
static field dynamic h = #C6;
|
||||
static field dynamic f1 = #C4;
|
||||
static field dynamic f2 = #C4;
|
||||
static field dynamic f3 = #C5;
|
||||
static field dynamic g1 = #C6;
|
||||
static field dynamic g2 = #C6;
|
||||
static field dynamic g3 = #C7;
|
||||
static field dynamic h = #C8;
|
||||
|
||||
constants {
|
||||
#C1 = 1
|
||||
#C2 = 2
|
||||
const (#C1, #C2)
|
||||
const ({a:#C1, b:#C2})
|
||||
const (#C1, {b:#C2})
|
||||
const ({a:#C3, b:#C4})
|
||||
const (#C5, #C3)
|
||||
const (#C3, {b:#C5})
|
||||
const (#C6, #C3)
|
||||
}
|
||||
|
||||
@@ -3,19 +3,29 @@ import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
static const field dynamic a = #C3;
|
||||
static const field dynamic b = #C4;
|
||||
static const field dynamic c = #C5;
|
||||
static const field dynamic d = #C6;
|
||||
static const field dynamic b1 = #C4;
|
||||
static const field dynamic b2 = #C4;
|
||||
static const field dynamic b3 = #C5;
|
||||
static const field dynamic c1 = #C6;
|
||||
static const field dynamic c2 = #C6;
|
||||
static const field dynamic c3 = #C7;
|
||||
static const field dynamic d = #C8;
|
||||
static field dynamic e = #C3;
|
||||
static field dynamic f = #C4;
|
||||
static field dynamic g = #C5;
|
||||
static field dynamic h = #C6;
|
||||
static field dynamic f1 = #C4;
|
||||
static field dynamic f2 = #C4;
|
||||
static field dynamic f3 = #C5;
|
||||
static field dynamic g1 = #C6;
|
||||
static field dynamic g2 = #C6;
|
||||
static field dynamic g3 = #C7;
|
||||
static field dynamic h = #C8;
|
||||
|
||||
constants {
|
||||
#C1 = 1
|
||||
#C2 = 2
|
||||
const (#C1, #C2)
|
||||
const ({a:#C1, b:#C2})
|
||||
const (#C1, {b:#C2})
|
||||
const ({a:#C3, b:#C4})
|
||||
const (#C5, #C3)
|
||||
const (#C3, {b:#C5})
|
||||
const (#C6, #C3)
|
||||
}
|
||||
|
||||
@@ -3,18 +3,30 @@ import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
static const field dynamic a = const (1, 2);
|
||||
static const field dynamic b = const ({a: 1, b: 2});
|
||||
static const field dynamic c = const ({a: self::a, b: self::b});
|
||||
static const field dynamic d = const (self::c, const (1, 2));
|
||||
static const field dynamic b1 = const ({a: 1, b: 2});
|
||||
static const field dynamic b2 = const ({a: 1, b: 2});
|
||||
static const field dynamic b3 = const (1, {b: 2});
|
||||
static const field dynamic c1 = const ({a: self::a, b: self::b1});
|
||||
static const field dynamic c2 = const ({a: self::a, b: self::b2});
|
||||
static const field dynamic c3 = const (self::a, {b: self::b3});
|
||||
static const field dynamic d = const (self::c1, const (1, 2));
|
||||
static field dynamic e;
|
||||
static field dynamic f;
|
||||
static field dynamic g;
|
||||
static field dynamic f1;
|
||||
static field dynamic f2;
|
||||
static field dynamic f3;
|
||||
static field dynamic g1;
|
||||
static field dynamic g2;
|
||||
static field dynamic g3;
|
||||
static field dynamic h;
|
||||
|
||||
|
||||
Extra constant evaluation status:
|
||||
Evaluated: RecordLiteral @ org-dartlang-testcase:///const_record_literal.dart:5:15 -> RecordConstant(const (1, 2))
|
||||
Evaluated: RecordLiteral @ org-dartlang-testcase:///const_record_literal.dart:6:15 -> RecordConstant(const ({a: 1, b: 2}))
|
||||
Evaluated: RecordLiteral @ org-dartlang-testcase:///const_record_literal.dart:7:15 -> RecordConstant(const ({a: const (1, 2), b: const ({a: 1, b: 2})}))
|
||||
Evaluated: RecordLiteral @ org-dartlang-testcase:///const_record_literal.dart:8:15 -> RecordConstant(const (const ({a: const (1, 2), b: const ({a: 1, b: 2})}), const (1, 2)))
|
||||
Extra constant evaluation: evaluated: 4, effectively constant: 4
|
||||
Evaluated: RecordLiteral @ org-dartlang-testcase:///const_record_literal.dart:7:15 -> RecordConstant(const ({a: 1, b: 2}))
|
||||
Evaluated: RecordLiteral @ org-dartlang-testcase:///const_record_literal.dart:8:15 -> RecordConstant(const (1, {b: 2}))
|
||||
Evaluated: RecordLiteral @ org-dartlang-testcase:///const_record_literal.dart:9:15 -> RecordConstant(const ({a: const (1, 2), b: const ({a: 1, b: 2})}))
|
||||
Evaluated: RecordLiteral @ org-dartlang-testcase:///const_record_literal.dart:10:15 -> RecordConstant(const ({a: const (1, 2), b: const ({a: 1, b: 2})}))
|
||||
Evaluated: RecordLiteral @ org-dartlang-testcase:///const_record_literal.dart:11:15 -> RecordConstant(const (const (1, 2), {b: const (1, {b: 2})}))
|
||||
Evaluated: RecordLiteral @ org-dartlang-testcase:///const_record_literal.dart:12:15 -> RecordConstant(const (const ({a: const (1, 2), b: const ({a: 1, b: 2})}), const (1, 2)))
|
||||
Extra constant evaluation: evaluated: 8, effectively constant: 8
|
||||
|
||||
@@ -3,19 +3,29 @@ import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
static const field dynamic a = #C3;
|
||||
static const field dynamic b = #C4;
|
||||
static const field dynamic c = #C5;
|
||||
static const field dynamic d = #C6;
|
||||
static const field dynamic b1 = #C4;
|
||||
static const field dynamic b2 = #C4;
|
||||
static const field dynamic b3 = #C5;
|
||||
static const field dynamic c1 = #C6;
|
||||
static const field dynamic c2 = #C6;
|
||||
static const field dynamic c3 = #C7;
|
||||
static const field dynamic d = #C8;
|
||||
static field dynamic e = #C3;
|
||||
static field dynamic f = #C4;
|
||||
static field dynamic g = #C5;
|
||||
static field dynamic h = #C6;
|
||||
static field dynamic f1 = #C4;
|
||||
static field dynamic f2 = #C4;
|
||||
static field dynamic f3 = #C5;
|
||||
static field dynamic g1 = #C6;
|
||||
static field dynamic g2 = #C6;
|
||||
static field dynamic g3 = #C7;
|
||||
static field dynamic h = #C8;
|
||||
|
||||
constants {
|
||||
#C1 = 1
|
||||
#C2 = 2
|
||||
const (#C1, #C2)
|
||||
const ({a:#C1, b:#C2})
|
||||
const (#C1, {b:#C2})
|
||||
const ({a:#C3, b:#C4})
|
||||
const (#C5, #C3)
|
||||
const (#C3, {b:#C5})
|
||||
const (#C6, #C3)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user