Skip to content

Commit 466d6a9

Browse files
committed
RequirementMachine: Refactor shouldSplitConcreteEquivalenceClasses() and splitConcreteEquivalenceClasses() a bit
Note that this changes the behavior of a test slightly when the -disable-concrete-contraction flag is used. This is because we're not using the Requirement Machine that minimized the signature and not the Requirement Machine built from the minimized signature; the former includes a concrete conformance rule. The isConcreteType() query returns true on the former when given the generic parameter τ_0_0. Since -disable-concrete-contraction is only meant for debugging, I'm just removing that line from the test.
1 parent 11b45ca commit 466d6a9

File tree

2 files changed

+37
-21
lines changed

2 files changed

+37
-21
lines changed

lib/AST/RequirementMachine/RequirementMachineRequests.cpp

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,23 @@ using namespace rewriting;
4040
/// same-type requirement between type parameters where one of them has an
4141
/// implied concrete type requirement. In this case, split it up into two
4242
/// concrete type requirements.
43-
static bool shouldSplitConcreteEquivalenceClass(Requirement req,
44-
GenericSignature sig) {
43+
static bool shouldSplitConcreteEquivalenceClass(
44+
Requirement req,
45+
const RequirementMachine *machine) {
4546
return (req.getKind() == RequirementKind::SameType &&
4647
req.getSecondType()->isTypeParameter() &&
47-
sig->isConcreteType(req.getSecondType()));
48+
machine->isConcreteType(req.getSecondType()));
4849
}
4950

5051
/// Returns true if this generic signature contains abstract same-type
5152
/// requirements between concrete type parameters. In this case, we split
5253
/// the abstract same-type requirements into pairs of concrete type
5354
/// requirements, and minimize the signature again.
54-
static bool shouldSplitConcreteEquivalenceClasses(GenericSignature sig) {
55-
for (auto req : sig.getRequirements()) {
56-
if (shouldSplitConcreteEquivalenceClass(req, sig))
55+
static bool shouldSplitConcreteEquivalenceClasses(
56+
ArrayRef<Requirement> requirements,
57+
const RequirementMachine *machine) {
58+
for (auto req : requirements) {
59+
if (shouldSplitConcreteEquivalenceClass(req, machine))
5760
return true;
5861
}
5962

@@ -67,8 +70,10 @@ static bool shouldSplitConcreteEquivalenceClasses(GenericSignature sig) {
6770
/// ahead of time.
6871
static void splitConcreteEquivalenceClasses(
6972
ASTContext &ctx,
70-
GenericSignature sig,
71-
SmallVectorImpl<StructuralRequirement> &requirements,
73+
ArrayRef<Requirement> requirements,
74+
const RequirementMachine *machine,
75+
TypeArrayView<GenericTypeParamType> genericParams,
76+
SmallVectorImpl<StructuralRequirement> &splitRequirements,
7277
unsigned &attempt) {
7378
unsigned maxAttempts =
7479
ctx.LangOpts.RequirementMachineMaxSplitConcreteEquivClassAttempts;
@@ -77,26 +82,32 @@ static void splitConcreteEquivalenceClasses(
7782
if (attempt >= maxAttempts) {
7883
llvm::errs() << "Splitting concrete equivalence classes did not "
7984
<< "reach fixed point after " << attempt << " attempts.\n";
80-
llvm::errs() << "Last result: " << sig << "\n";
85+
llvm::errs() << "Last attempt produced these requirements:\n";
86+
for (auto req : requirements) {
87+
req.dump(llvm::errs());
88+
llvm::errs() << "\n";
89+
}
90+
machine->dump(llvm::errs());
8191
abort();
8292
}
8393

84-
requirements.clear();
94+
splitRequirements.clear();
8595

86-
for (auto req : sig.getRequirements()) {
87-
if (shouldSplitConcreteEquivalenceClass(req, sig)) {
88-
auto concreteType = sig->getConcreteType(req.getSecondType());
96+
for (auto req : requirements) {
97+
if (shouldSplitConcreteEquivalenceClass(req, machine)) {
98+
auto concreteType = machine->getConcreteType(
99+
req.getSecondType(), genericParams);
89100

90101
Requirement firstReq(RequirementKind::SameType,
91102
req.getFirstType(), concreteType);
92103
Requirement secondReq(RequirementKind::SameType,
93104
req.getSecondType(), concreteType);
94-
requirements.push_back({firstReq, SourceLoc(), /*inferred=*/false});
95-
requirements.push_back({secondReq, SourceLoc(), /*inferred=*/false});
105+
splitRequirements.push_back({firstReq, SourceLoc(), /*inferred=*/false});
106+
splitRequirements.push_back({secondReq, SourceLoc(), /*inferred=*/false});
96107
continue;
97108
}
98109

99-
requirements.push_back({req, SourceLoc(), /*inferred=*/false});
110+
splitRequirements.push_back({req, SourceLoc(), /*inferred=*/false});
100111
}
101112
}
102113

@@ -458,8 +469,11 @@ AbstractGenericSignatureRequestRQM::evaluate(
458469
auto errorFlags = machine->getErrors();
459470

460471
if (!errorFlags) {
461-
if (shouldSplitConcreteEquivalenceClasses(result)) {
462-
splitConcreteEquivalenceClasses(ctx, result, requirements, attempt);
472+
if (shouldSplitConcreteEquivalenceClasses(result.getRequirements(),
473+
machine.get())) {
474+
splitConcreteEquivalenceClasses(ctx, result.getRequirements(),
475+
machine.get(), result.getGenericParams(),
476+
requirements, attempt);
463477
continue;
464478
}
465479

@@ -622,8 +636,11 @@ InferredGenericSignatureRequestRQM::evaluate(
622636

623637
if (!errorFlags) {
624638
// Check if we need to rebuild the signature.
625-
if (shouldSplitConcreteEquivalenceClasses(result)) {
626-
splitConcreteEquivalenceClasses(ctx, result, requirements, attempt);
639+
if (shouldSplitConcreteEquivalenceClasses(result.getRequirements(),
640+
machine.get())) {
641+
splitConcreteEquivalenceClasses(ctx, result.getRequirements(),
642+
machine.get(), result.getGenericParams(),
643+
requirements, attempt);
627644
continue;
628645
}
629646

test/SILGen/class_conforms_with_default_concrete_self.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// RUN: %target-swift-emit-silgen %s -requirement-machine-abstract-signatures=on | %FileCheck %s
2-
// RUN: %target-swift-emit-silgen %s -requirement-machine-abstract-signatures=on -disable-requirement-machine-concrete-contraction | %FileCheck %s
32

43
public protocol P {
54
associatedtype A : Q where A.B == Self

0 commit comments

Comments
 (0)