Skip to content

Commit 9ea048b

Browse files
srawlinsCommit Queue
authored and
Commit Queue
committed
Do not allow void results in record literals
I also privatize all of the "repor"t methods, so the sort makes for a big diff. Fixes #52759 Change-Id: I0e7b2602e27ffe2eeab7688787d38ed039895b15 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/341163 Commit-Queue: Samuel Rawlins <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]>
1 parent 804a306 commit 9ea048b

File tree

2 files changed

+70
-45
lines changed

2 files changed

+70
-45
lines changed

pkg/analyzer/lib/src/dart/resolver/record_literal_resolver.dart

Lines changed: 50 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,52 @@ class RecordLiteralResolver {
2323

2424
ErrorReporter get errorReporter => _resolver.errorReporter;
2525

26+
void resolve(
27+
RecordLiteralImpl node, {
28+
required DartType? contextType,
29+
}) {
30+
_resolveFields(node, contextType);
31+
_buildType(node, contextType);
32+
33+
_reportDuplicateFieldDefinitions(node);
34+
_reportInvalidFieldNames(node);
35+
}
36+
37+
void _buildType(RecordLiteralImpl node, DartType? contextType) {
38+
final positionalFields = <RecordTypePositionalFieldImpl>[];
39+
final namedFields = <RecordTypeNamedFieldImpl>[];
40+
for (final field in node.fields) {
41+
final fieldType = field.typeOrThrow;
42+
if (field is NamedExpressionImpl) {
43+
namedFields.add(
44+
RecordTypeNamedFieldImpl(
45+
name: field.name.label.name,
46+
type: fieldType,
47+
),
48+
);
49+
} else {
50+
positionalFields.add(
51+
RecordTypePositionalFieldImpl(
52+
type: fieldType,
53+
),
54+
);
55+
}
56+
}
57+
58+
_resolver.inferenceHelper.recordStaticType(
59+
node,
60+
RecordTypeImpl(
61+
positionalFields: positionalFields,
62+
namedFields: namedFields,
63+
nullabilitySuffix: NullabilitySuffix.none,
64+
),
65+
contextType: contextType,
66+
);
67+
}
68+
2669
/// Report any named fields in the record literal [node] that use a previously
2770
/// defined name.
28-
void reportDuplicateFieldDefinitions(RecordLiteralImpl node) {
71+
void _reportDuplicateFieldDefinitions(RecordLiteralImpl node) {
2972
var usedNames = <String, NamedExpression>{};
3073
for (var field in node.fields) {
3174
if (field is NamedExpressionImpl) {
@@ -43,7 +86,7 @@ class RecordLiteralResolver {
4386
}
4487

4588
/// Report any fields in the record literal [node] that use an invalid name.
46-
void reportInvalidFieldNames(RecordLiteralImpl node) {
89+
void _reportInvalidFieldNames(RecordLiteralImpl node) {
4790
var fields = node.fields;
4891
var positionalCount = 0;
4992
for (var field in fields) {
@@ -74,49 +117,6 @@ class RecordLiteralResolver {
74117
}
75118
}
76119

77-
void resolve(
78-
RecordLiteralImpl node, {
79-
required DartType? contextType,
80-
}) {
81-
_resolveFields(node, contextType);
82-
_buildType(node, contextType);
83-
84-
reportDuplicateFieldDefinitions(node);
85-
reportInvalidFieldNames(node);
86-
}
87-
88-
void _buildType(RecordLiteralImpl node, DartType? contextType) {
89-
final positionalFields = <RecordTypePositionalFieldImpl>[];
90-
final namedFields = <RecordTypeNamedFieldImpl>[];
91-
for (final field in node.fields) {
92-
final fieldType = field.typeOrThrow;
93-
if (field is NamedExpressionImpl) {
94-
namedFields.add(
95-
RecordTypeNamedFieldImpl(
96-
name: field.name.label.name,
97-
type: fieldType,
98-
),
99-
);
100-
} else {
101-
positionalFields.add(
102-
RecordTypePositionalFieldImpl(
103-
type: fieldType,
104-
),
105-
);
106-
}
107-
}
108-
109-
_resolver.inferenceHelper.recordStaticType(
110-
node,
111-
RecordTypeImpl(
112-
positionalFields: positionalFields,
113-
namedFields: namedFields,
114-
nullabilitySuffix: NullabilitySuffix.none,
115-
),
116-
contextType: contextType,
117-
);
118-
}
119-
120120
void _resolveField(ExpressionImpl field, DartType? contextType) {
121121
_resolver.analyzeExpression(field, contextType);
122122
field = _resolver.popRewrite()!;
@@ -128,6 +128,11 @@ class RecordLiteralResolver {
128128
field.expression.staticType = contextType;
129129
}
130130
}
131+
132+
if (field.typeOrThrow is VoidType) {
133+
errorReporter.reportErrorForNode(
134+
CompileTimeErrorCode.USE_OF_VOID_RESULT, field);
135+
}
131136
}
132137

133138
void _resolveFields(RecordLiteralImpl node, DartType? contextType) {

pkg/analyzer/test/src/diagnostics/use_of_void_result_test.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,26 @@ void f(void x) {
239239
]);
240240
}
241241

242+
test_recordLiteral_namedField() async {
243+
await assertErrorsInCode('''
244+
void f(void x) {
245+
(one: x,);
246+
}
247+
''', [
248+
error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 20, 6),
249+
]);
250+
}
251+
252+
test_recordLiteral_positionalField() async {
253+
await assertErrorsInCode('''
254+
void f(void x) {
255+
(x,);
256+
}
257+
''', [
258+
error(CompileTimeErrorCode.USE_OF_VOID_RESULT, 20, 1),
259+
]);
260+
}
261+
242262
test_switchStatement_expression() async {
243263
await assertErrorsInCode('''
244264
void f(void x) {

0 commit comments

Comments
 (0)