Skip to content

Commit 908123a

Browse files
committed
[GSB] Fix requirement sources from protocol requirement signature.
The stored dependent types in ProtocolRequirement elements within requirement sources were incorrect for requirements created from the requirement signature of another protocol, because we picked up the already-substituted subject type. Thread the optional substitution map through addRequirement(Requirement) as well, so we maintain the original spelling of the stored dependent type. This is a temporary fix; we should be able to recover the stored dependent types from the potential archetypes in the requirement source, so that we don't need to specify them explicitly at construction time.
1 parent edf915c commit 908123a

File tree

3 files changed

+49
-19
lines changed

3 files changed

+49
-19
lines changed

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,9 +339,11 @@ class GenericSignatureBuilder {
339339
///
340340
/// \returns true if this requirement makes the set of requirements
341341
/// inconsistent, in which case a diagnostic will have been issued.
342-
bool addRequirement(const Requirement &req, FloatingRequirementSource source);
342+
bool addRequirement(const Requirement &req, FloatingRequirementSource source,
343+
const SubstitutionMap *subMap = nullptr);
343344

344345
bool addRequirement(const Requirement &req, FloatingRequirementSource source,
346+
const SubstitutionMap *subMap,
345347
llvm::SmallPtrSetImpl<ProtocolDecl *> &Visited);
346348

347349
/// \brief Add a new requirement.
@@ -821,6 +823,9 @@ class GenericSignatureBuilder::RequirementSource final
821823
.dyn_cast<const RequirementRepr *>();
822824
}
823825

826+
/// Retrieve the type stored in this requirement.
827+
Type getStoredType() const;
828+
824829
/// Retrieve the protocol for this requirement, if there is one.
825830
ProtocolDecl *getProtocolDecl() const;
826831

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,20 @@ PotentialArchetype *RequirementSource::getRootPotentialArchetype() const {
421421
return storage.rootArchetype;
422422
}
423423

424+
Type RequirementSource::getStoredType() const {
425+
switch (storageKind) {
426+
case StorageKind::RootArchetype:
427+
case StorageKind::ProtocolConformance:
428+
case StorageKind::AssociatedTypeDecl:
429+
return Type();
430+
431+
case StorageKind::StoredType:
432+
return storage.type;
433+
}
434+
435+
llvm_unreachable("Unhandled StorageKind in switch.");
436+
}
437+
424438
ProtocolDecl *RequirementSource::getProtocolDecl() const {
425439
switch (storageKind) {
426440
case StorageKind::RootArchetype:
@@ -1845,10 +1859,8 @@ bool GenericSignatureBuilder::addConformanceRequirement(PotentialArchetype *PAT,
18451859

18461860
auto innerSource =
18471861
FloatingRequirementSource::viaProtocolRequirement(Source, Proto);
1848-
for (auto rawReq : reqSig->getRequirements()) {
1849-
auto req = rawReq.subst(protocolSubMap);
1850-
assert(req && "substituting Self in requirement shouldn't fail");
1851-
if (addRequirement(*req, innerSource, Visited))
1862+
for (auto req : reqSig->getRequirements()) {
1863+
if (addRequirement(req, innerSource, &protocolSubMap, Visited))
18521864
return true;
18531865
}
18541866

@@ -2423,6 +2435,7 @@ bool GenericSignatureBuilder::addRequirement(const RequirementRepr *Req,
24232435
return t;
24242436
};
24252437

2438+
24262439
switch (Req->getKind()) {
24272440
case RequirementReprKind::LayoutConstraint: {
24282441
// FIXME: Need to do something here.
@@ -2454,7 +2467,7 @@ bool GenericSignatureBuilder::addRequirement(const RequirementRepr *Req,
24542467

24552468
// Check whether this is a supertype requirement.
24562469
if (Req->getConstraint()->getClassOrBoundGenericClass()) {
2457-
return addSuperclassRequirement(PA, Req->getConstraint(),
2470+
return addSuperclassRequirement(PA, subst(Req->getConstraint()),
24582471
source.getSource(PA, Req->getSubject()));
24592472
}
24602473

@@ -2494,18 +2507,29 @@ bool GenericSignatureBuilder::addRequirement(const RequirementRepr *Req,
24942507
}
24952508

24962509
bool GenericSignatureBuilder::addRequirement(const Requirement &req,
2497-
FloatingRequirementSource source) {
2498-
llvm::SmallPtrSet<ProtocolDecl *, 8> Visited;
2499-
return addRequirement(req, source, Visited);
2510+
FloatingRequirementSource source,
2511+
const SubstitutionMap *subMap) {
2512+
llvm::SmallPtrSet<ProtocolDecl *, 8> visited;
2513+
return addRequirement(req, source, subMap, visited);
25002514
}
25012515

25022516
bool GenericSignatureBuilder::addRequirement(
2503-
const Requirement &req, FloatingRequirementSource source,
2504-
llvm::SmallPtrSetImpl<ProtocolDecl *> &Visited) {
2517+
const Requirement &req,
2518+
FloatingRequirementSource source,
2519+
const SubstitutionMap *subMap,
2520+
llvm::SmallPtrSetImpl<ProtocolDecl *> &Visited) {
2521+
auto subst = [&](Type t) {
2522+
if (subMap)
2523+
return t.subst(*subMap);
2524+
2525+
return t;
2526+
};
2527+
2528+
25052529
switch (req.getKind()) {
25062530
case RequirementKind::Superclass: {
25072531
// FIXME: Diagnose this.
2508-
PotentialArchetype *pa = resolveArchetype(req.getFirstType());
2532+
PotentialArchetype *pa = resolveArchetype(subst(req.getFirstType()));
25092533
if (!pa) return false;
25102534

25112535
assert(req.getSecondType()->getClassOrBoundGenericClass());
@@ -2515,7 +2539,7 @@ bool GenericSignatureBuilder::addRequirement(
25152539

25162540
case RequirementKind::Layout: {
25172541
// FIXME: Diagnose this.
2518-
PotentialArchetype *pa = resolveArchetype(req.getFirstType());
2542+
PotentialArchetype *pa = resolveArchetype(subst(req.getFirstType()));
25192543
if (!pa) return false;
25202544

25212545
return addLayoutRequirement(pa, req.getLayoutConstraint(),
@@ -2524,7 +2548,7 @@ bool GenericSignatureBuilder::addRequirement(
25242548

25252549
case RequirementKind::Conformance: {
25262550
// FIXME: Diagnose this.
2527-
PotentialArchetype *pa = resolveArchetype(req.getFirstType());
2551+
PotentialArchetype *pa = resolveArchetype(subst(req.getFirstType()));
25282552
if (!pa) return false;
25292553

25302554
SmallVector<ProtocolDecl *, 4> conformsTo;
@@ -2533,8 +2557,9 @@ bool GenericSignatureBuilder::addRequirement(
25332557
// Add each of the protocols.
25342558
for (auto proto : conformsTo) {
25352559
if (Visited.count(proto)) {
2536-
markPotentialArchetypeRecursive(pa, proto,
2537-
source.getSource(pa, req.getFirstType()));
2560+
markPotentialArchetypeRecursive(
2561+
pa, proto,
2562+
source.getSource(pa, req.getFirstType()));
25382563
continue;
25392564
}
25402565
if (addConformanceRequirement(pa, proto,
@@ -2548,7 +2573,7 @@ bool GenericSignatureBuilder::addRequirement(
25482573

25492574
case RequirementKind::SameType:
25502575
return addSameTypeRequirement(
2551-
req.getFirstType(), req.getSecondType(), source,
2576+
subst(req.getFirstType()), subst(req.getSecondType()), source,
25522577
[&](Type type1, Type type2) {
25532578
if (source.getLoc().isValid())
25542579
Diags.diagnose(source.getLoc(), diag::requires_same_concrete_type,

test/Generics/requirement_inference.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ struct Model_P3_P4_Eq<T : P3, U : P4> where T.P3Assoc == U.P4Assoc {}
117117
// CHECK-NEXT: Requirements:
118118
// CHECK-NEXT: τ_0_0 : P3 [τ_0_0: Inferred @ {{.*}}:32]
119119
// CHECK-NEXT: τ_0_1 : P4 [τ_0_1: Inferred @ {{.*}}:32]
120-
// CHECK-NEXT: τ_0_0[.P3].P3Assoc : P1 [τ_0_0: Inferred @ {{.*}}:32 -> Protocol requirement (via Self.P3Assoc in P3) -> Protocol requirement (via Self.P3Assoc in P2)]
120+
// CHECK-NEXT: τ_0_0[.P3].P3Assoc : P1 [τ_0_0: Inferred @ {{.*}}:32 -> Protocol requirement (via Self.P3Assoc in P3) -> Protocol requirement (via Self in P2)]
121121
// CHECK-NEXT: τ_0_0[.P3].P3Assoc : P2 [τ_0_0: Inferred @ {{.*}}:32 -> Protocol requirement (via Self.P3Assoc in P3)]
122122
// FIXME: τ_0_0[.P3].P3Assoc == τ_0_1[.P4].P4Assoc [τ_0_0: Inferred]
123123
func inferSameType1<T, U>(_ x: Model_P3_P4_Eq<T, U>) { }
@@ -126,7 +126,7 @@ func inferSameType1<T, U>(_ x: Model_P3_P4_Eq<T, U>) { }
126126
// CHECK-NEXT: Requirements:
127127
// CHECK-NEXT: τ_0_0 : P3 [τ_0_0: Explicit @ {{.*}}:25]
128128
// CHECK-NEXT: τ_0_1 : P4 [τ_0_1: Explicit @ {{.*}}:33]
129-
// CHECK-NEXT: τ_0_0[.P3].P3Assoc : P1 [τ_0_0: Explicit @ {{.*}}:25 -> Protocol requirement (via Self.P3Assoc in P3) -> Protocol requirement (via Self.P3Assoc in P2)]
129+
// CHECK-NEXT: τ_0_0[.P3].P3Assoc : P1 [τ_0_0: Explicit @ {{.*}}:25 -> Protocol requirement (via Self.P3Assoc in P3) -> Protocol requirement (via Self in P2)]
130130
// CHECK-NEXT: τ_0_0[.P3].P3Assoc : P2 [τ_0_0: Explicit @ {{.*}}:25 -> Protocol requirement (via Self.P3Assoc in P3)]
131131
// CHECK-NEXT: τ_0_0[.P3].P3Assoc == τ_0_1[.P4].P4Assoc [τ_0_0[.P3].P3Assoc: Explicit]
132132
func inferSameType2<T : P3, U : P4>(_: T, _: U) where U.P4Assoc : P2, T.P3Assoc == U.P4Assoc {}

0 commit comments

Comments
 (0)