Skip to content

Commit 24b6624

Browse files
committed
RequirementMachine: Move some code around in RequirementMachineRequests.cpp
1 parent bf779d3 commit 24b6624

File tree

1 file changed

+66
-66
lines changed

1 file changed

+66
-66
lines changed

lib/AST/RequirementMachine/RequirementMachineRequests.cpp

Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,72 @@
3636
using namespace swift;
3737
using namespace rewriting;
3838

39+
/// Hack for GenericSignatureBuilder compatibility. We might end up with a
40+
/// same-type requirement between type parameters where one of them has an
41+
/// implied concrete type requirement. In this case, split it up into two
42+
/// concrete type requirements.
43+
static bool shouldSplitConcreteEquivalenceClass(Requirement req,
44+
GenericSignature sig) {
45+
return (req.getKind() == RequirementKind::SameType &&
46+
req.getSecondType()->isTypeParameter() &&
47+
sig->isConcreteType(req.getSecondType()));
48+
}
49+
50+
/// Returns true if this generic signature contains abstract same-type
51+
/// requirements between concrete type parameters. In this case, we split
52+
/// the abstract same-type requirements into pairs of concrete type
53+
/// requirements, and minimize the signature again.
54+
static bool shouldSplitConcreteEquivalenceClasses(GenericSignature sig) {
55+
for (auto req : sig.getRequirements()) {
56+
if (shouldSplitConcreteEquivalenceClass(req, sig))
57+
return true;
58+
}
59+
60+
return false;
61+
}
62+
63+
/// Replace each same-type requirement 'T == U' where 'T' (and therefore 'U')
64+
/// is known to equal a concrete type 'C' with a pair of requirements
65+
/// 'T == C' and 'U == C'. We build the signature again in this case, since
66+
/// one of the two requirements will be redundant, but we don't know which
67+
/// ahead of time.
68+
static void splitConcreteEquivalenceClasses(
69+
ASTContext &ctx,
70+
GenericSignature sig,
71+
SmallVectorImpl<StructuralRequirement> &requirements,
72+
unsigned &attempt) {
73+
unsigned maxAttempts =
74+
ctx.LangOpts.RequirementMachineMaxSplitConcreteEquivClassAttempts;
75+
76+
++attempt;
77+
if (attempt >= maxAttempts) {
78+
llvm::errs() << "Splitting concrete equivalence classes did not "
79+
<< "reach fixed point after " << attempt << " attempts.\n";
80+
llvm::errs() << "Last result: " << sig << "\n";
81+
abort();
82+
}
83+
84+
requirements.clear();
85+
86+
for (auto req : sig.getRequirements()) {
87+
if (shouldSplitConcreteEquivalenceClass(req, sig)) {
88+
auto canType = sig->getSugaredType(
89+
sig.getCanonicalTypeInContext(
90+
req.getSecondType()));
91+
92+
Requirement firstReq(RequirementKind::SameType,
93+
req.getFirstType(), canType);
94+
Requirement secondReq(RequirementKind::SameType,
95+
req.getSecondType(), canType);
96+
requirements.push_back({firstReq, SourceLoc(), /*inferred=*/false});
97+
requirements.push_back({secondReq, SourceLoc(), /*inferred=*/false});
98+
continue;
99+
}
100+
101+
requirements.push_back({req, SourceLoc(), /*inferred=*/false});
102+
}
103+
}
104+
39105
/// Builds the requirement signatures for each protocol in this strongly
40106
/// connected component.
41107
llvm::DenseMap<const ProtocolDecl *, RequirementSignature>
@@ -243,72 +309,6 @@ static bool isCanonicalRequest(GenericSignature baseSignature,
243309
return true;
244310
}
245311

246-
/// Hack for GenericSignatureBuilder compatibility. We might end up with a
247-
/// same-type requirement between type parameters where one of them has an
248-
/// implied concrete type requirement. In this case, split it up into two
249-
/// concrete type requirements.
250-
static bool shouldSplitConcreteEquivalenceClass(Requirement req,
251-
GenericSignature sig) {
252-
return (req.getKind() == RequirementKind::SameType &&
253-
req.getSecondType()->isTypeParameter() &&
254-
sig->isConcreteType(req.getSecondType()));
255-
}
256-
257-
/// Returns true if this generic signature contains abstract same-type
258-
/// requirements between concrete type parameters. In this case, we split
259-
/// the abstract same-type requirements into pairs of concrete type
260-
/// requirements, and minimize the signature again.
261-
static bool shouldSplitConcreteEquivalenceClasses(GenericSignature sig) {
262-
for (auto req : sig.getRequirements()) {
263-
if (shouldSplitConcreteEquivalenceClass(req, sig))
264-
return true;
265-
}
266-
267-
return false;
268-
}
269-
270-
/// Replace each same-type requirement 'T == U' where 'T' (and therefore 'U')
271-
/// is known to equal a concrete type 'C' with a pair of requirements
272-
/// 'T == C' and 'U == C'. We build the signature again in this case, since
273-
/// one of the two requirements will be redundant, but we don't know which
274-
/// ahead of time.
275-
static void splitConcreteEquivalenceClasses(
276-
ASTContext &ctx,
277-
GenericSignature sig,
278-
SmallVectorImpl<StructuralRequirement> &requirements,
279-
unsigned &attempt) {
280-
unsigned maxAttempts =
281-
ctx.LangOpts.RequirementMachineMaxSplitConcreteEquivClassAttempts;
282-
283-
++attempt;
284-
if (attempt >= maxAttempts) {
285-
llvm::errs() << "Splitting concrete equivalence classes did not "
286-
<< "reach fixed point after " << attempt << " attempts.\n";
287-
llvm::errs() << "Last result: " << sig << "\n";
288-
abort();
289-
}
290-
291-
requirements.clear();
292-
293-
for (auto req : sig.getRequirements()) {
294-
if (shouldSplitConcreteEquivalenceClass(req, sig)) {
295-
auto canType = sig->getSugaredType(
296-
sig.getCanonicalTypeInContext(
297-
req.getSecondType()));
298-
299-
Requirement firstReq(RequirementKind::SameType,
300-
req.getFirstType(), canType);
301-
Requirement secondReq(RequirementKind::SameType,
302-
req.getSecondType(), canType);
303-
requirements.push_back({firstReq, SourceLoc(), /*inferred=*/false});
304-
requirements.push_back({secondReq, SourceLoc(), /*inferred=*/false});
305-
continue;
306-
}
307-
308-
requirements.push_back({req, SourceLoc(), /*inferred=*/false});
309-
}
310-
}
311-
312312
GenericSignatureWithError
313313
AbstractGenericSignatureRequestRQM::evaluate(
314314
Evaluator &evaluator,

0 commit comments

Comments
 (0)