Skip to content

Commit 6ed553d

Browse files
committed
AST: Introduce GenericSignature::getRequirementsWithInverses()
1 parent 192d275 commit 6ed553d

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

include/swift/AST/GenericSignature.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,13 @@ class alignas(1 << TypeAlignInBits) GenericSignatureImpl final
310310
return Mem;
311311
}
312312

313+
/// Transform the requirements into a form where implicit Copyable and
314+
/// Escapable conformances are omitted, and their absence is explicitly
315+
/// noted.
316+
void getRequirementsWithInverses(
317+
SmallVector<Requirement, 2> &reqs,
318+
SmallVector<InverseRequirement, 2> &inverses) const;
319+
313320
/// Look up a stored conformance in the generic signature. These are formed
314321
/// from same-type constraints placed on associated types of generic
315322
/// parameters which have conformance constraints on them.

lib/AST/GenericSignature.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,3 +1246,46 @@ GenericSignature GenericSignature::withoutMarkerProtocols() const {
12461246

12471247
return GenericSignature::get(getGenericParams(), reducedRequirements);
12481248
}
1249+
1250+
void GenericSignatureImpl::getRequirementsWithInverses(
1251+
SmallVector<Requirement, 2> &reqs,
1252+
SmallVector<InverseRequirement, 2> &inverses) const {
1253+
auto &ctx = getASTContext();
1254+
1255+
if (!SWIFT_ENABLE_EXPERIMENTAL_NONCOPYABLE_GENERICS &&
1256+
!ctx.LangOpts.hasFeature(Feature::NoncopyableGenerics)) {
1257+
reqs.append(getRequirements().begin(), getRequirements().end());
1258+
return;
1259+
}
1260+
1261+
// Record the absence of conformances to invertible protocols.
1262+
for (auto gp : getGenericParams()) {
1263+
// Any generic parameter with a superclass bound or concrete type does not
1264+
// have an inverse.
1265+
if (getSuperclassBound(gp) || getConcreteType(gp))
1266+
continue;
1267+
1268+
for (auto ip : InvertibleProtocolSet::full()) {
1269+
auto *proto = ctx.getProtocol(getKnownProtocolKind(ip));
1270+
1271+
// If we can derive a conformance to this protocol, then don't add an
1272+
// inverse.
1273+
if (requiresProtocol(gp, proto))
1274+
continue;
1275+
1276+
// Nothing implies a conformance to this protocol, so record the inverse.
1277+
inverses.push_back({gp, proto, SourceLoc()});
1278+
}
1279+
}
1280+
1281+
// Filter out explicit conformances to invertible protocols.
1282+
for (auto req : getRequirements()) {
1283+
if (req.getKind() == RequirementKind::Conformance &&
1284+
req.getFirstType()->is<GenericTypeParamType>() &&
1285+
req.getProtocolDecl()->getInvertibleProtocolKind()) {
1286+
continue;
1287+
}
1288+
1289+
reqs.push_back(req);
1290+
}
1291+
}

0 commit comments

Comments
 (0)