Skip to content

Commit 4860607

Browse files
committed
[GSB] Record unresolved potential archetypes as delayed requirements.
Whenever we form a potential archetype that is unresolved (because it names a member wasn't known at the time the potential archetype was formed), create a corresponding delayed requirement to resolve the potential archetype. This ensures that all potential archetypes get a chance to be resolve, fixing the nested type should have matched associated type assertion in rdar://problem/31401161 (and others).
1 parent aac0574 commit 4860607

File tree

3 files changed

+78
-8
lines changed

3 files changed

+78
-8
lines changed

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,10 @@ class GenericSignatureBuilder {
265265
GenericSignatureBuilder(const GenericSignatureBuilder &) = delete;
266266
GenericSignatureBuilder &operator=(const GenericSignatureBuilder &) = delete;
267267

268+
/// Record that the given potential archetype is unresolved, so we know to
269+
/// resolve it later.
270+
void recordUnresolvedType(PotentialArchetype *unresolvedPA);
271+
268272
/// When a particular requirement cannot be resolved due to, e.g., a
269273
/// currently-unresolvable or nested type, this routine should be
270274
/// called to cope with the unresolved requirement.
@@ -294,6 +298,9 @@ class GenericSignatureBuilder {
294298
ProtocolDecl *Proto,
295299
const RequirementSource *Source);
296300

301+
/// Try to resolve the given unresolved potential archetype.
302+
ConstraintResult resolveUnresolvedType(PotentialArchetype *pa);
303+
297304
public:
298305
/// \brief Add a new same-type requirement between two fully resolved types
299306
/// (output of \c GenericSignatureBuilder::resolve).
@@ -1325,13 +1332,7 @@ class GenericSignatureBuilder::PotentialArchetype {
13251332

13261333
/// \brief Construct a new potential archetype for an unresolved
13271334
/// associated type.
1328-
PotentialArchetype(PotentialArchetype *parent, Identifier name)
1329-
: parentOrBuilder(parent), identifier(name), isUnresolvedNestedType(true),
1330-
IsRecursive(false), Invalid(false),
1331-
DiagnosedRename(false)
1332-
{
1333-
assert(parent != nullptr && "Not an associated type?");
1334-
}
1335+
PotentialArchetype(PotentialArchetype *parent, Identifier name);
13351336

13361337
/// \brief Construct a new potential archetype for an associated type.
13371338
PotentialArchetype(PotentialArchetype *parent, AssociatedTypeDecl *assocType)
@@ -1688,6 +1689,9 @@ class GenericSignatureBuilder::DelayedRequirement {
16881689

16891690
/// A same-type requirement.
16901691
SameType,
1692+
1693+
/// An unresolved potential archetype.
1694+
Unresolved,
16911695
};
16921696

16931697
Kind kind;

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,16 @@ bool FloatingRequirementSource::isRecursive(
10251025
return false;
10261026
}
10271027

1028+
PotentialArchetype::PotentialArchetype(PotentialArchetype *parent,
1029+
Identifier name)
1030+
: parentOrBuilder(parent), identifier(name), isUnresolvedNestedType(true),
1031+
IsRecursive(false), Invalid(false),
1032+
DiagnosedRename(false)
1033+
{
1034+
assert(parent != nullptr && "Not an associated type?");
1035+
getBuilder()->recordUnresolvedType(this);
1036+
}
1037+
10281038
GenericSignatureBuilder::PotentialArchetype::~PotentialArchetype() {
10291039
++NumPotentialArchetypes;
10301040

@@ -1202,6 +1212,15 @@ void EquivalenceClass::dump() const {
12021212
dump(llvm::errs());
12031213
}
12041214

1215+
void GenericSignatureBuilder::recordUnresolvedType(
1216+
PotentialArchetype *unresolvedPA) {
1217+
++Impl->NumUnresolvedNestedTypes;
1218+
1219+
Impl->DelayedRequirements.push_back(
1220+
{DelayedRequirement::Unresolved, unresolvedPA, RequirementRHS(),
1221+
FloatingRequirementSource::forAbstract()});
1222+
}
1223+
12051224
ConstraintResult GenericSignatureBuilder::handleUnresolvedRequirement(
12061225
RequirementKind kind,
12071226
UnresolvedType lhs,
@@ -1770,7 +1789,6 @@ PotentialArchetype *PotentialArchetype::getNestedArchetypeAnchor(
17701789
auto &nested = NestedTypes[name];
17711790
if (nested.empty()) {
17721791
nested.push_back(new PotentialArchetype(this, name));
1773-
++builder.Impl->NumUnresolvedNestedTypes;
17741792

17751793
auto rep = getRepresentative();
17761794
if (rep != this) {
@@ -2788,6 +2806,32 @@ ConstraintResult GenericSignatureBuilder::addConformanceRequirement(
27882806
return ConstraintResult::Resolved;
27892807
}
27902808

2809+
ConstraintResult GenericSignatureBuilder::resolveUnresolvedType(
2810+
PotentialArchetype *pa) {
2811+
// If something else resolved this type, we're done.
2812+
if (!pa->isUnresolved())
2813+
return ConstraintResult::Resolved;
2814+
2815+
// If the parent isn't resolved, we can't resolve this now.
2816+
auto parentPA = pa->getParent();
2817+
if (parentPA->isUnresolved())
2818+
return ConstraintResult::Unresolved;
2819+
2820+
// Resolve this via its parent.
2821+
auto resolvedPA =
2822+
parentPA->getNestedArchetypeAnchor(
2823+
pa->getNestedName(),
2824+
*this,
2825+
PotentialArchetype::NestedTypeUpdate::ResolveExisting);
2826+
if (resolvedPA) {
2827+
assert(!pa->isUnresolved() && "This type must have been resolved");
2828+
return ConstraintResult::Resolved;
2829+
}
2830+
2831+
// We are unable to resolve this constraint.
2832+
return ConstraintResult::Unresolved;
2833+
}
2834+
27912835
ConstraintResult GenericSignatureBuilder::addLayoutRequirementDirect(
27922836
PotentialArchetype *PAT,
27932837
LayoutConstraint Layout,
@@ -4146,6 +4190,10 @@ void GenericSignatureBuilder::processDelayedRequirements() {
41464190
req.lhs, asUnresolvedType(req.rhs), req.source,
41474191
UnresolvedHandlingKind::ReturnUnresolved);
41484192
break;
4193+
4194+
case DelayedRequirement::Unresolved:
4195+
reqResult = resolveUnresolvedType(req.lhs.get<PotentialArchetype *>());
4196+
break;
41494197
}
41504198

41514199
// Update our state based on what happened.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
// rdar://problem/31401161
4+
class C1 {}
5+
6+
protocol P1 {
7+
associatedtype Element
8+
}
9+
10+
protocol P2 : P1 {
11+
associatedtype SubSequence : P1 // expected-note{{'SubSequence' declared here}}
12+
}
13+
14+
protocol P3 : P2 {
15+
associatedtype SubSequence : P2 // expected-warning{{redeclaration of associated type 'SubSequence' from protocol 'P2' is better expressed as a 'where' clause on the protocol}}
16+
}
17+
18+
func foo<S>(_: S) where S.SubSequence.Element == C1, S : P3 {}

0 commit comments

Comments
 (0)