[dart2js] Small improvements to record type inference. Change-Id: Iec3bf6f639e5047327866810e3847ce1925e8d8f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/304580 Reviewed-by: Mayank Patke <fishythefish@google.com> Commit-Queue: Nate Biggs <natebiggs@google.com>
diff --git a/pkg/compiler/lib/src/inferrer/engine.dart b/pkg/compiler/lib/src/inferrer/engine.dart index 932c822..2356ffd 100644 --- a/pkg/compiler/lib/src/inferrer/engine.dart +++ b/pkg/compiler/lib/src/inferrer/engine.dart
@@ -804,7 +804,6 @@ _workQueue.addAll(types.allocatedTypes); _workQueue.addAll(types.allocatedClosures); _workQueue.addAll(types.allocatedCalls); - _workQueue.addAll(types.allocatedRecords.values); } /// Update the inputs to parameters in the graph. [remove] tells whether
diff --git a/pkg/compiler/lib/src/inferrer/node_tracer.dart b/pkg/compiler/lib/src/inferrer/node_tracer.dart index 21f0970..058042c 100644 --- a/pkg/compiler/lib/src/inferrer/node_tracer.dart +++ b/pkg/compiler/lib/src/inferrer/node_tracer.dart
@@ -359,9 +359,12 @@ if (user is RecordFieldAccessTypeInformation) { final getterIndex = record.recordShape.indexOfGetterName(user.getterName); - if (user.receiver != flow || - record.fieldTypes.indexOf(currentUser!) != getterIndex) return; - addNewEscapeInformation(user); + if (user.receiver == flow && + getterIndex >= 0 && + getterIndex < record.fieldTypes.length && + record.fieldTypes[getterIndex] == currentUser) { + addNewEscapeInformation(user); + } } }); });
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart index 0455a8c..b2e4764 100644 --- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart +++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -2104,13 +2104,11 @@ /// constants and literals. class RecordTypeInformation extends TypeInformation with TracedTypeInformation { final RecordShape recordShape; - final AbstractValue originalType; - final List<TypeInformation> fieldTypes; - RecordTypeInformation(MemberTypeInformation? context, this.originalType, - this.recordShape, this.fieldTypes) - : super(originalType, context) { + RecordTypeInformation( + super.type, super.context, this.recordShape, this.fieldTypes) + : super.noInputs() { for (final fieldType in fieldTypes) { fieldType.addUser(this); } @@ -2137,8 +2135,14 @@ } @override - // TODO(50701): This could be a top type of the record shape. - AbstractValue safeType(InferrerEngine inferrer) => originalType; + AbstractValue safeType(InferrerEngine inferrer) { + final shapeClass = inferrer.closedWorld.recordData + .representationForShape(recordShape) + ?.cls; + return shapeClass != null + ? inferrer.abstractValueDomain.createNonNullSubtype(shapeClass) + : inferrer.abstractValueDomain.recordType; + } @override bool hasStableType(InferrerEngine inferrer) { @@ -2188,7 +2192,11 @@ @override AbstractValue computeType(InferrerEngine inferrer) { final recordType = receiver.type; - if (!inferrer.abstractValueDomain.isRecord(recordType)) { + if (inferrer.abstractValueDomain.isEmpty(recordType).isDefinitelyTrue) { + // These field accesses should begin at empty until we have a type for the + // receiver. + return inferrer.abstractValueDomain.emptyType; + } else if (!inferrer.abstractValueDomain.isRecord(recordType)) { return safeType(inferrer); } final getterType = inferrer.abstractValueDomain
diff --git a/pkg/compiler/lib/src/inferrer/type_system.dart b/pkg/compiler/lib/src/inferrer/type_system.dart index dfa591e..447ca18 100644 --- a/pkg/compiler/lib/src/inferrer/type_system.dart +++ b/pkg/compiler/lib/src/inferrer/type_system.dart
@@ -539,9 +539,10 @@ allocatedTypes.add(getterType); } - final record = RecordTypeInformation(currentMember, - _abstractValueDomain.recordType, recordType.shape, fieldTypes); + final record = RecordTypeInformation(_abstractValueDomain.recordType, + currentMember, recordType.shape, fieldTypes); allocatedRecords[node] = record; + allocatedTypes.add(record); return record; }