@@ -73,6 +73,10 @@ class BuilderClosureVisitor
73
73
Identifier buildOptionalId;
74
74
llvm::SmallDenseMap<DeclName, bool > supportedOps;
75
75
76
+ // / The variable used as a base for all `build*` operations added
77
+ // / by this transform.
78
+ VarDecl *builderVar = nullptr ;
79
+
76
80
SkipUnhandledConstructInResultBuilder::UnhandledNode unhandledNode;
77
81
78
82
// / Whether an error occurred during application of the builder closure,
@@ -94,32 +98,6 @@ class BuilderClosureVisitor
94
98
if (!cs)
95
99
return nullptr ;
96
100
97
- // FIXME: Setting a base on this expression is necessary in order
98
- // to get diagnostics if something about this builder call fails,
99
- // e.g. if there isn't a matching overload for `buildBlock`.
100
- TypeExpr *typeExpr;
101
- auto simplifiedTy = cs->simplifyType (builderType);
102
- if (!simplifiedTy->hasTypeVariable ()) {
103
- typeExpr = TypeExpr::createImplicitHack (loc, simplifiedTy, ctx);
104
- } else if (auto *decl = simplifiedTy->getAnyGeneric ()) {
105
- // HACK: If there's not enough information to completely resolve the
106
- // builder type, but we have the base available to us, form an *explicit*
107
- // TypeExpr pointing at it. We cannot form an implicit base without
108
- // a fully-resolved concrete type. Really, whatever we put here has no
109
- // bearing on the generated solution because we're going to use this node
110
- // to stash the builder type and hand it back to the ambient
111
- // constraint system.
112
- typeExpr = TypeExpr::createForDecl (DeclNameLoc (loc), decl, dc);
113
- } else {
114
- // HACK: If there's not enough information in the constraint system,
115
- // create a garbage base type to force it to diagnose
116
- // this as an ambiguous expression.
117
- // FIXME: We can also construct an UnresolvedMemberExpr here instead of
118
- // an UnresolvedDotExpr and get a slightly better diagnostic.
119
- typeExpr = TypeExpr::createImplicitHack (loc, ErrorType::get (ctx), ctx);
120
- }
121
- cs->setType (typeExpr, MetatypeType::get (builderType));
122
-
123
101
SmallVector<Argument, 4 > args;
124
102
for (auto i : indices (argExprs)) {
125
103
auto *expr = argExprs[i];
@@ -128,8 +106,11 @@ class BuilderClosureVisitor
128
106
args.emplace_back (labelLoc, label, expr);
129
107
}
130
108
109
+ auto *baseExpr = new (ctx) DeclRefExpr ({builderVar}, DeclNameLoc (loc),
110
+ /* isImplicit=*/ true );
111
+
131
112
auto memberRef = new (ctx) UnresolvedDotExpr (
132
- typeExpr , loc, DeclNameRef (fnName), DeclNameLoc (loc),
113
+ baseExpr , loc, DeclNameRef (fnName), DeclNameLoc (loc),
133
114
/* implicit=*/ true );
134
115
memberRef->setFunctionRefKind (FunctionRefKind::SingleApply);
135
116
@@ -223,6 +204,16 @@ class BuilderClosureVisitor
223
204
buildOptionalId = ctx.Id_buildOptional ;
224
205
else
225
206
buildOptionalId = ctx.Id_buildIf ;
207
+
208
+ // If we are about to generate constraints, let's establish builder
209
+ // variable for the base of `build*` calls.
210
+ if (cs) {
211
+ builderVar = new (ctx) VarDecl (
212
+ /* isStatic=*/ false , VarDecl::Introducer::Let,
213
+ /* nameLoc=*/ SourceLoc (), ctx.Id_builderSelf , dc);
214
+ builderVar->setImplicit ();
215
+ cs->setType (builderVar, MetatypeType::get (cs->simplifyType (builderType)));
216
+ }
226
217
}
227
218
228
219
// / Apply the builder transform to the given statement.
0 commit comments