Skip to content

Commit e41a173

Browse files
authored
Merge pull request swiftlang#74538 from slavapestov/fix-rdar129540617
Sema: Re-introduce the hack for re-using generic signature of extended protocol
2 parents 91f79c4 + f747121 commit e41a173

File tree

4 files changed

+43
-12
lines changed

4 files changed

+43
-12
lines changed

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,25 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
815815

816816
auto *extendedNominal = ext->getExtendedNominal();
817817

818+
// Avoid building a generic signature if we have an unconstrained protocol
819+
// extension of a protocol that does not suppress conformance to ~Copyable
820+
// or ~Escapable. This avoids a request cycle when referencing a protocol
821+
// extension type alias via an unqualified name from a `where` clause on
822+
// the protocol.
823+
if (auto *proto = dyn_cast<ProtocolDecl>(extendedNominal)) {
824+
if (extraReqs.empty() &&
825+
!ext->getTrailingWhereClause()) {
826+
InvertibleProtocolSet protos;
827+
for (auto *inherited : proto->getAllInheritedProtocols()) {
828+
if (auto kind = inherited->getInvertibleProtocolKind())
829+
protos.insert(*kind);
830+
}
831+
832+
if (protos == InvertibleProtocolSet::allKnown())
833+
return extendedNominal->getGenericSignatureOfContext();
834+
}
835+
}
836+
818837
if (isa<BuiltinTupleDecl>(extendedNominal)) {
819838
genericParams = ext->getGenericParams();
820839
} else {

lib/Sema/TypeCheckType.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -536,10 +536,10 @@ Type TypeResolution::resolveTypeInContext(TypeDecl *typeDecl,
536536
typeDecl->getDeclContext()->getSelfProtocolDecl()) {
537537
// When looking up a nominal type declaration inside of a
538538
// protocol extension, always use the nominal type and
539-
// not the protocol 'Self' type.
540-
if (!foundDC->getDeclaredInterfaceType())
541-
return ErrorType::get(ctx);
542-
539+
// not the protocol 'Self' type. This is invalid and will
540+
// be diagnosed anyway, but we want to avoid an invariant
541+
// violation from trying to construct a nominal type with
542+
// a generic parameter as its parent type.
543543
selfType = foundDC->getDeclaredInterfaceType();
544544
} else {
545545
// Otherwise, we want the protocol 'Self' type for
@@ -735,7 +735,8 @@ void swift::diagnoseInvalidGenericArguments(SourceLoc loc,
735735
/// error.
736736
///
737737
/// \see TypeResolution::applyUnboundGenericArguments
738-
static Type applyGenericArguments(Type type, TypeResolution resolution,
738+
static Type applyGenericArguments(Type type,
739+
const TypeResolution &resolution,
739740
SILTypeResolutionContext *silContext,
740741
DeclRefTypeRepr *repr) {
741742
auto options = resolution.getOptions();
@@ -1249,7 +1250,7 @@ static void maybeDiagnoseBadConformanceRef(DeclContext *dc,
12491250

12501251
/// Returns a valid type or ErrorType in case of an error.
12511252
static Type resolveTypeDecl(TypeDecl *typeDecl, DeclContext *foundDC,
1252-
TypeResolution resolution,
1253+
const TypeResolution &resolution,
12531254
SILTypeResolutionContext *silContext,
12541255
UnqualifiedIdentTypeRepr *repr) {
12551256
// Resolve the type declaration to a specific type. How this occurs
@@ -1306,7 +1307,7 @@ static std::string getDeclNameFromContext(DeclContext *dc,
13061307
///
13071308
/// \returns either the corrected type, if possible, or an error type to
13081309
/// that correction failed.
1309-
static Type diagnoseUnknownType(TypeResolution resolution,
1310+
static Type diagnoseUnknownType(const TypeResolution &resolution,
13101311
Type parentType,
13111312
SourceRange parentRange,
13121313
DeclRefTypeRepr *repr,
@@ -1570,7 +1571,7 @@ static SelfTypeKind getSelfTypeKind(DeclContext *dc,
15701571
}
15711572
}
15721573

1573-
static void diagnoseGenericArgumentsOnSelf(TypeResolution resolution,
1574+
static void diagnoseGenericArgumentsOnSelf(const TypeResolution &resolution,
15741575
UnqualifiedIdentTypeRepr *repr,
15751576
DeclContext *typeDC) {
15761577
ASTContext &ctx = resolution.getASTContext();
@@ -1597,7 +1598,7 @@ static void diagnoseGenericArgumentsOnSelf(TypeResolution resolution,
15971598
/// \returns Either the resolved type or a null type, the latter of
15981599
/// which indicates that some dependencies were unsatisfied.
15991600
static Type
1600-
resolveUnqualifiedIdentTypeRepr(TypeResolution resolution,
1601+
resolveUnqualifiedIdentTypeRepr(const TypeResolution &resolution,
16011602
SILTypeResolutionContext *silContext,
16021603
UnqualifiedIdentTypeRepr *repr) {
16031604
const auto options = resolution.getOptions();
@@ -1773,7 +1774,7 @@ static void diagnoseAmbiguousMemberType(Type baseTy, SourceRange baseRange,
17731774
/// lookup within the given parent type, returning the type it
17741775
/// references.
17751776
/// \param silContext Used to look up generic parameters in SIL mode.
1776-
static Type resolveQualifiedIdentTypeRepr(TypeResolution resolution,
1777+
static Type resolveQualifiedIdentTypeRepr(const TypeResolution &resolution,
17771778
SILTypeResolutionContext *silContext,
17781779
Type parentTy,
17791780
QualifiedIdentTypeRepr *repr) {

test/Generics/rdar123013710.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ extension Never: Q, P { // expected-note 2{{through reference here}}
1515
public static func f() -> Any? { nil }
1616
}
1717

18-
extension Q { // expected-note {{through reference here}}
19-
public var b: Never { fatalError() } // expected-note 4{{through reference here}}
18+
extension Q {
19+
public var b: Never { fatalError() } // expected-note {{through reference here}}
2020
}
2121

test/NameLookup/protocol_extension_where_clause.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,15 @@ extension P1 where Self: A {
2828
// This is terrible and we should ban it some day
2929
extension P1 where Self: A, B: Hashable {
3030
func h(_: Set<B>) {}
31+
}
32+
33+
// This is also terrible and we should ban it
34+
public protocol P3 {
35+
associatedtype A
36+
}
37+
38+
public protocol P4: P3 where A == B {}
39+
40+
extension P4 {
41+
public typealias B = String
3142
}

0 commit comments

Comments
 (0)