Skip to content

Commit 10ebdcd

Browse files
committed
[GSB] Broaden the Boolean result of "add a constraint" operations.
Rather than true (an error occurred) or false (the constraint was resolved), introduce ConstraintResult to better model what happened. NFC for now, but the intent here is to report unresolved constraints through this mechanism.
1 parent 5659f48 commit 10ebdcd

File tree

4 files changed

+173
-126
lines changed

4 files changed

+173
-126
lines changed

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 79 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,20 @@ class GenericSignatureBuilder {
178178

179179
friend class RequirementSource;
180180

181+
/// The result of introducing a new constraint.
182+
enum class ConstraintResult {
183+
/// The constraint was resolved and the relative potential archetypes
184+
/// have been updated.
185+
Resolved,
186+
187+
/// The constraint was written directly on a concrete type.
188+
Concrete,
189+
190+
/// The constraint conflicted with existing constraints in some way;
191+
/// the generic signature is ill-formed.
192+
Conflicting,
193+
};
194+
181195
private:
182196
class InferRequirementsWalker;
183197
friend class InferRequirementsWalker;
@@ -195,8 +209,8 @@ class GenericSignatureBuilder {
195209
/// currently-unresolvable or nested type, this routine should be
196210
/// called to record the unresolved requirement to be reconsidered later.
197211
///
198-
/// \returns false, which is used elsewhere to indicate "no failure".
199-
bool recordUnresolvedRequirement(RequirementKind kind,
212+
/// \returns ConstraintResult::Resolved.
213+
ConstraintResult recordUnresolvedRequirement(RequirementKind kind,
200214
UnresolvedType lhs,
201215
RequirementRHS rhs,
202216
FloatingRequirementSource source);
@@ -214,14 +228,15 @@ class GenericSignatureBuilder {
214228

215229
/// \brief Add a new conformance requirement specifying that the given
216230
/// potential archetype conforms to the given protocol.
217-
bool addConformanceRequirement(PotentialArchetype *T,
218-
ProtocolDecl *Proto,
219-
const RequirementSource *Source);
231+
ConstraintResult addConformanceRequirement(PotentialArchetype *T,
232+
ProtocolDecl *Proto,
233+
const RequirementSource *Source);
220234

221-
bool addConformanceRequirement(PotentialArchetype *T,
222-
ProtocolDecl *Proto,
223-
const RequirementSource *Source,
224-
llvm::SmallPtrSetImpl<ProtocolDecl *> &Visited);
235+
ConstraintResult addConformanceRequirement(
236+
PotentialArchetype *T,
237+
ProtocolDecl *Proto,
238+
const RequirementSource *Source,
239+
llvm::SmallPtrSetImpl<ProtocolDecl *> &Visited);
225240

226241
public:
227242
/// \brief Add a new same-type requirement between two fully resolved types
@@ -231,7 +246,7 @@ class GenericSignatureBuilder {
231246
/// incompatible (e.g. \c Foo<Bar<T>> and \c Foo<Baz>), \c diagnoseMismatch is
232247
/// called with the two types that don't match (\c Bar<T> and \c Baz for the
233248
/// previous example).
234-
bool
249+
ConstraintResult
235250
addSameTypeRequirementDirect(
236251
ResolvedType paOrT1, ResolvedType paOrT2,
237252
FloatingRequirementSource Source,
@@ -241,57 +256,63 @@ class GenericSignatureBuilder {
241256
/// (output of GenericSignatureBuilder::resolve).
242257
///
243258
/// The two types must not be incompatible concrete types.
244-
bool addSameTypeRequirementDirect(ResolvedType paOrT1, ResolvedType paOrT2,
245-
FloatingRequirementSource Source);
259+
ConstraintResult addSameTypeRequirementDirect(
260+
ResolvedType paOrT1,
261+
ResolvedType paOrT2,
262+
FloatingRequirementSource Source);
246263

247264
/// \brief Add a new same-type requirement between two unresolved types.
248265
///
249266
/// The types are resolved with \c GenericSignatureBuilder::resolve, and must
250267
/// not be incompatible concrete types.
251-
bool addSameTypeRequirement(UnresolvedType paOrT1, UnresolvedType paOrT2,
252-
FloatingRequirementSource Source);
268+
ConstraintResult addSameTypeRequirement(UnresolvedType paOrT1,
269+
UnresolvedType paOrT2,
270+
FloatingRequirementSource Source);
253271

254272
/// \brief Add a new same-type requirement between two unresolved types.
255273
///
256274
/// The types are resolved with \c GenericSignatureBuilder::resolve. \c
257275
/// diagnoseMismatch is called if the two types refer to incompatible concrete
258276
/// types.
259-
bool
277+
ConstraintResult
260278
addSameTypeRequirement(UnresolvedType paOrT1, UnresolvedType paOrT2,
261279
FloatingRequirementSource Source,
262280
llvm::function_ref<void(Type, Type)> diagnoseMismatch);
263281

264282
/// Update the superclass for the equivalence class of \c T.
265283
///
266-
/// This assumes that the constraint has already been recorded
267-
bool updateSuperclass(PotentialArchetype *T,
284+
/// This assumes that the constraint has already been recorded.
285+
void updateSuperclass(PotentialArchetype *T,
268286
Type superclass,
269287
const RequirementSource *source);
270288

271289
private:
272290
/// \brief Add a new superclass requirement specifying that the given
273291
/// potential archetype has the given type as an ancestor.
274-
bool addSuperclassRequirementDirect(PotentialArchetype *T,
275-
Type Superclass,
276-
const RequirementSource *Source);
292+
ConstraintResult addSuperclassRequirementDirect(
293+
PotentialArchetype *T,
294+
Type Superclass,
295+
const RequirementSource *Source);
277296

278297
/// \brief Add a new type requirement specifying that the given
279298
/// type conforms-to or is a superclass of the second type.
280-
bool addTypeRequirement(UnresolvedType subject,
299+
ConstraintResult addTypeRequirement(
300+
UnresolvedType subject,
281301
UnresolvedType constraint,
282302
FloatingRequirementSource source,
283303
llvm::SmallPtrSetImpl<ProtocolDecl *> *visited
284304
= nullptr);
285305

286306
/// \brief Add a new conformance requirement specifying that the given
287307
/// potential archetypes are equivalent.
288-
bool addSameTypeRequirementBetweenArchetypes(PotentialArchetype *T1,
308+
ConstraintResult addSameTypeRequirementBetweenArchetypes(
309+
PotentialArchetype *T1,
289310
PotentialArchetype *T2,
290311
const RequirementSource *Source);
291312

292313
/// \brief Add a new conformance requirement specifying that the given
293314
/// potential archetype is bound to a concrete type.
294-
bool addSameTypeRequirementToConcrete(PotentialArchetype *T,
315+
ConstraintResult addSameTypeRequirementToConcrete(PotentialArchetype *T,
295316
Type Concrete,
296317
const RequirementSource *Source);
297318

@@ -300,26 +321,28 @@ class GenericSignatureBuilder {
300321
///
301322
/// \param diagnoseMismatch Callback invoked when the types in the same-type
302323
/// requirement mismatch.
303-
bool addSameTypeRequirementBetweenConcrete(
324+
ConstraintResult addSameTypeRequirementBetweenConcrete(
304325
Type T1, Type T2, FloatingRequirementSource Source,
305326
llvm::function_ref<void(Type, Type)> diagnoseMismatch);
306327

307328
/// \brief Add a new layout requirement directly on the potential archetype.
308329
///
309330
/// \returns true if this requirement makes the set of requirements
310331
/// inconsistent, in which case a diagnostic will have been issued.
311-
bool addLayoutRequirementDirect(PotentialArchetype *PAT,
312-
LayoutConstraint Layout,
313-
const RequirementSource *Source);
332+
ConstraintResult addLayoutRequirementDirect(PotentialArchetype *PAT,
333+
LayoutConstraint Layout,
334+
const RequirementSource *Source);
314335

315336
/// Add a new layout requirement to the subject.
316-
bool addLayoutRequirement(UnresolvedType subject,
317-
LayoutConstraint layout,
318-
FloatingRequirementSource source);
337+
ConstraintResult addLayoutRequirement(UnresolvedType subject,
338+
LayoutConstraint layout,
339+
FloatingRequirementSource source);
319340

320341
/// Add the requirements placed on the given type parameter
321342
/// to the given potential archetype.
322-
bool addInheritedRequirements(TypeDecl *decl, PotentialArchetype *pa,
343+
ConstraintResult addInheritedRequirements(
344+
TypeDecl *decl,
345+
PotentialArchetype *pa,
323346
const RequirementSource *parentSource,
324347
llvm::SmallPtrSetImpl<ProtocolDecl *> &visited);
325348

@@ -379,15 +402,15 @@ class GenericSignatureBuilder {
379402
///
380403
/// \returns true if this requirement makes the set of requirements
381404
/// inconsistent, in which case a diagnostic will have been issued.
382-
bool addRequirement(const RequirementRepr *req);
405+
ConstraintResult addRequirement(const RequirementRepr *req);
383406

384407
/// \brief Add a new requirement.
385408
///
386409
/// \returns true if this requirement makes the set of requirements
387410
/// inconsistent, in which case a diagnostic will have been issued.
388-
bool addRequirement(const RequirementRepr *Req,
389-
FloatingRequirementSource source,
390-
const SubstitutionMap *subMap);
411+
ConstraintResult addRequirement(const RequirementRepr *Req,
412+
FloatingRequirementSource source,
413+
const SubstitutionMap *subMap);
391414

392415
/// \brief Add an already-checked requirement.
393416
///
@@ -396,12 +419,15 @@ class GenericSignatureBuilder {
396419
///
397420
/// \returns true if this requirement makes the set of requirements
398421
/// inconsistent, in which case a diagnostic will have been issued.
399-
bool addRequirement(const Requirement &req, FloatingRequirementSource source,
400-
const SubstitutionMap *subMap = nullptr);
401-
402-
bool addRequirement(const Requirement &req, FloatingRequirementSource source,
403-
const SubstitutionMap *subMap,
404-
llvm::SmallPtrSetImpl<ProtocolDecl *> &Visited);
422+
ConstraintResult addRequirement(const Requirement &req,
423+
FloatingRequirementSource source,
424+
const SubstitutionMap *subMap = nullptr);
425+
426+
ConstraintResult addRequirement(
427+
const Requirement &req,
428+
FloatingRequirementSource source,
429+
const SubstitutionMap *subMap,
430+
llvm::SmallPtrSetImpl<ProtocolDecl *> &Visited);
405431

406432
/// \brief Add all of a generic signature's parameters and requirements.
407433
void addGenericSignature(GenericSignature *sig);
@@ -1519,6 +1545,18 @@ class GenericSignatureBuilder::PotentialArchetype {
15191545
friend class GenericSignatureBuilder;
15201546
};
15211547

1548+
/// Whether the given constraint result signals an error.
1549+
inline bool isErrorResult(GenericSignatureBuilder::ConstraintResult result) {
1550+
switch (result) {
1551+
case GenericSignatureBuilder::ConstraintResult::Concrete:
1552+
case GenericSignatureBuilder::ConstraintResult::Conflicting:
1553+
return true;
1554+
1555+
case GenericSignatureBuilder::ConstraintResult::Resolved:
1556+
return false;
1557+
}
1558+
}
1559+
15221560
} // end namespace swift
15231561

15241562
#endif

0 commit comments

Comments
 (0)