@@ -134,6 +134,8 @@ struct ResultBuilder {
134134 return BuilderType->getAnyNominal ();
135135 }
136136
137+ VarDecl *getBuilderSelf () const { return BuilderSelf; }
138+
137139 Identifier getBuildOptionalId () const { return BuildOptionalId; }
138140
139141 bool supports (Identifier fnBaseName, ArrayRef<Identifier> argLabels = {},
@@ -647,6 +649,10 @@ T *getAsPattern(ASTNode node) {
647649 return nullptr ;
648650}
649651
652+ template <typename T = Stmt> T *castToStmt (ASTNode node) {
653+ return cast<T>(node.get <Stmt *>());
654+ }
655+
650656SourceLoc getLoc (ASTNode node);
651657SourceRange getSourceRange (ASTNode node);
652658
@@ -910,6 +916,10 @@ struct AppliedBuilderTransform {
910916 // / converted. Opaque types should be unopened.
911917 Type bodyResultType;
912918
919+ // / The version of the original body with result builder applied
920+ // / as AST transformation.
921+ NullablePtr<BraceStmt> transformedBody;
922+
913923 // / An expression whose value has been recorded for later use.
914924 struct RecordedExpr {
915925 // / The temporary value that captures the value of the expression, if
@@ -1059,6 +1069,7 @@ class SolutionApplicationTargetsKey {
10591069 pattern,
10601070 patternBindingEntry,
10611071 varDecl,
1072+ functionRef,
10621073 };
10631074
10641075private:
@@ -1079,6 +1090,8 @@ class SolutionApplicationTargetsKey {
10791090 } patternBindingEntry;
10801091
10811092 const VarDecl *varDecl;
1093+
1094+ const DeclContext *functionRef;
10821095 } storage;
10831096
10841097public:
@@ -1124,6 +1137,11 @@ class SolutionApplicationTargetsKey {
11241137 storage.varDecl = varDecl;
11251138 }
11261139
1140+ SolutionApplicationTargetsKey (const AnyFunctionRef functionRef) {
1141+ kind = Kind::functionRef;
1142+ storage.functionRef = functionRef.getAsDeclContext ();
1143+ }
1144+
11271145 friend bool operator ==(
11281146 SolutionApplicationTargetsKey lhs, SolutionApplicationTargetsKey rhs) {
11291147 if (lhs.kind != rhs.kind )
@@ -1155,6 +1173,9 @@ class SolutionApplicationTargetsKey {
11551173
11561174 case Kind::varDecl:
11571175 return lhs.storage .varDecl == rhs.storage .varDecl ;
1176+
1177+ case Kind::functionRef:
1178+ return lhs.storage .functionRef == rhs.storage .functionRef ;
11581179 }
11591180 llvm_unreachable (" invalid SolutionApplicationTargetsKey kind" );
11601181 }
@@ -1206,6 +1227,11 @@ class SolutionApplicationTargetsKey {
12061227 return hash_combine (
12071228 DenseMapInfo<unsigned >::getHashValue (static_cast <unsigned >(kind)),
12081229 DenseMapInfo<void *>::getHashValue (storage.varDecl ));
1230+
1231+ case Kind::functionRef:
1232+ return hash_combine (
1233+ DenseMapInfo<unsigned >::getHashValue (static_cast <unsigned >(kind)),
1234+ DenseMapInfo<void *>::getHashValue (storage.functionRef ));
12091235 }
12101236 llvm_unreachable (" invalid statement kind" );
12111237 }
@@ -2710,6 +2736,14 @@ class ConstraintSystem {
27102736 // / diagnostics when result builder has multiple overloads.
27112737 llvm::SmallDenseSet<AnyFunctionRef> InvalidResultBuilderBodies;
27122738
2739+ // / The *global* set of all functions that have a particular result builder
2740+ // / applied.
2741+ // /
2742+ // / The value here is `$__builderSelf` variable and a transformed body.
2743+ llvm::DenseMap<std::pair<AnyFunctionRef, NominalTypeDecl *>,
2744+ std::pair<VarDecl *, BraceStmt *>>
2745+ BuilderTransformedBodies;
2746+
27132747 // / Arguments after the code completion token that were thus ignored (i.e.
27142748 // / assigned fresh type variables) for type checking.
27152749 llvm::SetVector<Expr *> IgnoredArguments;
@@ -3714,6 +3748,35 @@ class ConstraintSystem {
37143748 return known->second ;
37153749 }
37163750
3751+ Optional<AppliedBuilderTransform>
3752+ getAppliedResultBuilderTransform (AnyFunctionRef fn) const {
3753+ auto transformed = resultBuilderTransformed.find (fn);
3754+ if (transformed != resultBuilderTransformed.end ())
3755+ return transformed->second ;
3756+ return None;
3757+ }
3758+
3759+ void setBuilderTransformedBody (AnyFunctionRef fn, NominalTypeDecl *builder,
3760+ NullablePtr<VarDecl> builderSelf,
3761+ NullablePtr<BraceStmt> body) {
3762+ assert (builder->getAttrs ().hasAttribute <ResultBuilderAttr>());
3763+ assert (body);
3764+ assert (builderSelf);
3765+
3766+ auto existing = BuilderTransformedBodies.insert (
3767+ {{fn, builder}, {builderSelf.get (), body.get ()}});
3768+ assert (existing.second && " Duplicate result builder transform" );
3769+ (void )existing;
3770+ }
3771+
3772+ Optional<std::pair<VarDecl *, BraceStmt *>>
3773+ getBuilderTransformedBody (AnyFunctionRef fn, NominalTypeDecl *builder) const {
3774+ auto result = BuilderTransformedBodies.find ({fn, builder});
3775+ if (result == BuilderTransformedBodies.end ())
3776+ return None;
3777+ return result->second ;
3778+ }
3779+
37173780 void setCaseLabelItemInfo (const CaseLabelItem *item, CaseLabelItemInfo info) {
37183781 assert (item != nullptr );
37193782 assert (caseLabelItems.count (item) == 0 );
@@ -4792,6 +4855,16 @@ class ConstraintSystem {
47924855 LLVM_NODISCARD
47934856 bool generateConstraints (ClosureExpr *closure);
47944857
4858+ // / Generate constraints for the body of the given function.
4859+ // /
4860+ // / \param fn The function or closure expression
4861+ // / \param body The body of the given function that should be
4862+ // / used for constraint generation.
4863+ // /
4864+ // / \returns \c true if constraint generation failed, \c false otherwise
4865+ LLVM_NODISCARD
4866+ bool generateConstraints (AnyFunctionRef fn, BraceStmt *body);
4867+
47954868 // / Generate constraints for the given (unchecked) expression.
47964869 // /
47974870 // / \returns a possibly-sanitized expression, or null if an error occurred.
@@ -5640,14 +5713,14 @@ class ConstraintSystem {
56405713 // /
56415714 // /
56425715 // / \param solution The solution to apply.
5643- // / \param closure The closure to which the solution is being applied.
5716+ // / \param fn The function or closure to which the solution is being applied.
56445717 // / \param currentDC The declaration context in which transformations
56455718 // / will be applied.
56465719 // / \param rewriteTarget Function that performs a rewrite of any
56475720 // / solution application target within the context.
56485721 // /
56495722 // / \returns true if solution cannot be applied.
5650- bool applySolutionToBody (Solution &solution, ClosureExpr *closure ,
5723+ bool applySolutionToBody (Solution &solution, AnyFunctionRef fn ,
56515724 DeclContext *¤tDC,
56525725 std::function<Optional<SolutionApplicationTarget>(
56535726 SolutionApplicationTarget)>
@@ -6485,6 +6558,13 @@ bool isOperatorDisjunction(Constraint *disjunction);
64856558// / or nested declarations).
64866559ASTNode findAsyncNode (ClosureExpr *closure);
64876560
6561+ // / Check whether the given binding represents a placeholder variable that
6562+ // / has to get its type inferred at a first use site.
6563+ // /
6564+ // / \returns The currently assigned type if it's a placeholder,
6565+ // / empty type otherwise.
6566+ Type isPlaceholderVar (PatternBindingDecl *PB);
6567+
64886568} // end namespace constraints
64896569
64906570template <typename ...Args>
0 commit comments