Skip to content

Commit fcd41a0

Browse files
committed
RequirementMachine: Fix introduction of same-type requirement for recursive concrete witness
1 parent 0f3ec0f commit fcd41a0

File tree

2 files changed

+42
-11
lines changed

2 files changed

+42
-11
lines changed

lib/AST/RequirementMachine/ConcreteTypeWitness.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,14 @@ MutableTerm PropertyMap::computeConstraintTermForTypeWitness(
314314
return result;
315315
}
316316

317+
// Compute the concrete type symbol [concrete: C.X].
318+
SmallVector<Term, 3> result;
319+
auto typeWitnessSchema =
320+
Context.getRelativeSubstitutionSchemaFromType(typeWitness, substitutions,
321+
result);
322+
auto typeWitnessSymbol =
323+
Symbol::forConcreteType(typeWitnessSchema, result, Context);
324+
317325
// If the type witness is completely concrete, check if one of our prefix
318326
// types has the same concrete type, and if so, introduce a same-type
319327
// requirement between the subject type and the prefix.
@@ -326,10 +334,14 @@ MutableTerm PropertyMap::computeConstraintTermForTypeWitness(
326334
if (auto *props = lookUpProperties(prefix)) {
327335
if (props->isConcreteType() &&
328336
props->getConcreteType() == typeWitness) {
329-
auto result = props->getKey();
337+
// Record a relation U.[concrete: C.X] =>> U.V.[concrete: C : P].[P:X]
338+
// where U is the parent such that U.[concrete: C:X] => U.
339+
MutableTerm result(props->getKey());
340+
result.add(typeWitnessSymbol);
330341

331342
unsigned relationID = System.recordRelation(
332-
result, Term::get(subjectType, Context));
343+
Term::get(result, Context),
344+
Term::get(subjectType, Context));
333345
path.add(RewriteStep::forRelation(
334346
/*startOffset=*/0, relationID,
335347
/*inverse=*/false));
@@ -339,7 +351,7 @@ MutableTerm PropertyMap::computeConstraintTermForTypeWitness(
339351
<< result << "\n";
340352
}
341353

342-
return MutableTerm(result);
354+
return result;
343355
}
344356
}
345357

@@ -350,14 +362,6 @@ MutableTerm PropertyMap::computeConstraintTermForTypeWitness(
350362
// Otherwise the type witness is concrete, but may contain type
351363
// parameters in structural position.
352364

353-
// Compute the concrete type symbol [concrete: C.X].
354-
SmallVector<Term, 3> result;
355-
auto typeWitnessSchema =
356-
Context.getRelativeSubstitutionSchemaFromType(typeWitness, substitutions,
357-
result);
358-
auto typeWitnessSymbol =
359-
Symbol::forConcreteType(typeWitnessSchema, result, Context);
360-
361365
auto concreteConformanceSymbol = *(subjectType.end() - 2);
362366
auto associatedTypeSymbol = *(subjectType.end() - 1);
363367

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-inferred-signatures=on 2>&1 | %FileCheck %s
2+
3+
protocol P1 {
4+
associatedtype X
5+
}
6+
7+
protocol P2 {
8+
associatedtype Y
9+
}
10+
11+
protocol P3: P2 {
12+
associatedtype Z: P1 where Z.X == C
13+
}
14+
15+
struct C: P3 {
16+
typealias Y = C
17+
18+
struct Z: P1 {
19+
typealias X = C
20+
}
21+
}
22+
23+
// CHECK-LABEL: ExtensionDecl line={{.*}} base=P1
24+
// CHECK-NEXT: Generic signature: <Self where Self : P1, Self.[P1]X : P2, Self.[P1]X.[P2]Y == C>
25+
extension P1 where X: P2, X.Y : P3, X.Y == C {
26+
func foo(_ x: X.Y) -> C { return x }
27+
}

0 commit comments

Comments
 (0)