Skip to content

Commit c915dd5

Browse files
committed
Teach the ASTSynthesis stuff how to add generic constraints
1 parent 669a49a commit c915dd5

File tree

2 files changed

+56
-4
lines changed

2 files changed

+56
-4
lines changed

include/swift/AST/ASTSynthesis.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ struct VariadicSynthesizerStorage<> {
135135
constexpr VariadicSynthesizerStorage() {}
136136

137137
template <class Fn>
138-
void visit(const Fn &fn) const {}
138+
void visit(Fn &&fn) const {}
139139
};
140140
template <class Head, class... Tail>
141141
struct VariadicSynthesizerStorage<Head, Tail...> {
@@ -145,7 +145,7 @@ struct VariadicSynthesizerStorage<Head, Tail...> {
145145
: head(head), tail(tail...) {}
146146

147147
template <class Fn>
148-
void visit(const Fn &fn) const {
148+
void visit(Fn &&fn) const {
149149
fn(head);
150150
tail.visit(fn);
151151
}

lib/AST/Builtins.cpp

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,33 @@ namespace {
162162
/// for generics.
163163
enum UnrestrictedGenericParam { _unrestricted };
164164

165+
/// A synthesizer which generates a conformance requirement.
166+
template <class TypeS, class ProtocolS>
167+
struct ConformsToSynthesizer {
168+
TypeS Type;
169+
ProtocolS Protocol;
170+
};
171+
template <class TypeS, class ProtocolS>
172+
constexpr ConformsToSynthesizer<TypeS, ProtocolS>
173+
_conformsTo(TypeS type, ProtocolS protocol) {
174+
return {type, protocol};
175+
}
176+
177+
/// A synthesizer which generates a layout constraint requirement.
178+
template <class TypeS>
179+
struct LayoutConstraintSynthesizer {
180+
TypeS Type;
181+
LayoutConstraint Constraint;
182+
};
183+
template <class TypeS>
184+
LayoutConstraintSynthesizer<TypeS>
185+
_layout(TypeS type, LayoutConstraint constraint) {
186+
return {type, constraint};
187+
}
188+
static LayoutConstraint _classLayout() {
189+
return LayoutConstraint::getLayoutConstraint(LayoutConstraintKind::Class);
190+
}
191+
165192
/// A synthesizer which generates a generic parameter list.
166193
template <class... ParamS>
167194
struct GenericParamListSynthesizer {
@@ -179,6 +206,16 @@ struct CountGenericParameters {
179206
void operator()(UnrestrictedGenericParam _) const {
180207
Count++;
181208
}
209+
210+
template <class TypeS, class ProtoS>
211+
void operator()(const ConformsToSynthesizer<TypeS, ProtoS> &_) const {
212+
// not a parameter
213+
}
214+
215+
template <class TypeS>
216+
void operator()(const LayoutConstraintSynthesizer<TypeS> &_) const {
217+
// not a parameter
218+
}
182219
};
183220

184221
} // end anonymous namespace
@@ -240,15 +277,30 @@ struct CollectGenericParams {
240277
}
241278
}
242279

243-
void operator()(UnrestrictedGenericParam _) const {}
280+
void operator()(UnrestrictedGenericParam _) {}
281+
282+
template <class TypeS, class ProtoS>
283+
void operator()(const ConformsToSynthesizer<TypeS, ProtoS> &conf) {
284+
auto type = synthesizeType(SC, conf.Type);
285+
auto protocolType = synthesizeType(SC, conf.Protocol);
286+
AddedRequirements.push_back({RequirementKind::Conformance,
287+
type, protocolType});
288+
}
289+
290+
template <class TypeS>
291+
void operator()(const LayoutConstraintSynthesizer<TypeS> &req) {
292+
auto type = synthesizeType(SC, req.Type);
293+
AddedRequirements.push_back({RequirementKind::Layout,
294+
type, req.Constraint});
295+
}
244296
};
245297

246298
} // end anonymous namespace
247299

248300
template <class... ParamsS>
249301
static GenericSignature
250302
synthesizeGenericSignature(SynthesisContext &SC,
251-
GenericParamListSynthesizer<ParamsS...> list) {
303+
const GenericParamListSynthesizer<ParamsS...> &list) {
252304
assert(SC.GenericParams && "synthesizeGenericParamList not called first");
253305
CollectGenericParams collector(SC);
254306
list.Params.visit(collector);

0 commit comments

Comments
 (0)