Skip to content

Commit 5de14cb

Browse files
committed
[NFC] Sema: Add more comments to inferResultBuilderType
1 parent 16f97d7 commit 5de14cb

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

lib/Sema/TypeCheckRequestFunctions.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,21 @@ static Type inferResultBuilderType(ValueDecl *decl) {
215215
}
216216
}
217217

218+
// Below is a list of supported inference sources (in relation to the function
219+
// in question), followed by a list of inference rules.
220+
//
221+
// (a): Its dynamically replaced function.
222+
// (b): Protocol requirements that it witnesses.
223+
// (c): Protocol requirements that its dynamically replaced function
224+
// witnesses.
225+
//
226+
// (r1): (a) and (b) are always attempted.
227+
// (r2): (c) is attempted only if (a) has no result builder.
228+
218229
auto *dc = decl->getDeclContext();
230+
231+
// Neither of the aforementioned inference sources apply to a protocol
232+
// requirement.
219233
if (isa<ProtocolDecl>(dc)) {
220234
return Type();
221235
}
@@ -225,6 +239,29 @@ static Type inferResultBuilderType(ValueDecl *decl) {
225239
return Type();
226240
}
227241

242+
// A potentially inferred result builder will not be used to transform
243+
// the body in the following cases:
244+
// - The function has no body.
245+
// - The function was deserialized (has no parent source file) and, thus,
246+
// is already type-checked.
247+
// - The body has an explicit 'return' statement, which disables the result
248+
// builder transform.
249+
//
250+
// In these cases, inference can be skipped as an optimization.
251+
//
252+
// To demostrate that skipping inference here will not affect result builder
253+
// inference for other functions, suppose that the function at hand ('x') is
254+
// an inference source for another function ('y'). Since 'x' is not a protocol
255+
// requirement, the only inference source it can assume is (a). Consequently,
256+
// the only inference source available to 'x' is (b) because a dynamically
257+
// replaced declaration cannot itself be '@_dynamicReplacement'.
258+
//
259+
// This implies that inferring a result builder for 'x' is equivalent to
260+
// attempting (b) for 'x', which in turn is equivalent to attempting (c) for
261+
// 'y'. Now, recall that 'x' is (a) for 'y'. According to rule (r2), skipping
262+
// inference for 'x' will cause (c) to be attempted for 'y'. We see that
263+
// the result of inferring for 'x' will be considered when inferring for 'y'
264+
// either way.
228265
if (!funcDecl->hasBody() || !dc->getParentSourceFile() ||
229266
!TypeChecker::findReturnStatements(funcDecl).empty()) {
230267
return Type();

0 commit comments

Comments
 (0)