Skip to content

Commit 5cebbb2

Browse files
authored
Merge pull request #19844 from slavapestov/protocol-where-self-is-crap
Sema: Allow protocols with 'Self' constraints again
2 parents 3fe38e2 + 64f12ff commit 5cebbb2

16 files changed

+961
-124
lines changed

include/swift/AST/DeclContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ class alignas(1 << DeclContextAlignInBits) DeclContext {
501501
/// lookup.
502502
///
503503
/// \returns true if anything was found.
504-
bool lookupQualified(ArrayRef<TypeDecl *> types, DeclName member,
504+
bool lookupQualified(ArrayRef<NominalTypeDecl *> types, DeclName member,
505505
NLOptions options,
506506
SmallVectorImpl<ValueDecl *> &decls) const;
507507

include/swift/AST/NameLookup.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ namespace swift {
3434
class Type;
3535
class TypeDecl;
3636
class ValueDecl;
37+
struct SelfBounds;
3738

3839
/// LookupResultEntry - One result of unqualified lookup.
3940
struct LookupResultEntry {
@@ -374,6 +375,12 @@ getDirectlyInheritedNominalTypeDecls(
374375
llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl,
375376
bool &anyObject);
376377

378+
/// Retrieve the set of nominal type declarations that appear as the
379+
/// constraint type of any "Self" constraints in the where clause of the
380+
/// given protocol or protocol extension.
381+
SelfBounds getSelfBoundsFromWhereClause(
382+
llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl);
383+
377384
} // end namespace swift
378385

379386
#endif

include/swift/AST/NameLookupRequests.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -182,26 +182,31 @@ class ExtendedNominalRequest :
182182
void noteCycleStep(DiagnosticEngine &diags) const;
183183
};
184184

185+
struct SelfBounds {
186+
llvm::TinyPtrVector<NominalTypeDecl *> decls;
187+
bool anyObject = false;
188+
};
189+
185190
/// Request the nominal types that occur as the right-hand side of "Self: Foo"
186191
/// constraints in the "where" clause of a protocol extension.
187192
class SelfBoundsFromWhereClauseRequest :
188193
public SimpleRequest<SelfBoundsFromWhereClauseRequest,
189194
CacheKind::Uncached,
190-
llvm::TinyPtrVector<NominalTypeDecl *>,
191-
ExtensionDecl *> {
195+
SelfBounds,
196+
llvm::PointerUnion<TypeDecl *, ExtensionDecl *>> {
192197
public:
193198
using SimpleRequest::SimpleRequest;
194199

195200
private:
196201
friend SimpleRequest;
197202

198203
// Evaluation.
199-
llvm::TinyPtrVector<NominalTypeDecl *> evaluate(Evaluator &evaluator,
200-
ExtensionDecl *ext) const;
204+
SelfBounds evaluate(Evaluator &evaluator,
205+
llvm::PointerUnion<TypeDecl *, ExtensionDecl *>) const;
201206

202207
public:
203208
// Cycle handling
204-
llvm::TinyPtrVector<NominalTypeDecl *> breakCycle() const { return { }; }
209+
SelfBounds breakCycle() const { return { }; }
205210
void diagnoseCycle(DiagnosticEngine &diags) const;
206211
void noteCycleStep(DiagnosticEngine &diags) const;
207212
};

lib/AST/Decl.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3642,7 +3642,7 @@ ProtocolDecl::getInheritedProtocols() const {
36423642
SmallPtrSet<const ProtocolDecl *, 4> known;
36433643
known.insert(this);
36443644
bool anyObject = false;
3645-
for (const auto &found :
3645+
for (const auto found :
36463646
getDirectlyInheritedNominalTypeDecls(
36473647
const_cast<ProtocolDecl *>(this), anyObject)) {
36483648
if (auto proto = dyn_cast<ProtocolDecl>(found.second)) {
@@ -3758,12 +3758,14 @@ bool ProtocolDecl::requiresClassSlow() {
37583758
getDirectlyInheritedNominalTypeDecls(this, anyObject);
37593759

37603760
// Quick check: do we inherit AnyObject?
3761-
if (anyObject)
3762-
return Bits.ProtocolDecl.RequiresClass = true;
3761+
if (anyObject) {
3762+
Bits.ProtocolDecl.RequiresClass = true;
3763+
return true;
3764+
}
37633765

37643766
// Look through all of the inherited nominals for a superclass or a
37653767
// class-bound protocol.
3766-
for (const auto &found : allInheritedNominals) {
3768+
for (const auto found : allInheritedNominals) {
37673769
// Superclass bound.
37683770
if (isa<ClassDecl>(found.second))
37693771
return Bits.ProtocolDecl.RequiresClass = true;

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7251,19 +7251,18 @@ void GenericSignatureBuilder::enumerateRequirements(
72517251
// Enumerate conformance requirements.
72527252
SmallVector<ProtocolDecl *, 4> protocols;
72537253
DenseMap<ProtocolDecl *, const RequirementSource *> protocolSources;
7254-
if (equivClass) {
7255-
for (const auto &conforms : equivClass->conformsTo) {
7256-
protocols.push_back(conforms.first);
7257-
assert(protocolSources.count(conforms.first) == 0 &&
7258-
"redundant protocol requirement?");
7259-
7260-
protocolSources.insert(
7261-
{conforms.first,
7262-
*getBestConstraintSource<ProtocolDecl *>(conforms.second,
7263-
[&](ProtocolDecl *proto) {
7264-
return proto == conforms.first;
7265-
})});
7266-
}
7254+
7255+
for (const auto &conforms : equivClass->conformsTo) {
7256+
protocols.push_back(conforms.first);
7257+
assert(protocolSources.count(conforms.first) == 0 &&
7258+
"redundant protocol requirement?");
7259+
7260+
protocolSources.insert(
7261+
{conforms.first,
7262+
*getBestConstraintSource<ProtocolDecl *>(conforms.second,
7263+
[&](ProtocolDecl *proto) {
7264+
return proto == conforms.first;
7265+
})});
72677266
}
72687267

72697268
// Sort the protocols in canonical order.

0 commit comments

Comments
 (0)