Skip to content

Commit 5f47862

Browse files
committed
[ConstraintLocator] Add generic signature to OpenedGeneric element
This information is useful for requirement diagnostics, because generic signature represents the source of generic requirements.
1 parent 930ea50 commit 5f47862

File tree

2 files changed

+28
-10
lines changed

2 files changed

+28
-10
lines changed

lib/Sema/ConstraintLocator.h

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,12 @@ class ConstraintLocator : public llvm::FoldingSetNode {
152152
case AutoclosureResult:
153153
case Requirement:
154154
case Witness:
155-
case OpenedGeneric:
156155
case ImplicitlyUnwrappedDisjunctionChoice:
157156
case DynamicLookupResult:
158157
case ContextualType:
159158
return 0;
160159

160+
case OpenedGeneric:
161161
case GenericArgument:
162162
case NamedTupleElement:
163163
case TupleElement:
@@ -236,6 +236,7 @@ class ConstraintLocator : public llvm::FoldingSetNode {
236236
StoredGenericParameter,
237237
StoredRequirement,
238238
StoredWitness,
239+
StoredGenericSignature,
239240
StoredKindAndValue
240241
};
241242

@@ -249,11 +250,11 @@ class ConstraintLocator : public llvm::FoldingSetNode {
249250
/// kind. Use \c encodeStorage and \c decodeStorage to work with this value.
250251
///
251252
/// \note The "storage kind" is stored in the \c storedKind field.
252-
uint64_t storage : 62;
253+
uint64_t storage : 61;
253254

254255
/// The kind of value stored in \c storage. Valid values are those
255256
/// from the StoredKind enum.
256-
uint64_t storedKind : 2;
257+
uint64_t storedKind : 3;
257258

258259
/// Encode a path element kind and a value into the storage format.
259260
static uint64_t encodeStorage(PathElementKind kind, unsigned value) {
@@ -281,6 +282,10 @@ class ConstraintLocator : public llvm::FoldingSetNode {
281282
"Path element kind does not require 2 values");
282283
}
283284

285+
PathElement(GenericSignature *sig)
286+
: storage((reinterpret_cast<uintptr_t>(sig) >> 3)),
287+
storedKind(StoredGenericSignature) {}
288+
284289
friend class ConstraintLocator;
285290

286291
public:
@@ -292,7 +297,7 @@ class ConstraintLocator : public llvm::FoldingSetNode {
292297
}
293298

294299
PathElement(GenericTypeParamType *type)
295-
: storage((reinterpret_cast<uintptr_t>(type) >> 2)),
300+
: storage((reinterpret_cast<uintptr_t>(type) >> 3)),
296301
storedKind(StoredGenericParameter)
297302
{
298303
static_assert(alignof(GenericTypeParamType) >= 4,
@@ -301,7 +306,7 @@ class ConstraintLocator : public llvm::FoldingSetNode {
301306
}
302307

303308
PathElement(PathElementKind kind, ValueDecl *decl)
304-
: storage((reinterpret_cast<uintptr_t>(decl) >> 2)),
309+
: storage((reinterpret_cast<uintptr_t>(decl) >> 3)),
305310
storedKind(kind == Witness ? StoredWitness : StoredRequirement)
306311
{
307312
assert((kind == Witness || kind == Requirement) &&
@@ -339,6 +344,10 @@ class ConstraintLocator : public llvm::FoldingSetNode {
339344
return PathElement(KeyPathComponent, position);
340345
}
341346

347+
static PathElement getOpenedGeneric(GenericSignature *sig) {
348+
return PathElement(sig);
349+
}
350+
342351
/// Get a path element for a conditional requirement.
343352
static PathElement
344353
getConditionalRequirementComponent(unsigned index, RequirementKind kind) {
@@ -364,6 +373,9 @@ class ConstraintLocator : public llvm::FoldingSetNode {
364373
case StoredWitness:
365374
return Witness;
366375

376+
case StoredGenericSignature:
377+
return OpenedGeneric;
378+
367379
case StoredKindAndValue:
368380
return decodeStorage(storage).first;
369381
}
@@ -399,22 +411,28 @@ class ConstraintLocator : public llvm::FoldingSetNode {
399411
/// Retrieve the declaration for a witness path element.
400412
ValueDecl *getWitness() const {
401413
assert(getKind() == Witness && "Is not a witness");
402-
return reinterpret_cast<ValueDecl *>(storage << 2);
414+
return reinterpret_cast<ValueDecl *>(storage << 3);
403415
}
404416

405417
/// Retrieve the actual archetype for a generic parameter path
406418
/// element.
407419
GenericTypeParamType *getGenericParameter() const {
408420
assert(getKind() == GenericParameter &&
409421
"Not a generic parameter path element");
410-
return reinterpret_cast<GenericTypeParamType *>(storage << 2);
422+
return reinterpret_cast<GenericTypeParamType *>(storage << 3);
411423
}
412424

413425
/// Retrieve the declaration for a requirement path element.
414426
ValueDecl *getRequirement() const {
415427
assert((static_cast<StoredKind>(storedKind) == StoredRequirement) &&
416428
"Is not a requirement");
417-
return reinterpret_cast<ValueDecl *>(storage << 2);
429+
return reinterpret_cast<ValueDecl *>(storage << 3);
430+
}
431+
432+
GenericSignature *getGenericSignature() const {
433+
assert((static_cast<StoredKind>(storedKind) == StoredGenericSignature) &&
434+
"Is not an opened generic");
435+
return reinterpret_cast<GenericSignature *>(storage << 3);
418436
}
419437

420438
/// Return the summary flags for this particular element.

lib/Sema/ConstraintSystem.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,7 +1079,7 @@ void ConstraintSystem::openGeneric(
10791079
// Remember that any new constraints generated by opening this generic are
10801080
// due to the opening.
10811081
locatorPtr = getConstraintLocator(
1082-
locator.withPathElement(ConstraintLocator::OpenedGeneric));
1082+
locator.withPathElement(LocatorPathElt::getOpenedGeneric(sig)));
10831083

10841084
bindArchetypesFromContext(*this, outerDC, locatorPtr, replacements);
10851085

@@ -1124,7 +1124,7 @@ void ConstraintSystem::openGenericRequirements(
11241124

11251125
addConstraint(
11261126
*openedReq,
1127-
locator.withPathElement(ConstraintLocator::OpenedGeneric)
1127+
locator.withPathElement(LocatorPathElt::getOpenedGeneric(signature))
11281128
.withPathElement(
11291129
LocatorPathElt::getTypeRequirementComponent(pos, kind)));
11301130
}

0 commit comments

Comments
 (0)