[modular_aot] Fix simplification of string interpolation

Issue: https://github.com/dart-lang/sdk/issues/61635
Change-Id: I6404c761f9849a50ee25c0387557c20c7b4d632c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/508700
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Alexander Markov
2026-06-03 12:12:19 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent 8b77454b37
commit 42ebe08081
3 changed files with 44 additions and 1 deletions
+12 -1
View File
@@ -256,6 +256,10 @@ final class Simplification extends Pass
Instruction visitStringInterpolation(StringInterpolation instr) {
final buf = _StringInterpolationBuffer(constantFolding);
buf.addStringInterpolation(instr);
assert(buf.consumed.isEmpty || buf.optimized);
for (final i in buf.consumed) {
i.removeFromGraph();
}
if (buf.inputs.length == 1) {
final input = buf.inputs.single;
if (input is String) {
@@ -633,6 +637,9 @@ class _StringInterpolationBuffer {
// Contains either String or Definition.
final List<Object> inputs = [];
// Consumed StringInterpolation instructions.
final List<StringInterpolation> consumed = [];
bool optimized = false;
_StringInterpolationBuffer(this.constantFolding);
@@ -669,7 +676,11 @@ class _StringInterpolationBuffer {
break;
case StringInterpolation() when input.singleUser == instr:
addStringInterpolation(input);
input.removeFromGraph();
// Do not remove the consumed instruction from the graph immediately,
// as removal may change "has single user" property.
// As a result, instruction which is used multiple times would be both added
// as input and removed, leaving the graph in the inconsistent state.
consumed.add(input);
optimized = true;
break;
default:
+11
View File
@@ -119,6 +119,17 @@ void stringInterpolation(int x) {
print('enclosing start... ${'some nested $s, x=$x'} ...end');
}
void stringInterpolation2(List<String> x) {
var path = '${x[0]}${x[1]}';
var right = 'prefix1:$path';
var wrong = 'prefix2:$path';
print(
'A very very looooooooooooooooooooooooooooong prefix: '
"'$right', not '$wrong'.",
);
}
void closureCall() {
final x = (int arg) {
print(arg);
@@ -219,6 +219,27 @@ B0 = EntryBlock()
DirectCall print(v43)
Return(v12)
--- stringInterpolation2
B0 = EntryBlock()
v3 = Constant(0)
v6 = Constant(1)
Constant("prefix1:")
Constant("prefix2:")
Constant("A very very looooooooooooooooooooooooooooong prefix: ")
Constant("'")
Constant("', not '")
v23 = Constant("'.")
v26 = Constant(null)
v29 = Constant("A very very looooooooooooooooooooooooooooong prefix: 'prefix1:")
v30 = Constant("', not 'prefix2:")
v1 = Parameter(x)
v4 = InterfaceCall List.[](v1, v3)
v7 = InterfaceCall List.[](v1, v6)
v8 = StringInterpolation(v4, v7)
v28 = StringInterpolation(v29, v8, v30, v8, v23)
DirectCall print(v28)
Return(v26)
--- closureCall
B0 = EntryBlock()
v4 = Constant(42)