@@ -40,20 +40,23 @@ using namespace rewriting;
40
40
// / same-type requirement between type parameters where one of them has an
41
41
// / implied concrete type requirement. In this case, split it up into two
42
42
// / concrete type requirements.
43
- static bool shouldSplitConcreteEquivalenceClass (Requirement req,
44
- GenericSignature sig) {
43
+ static bool shouldSplitConcreteEquivalenceClass (
44
+ Requirement req,
45
+ const RequirementMachine *machine) {
45
46
return (req.getKind () == RequirementKind::SameType &&
46
47
req.getSecondType ()->isTypeParameter () &&
47
- sig ->isConcreteType (req.getSecondType ()));
48
+ machine ->isConcreteType (req.getSecondType ()));
48
49
}
49
50
50
51
// / Returns true if this generic signature contains abstract same-type
51
52
// / requirements between concrete type parameters. In this case, we split
52
53
// / the abstract same-type requirements into pairs of concrete type
53
54
// / 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))
57
60
return true ;
58
61
}
59
62
@@ -67,8 +70,10 @@ static bool shouldSplitConcreteEquivalenceClasses(GenericSignature sig) {
67
70
// / ahead of time.
68
71
static void splitConcreteEquivalenceClasses (
69
72
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,
72
77
unsigned &attempt) {
73
78
unsigned maxAttempts =
74
79
ctx.LangOpts .RequirementMachineMaxSplitConcreteEquivClassAttempts ;
@@ -77,26 +82,32 @@ static void splitConcreteEquivalenceClasses(
77
82
if (attempt >= maxAttempts) {
78
83
llvm::errs () << " Splitting concrete equivalence classes did not "
79
84
<< " 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 ());
81
91
abort ();
82
92
}
83
93
84
- requirements .clear ();
94
+ splitRequirements .clear ();
85
95
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);
89
100
90
101
Requirement firstReq (RequirementKind::SameType,
91
102
req.getFirstType (), concreteType);
92
103
Requirement secondReq (RequirementKind::SameType,
93
104
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 });
96
107
continue ;
97
108
}
98
109
99
- requirements .push_back ({req, SourceLoc (), /* inferred=*/ false });
110
+ splitRequirements .push_back ({req, SourceLoc (), /* inferred=*/ false });
100
111
}
101
112
}
102
113
@@ -458,8 +469,11 @@ AbstractGenericSignatureRequestRQM::evaluate(
458
469
auto errorFlags = machine->getErrors ();
459
470
460
471
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);
463
477
continue ;
464
478
}
465
479
@@ -622,8 +636,11 @@ InferredGenericSignatureRequestRQM::evaluate(
622
636
623
637
if (!errorFlags) {
624
638
// 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);
627
644
continue ;
628
645
}
629
646
0 commit comments