Skip to content

Commit

Permalink
Sema: Re-introduce the hack for re-using generic signature of extende…
Browse files Browse the repository at this point in the history
…d protocol

In Swift 5.10 if you wrote `extension Foo {}` for some protocol Foo,
the extension would always re-use the generic signature of Foo, which
is <Self where Self: Foo>. In Swift 6 this no longer works because Foo
might be ~Copyable, in which case `extension Foo {}` adds default
requirements, so we changed GenericSignatureRequest to just always
build a new signature if we're given an extension.

However, to avoid a request cycle with a code example that really should
have never worked at all, I'm re-introducing the hack for re-using the
signature.

Fixes rdar://problem/129540617.
  • Loading branch information
slavapestov committed Jun 18, 2024
1 parent 6d1ca1e commit 493d6d1
Showing 1 changed file with 23 additions and 2 deletions.
25 changes: 23 additions & 2 deletions lib/Sema/TypeCheckGeneric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,29 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,

auto *extendedNominal = ext->getExtendedNominal();

collectAdditionalExtensionRequirements(ext->getExtendedType(), extraReqs);

// Avoid building a generic signature if we have an unconstrained protocol
// extension of a protocol that does not suppress conformance to ~Copyable
// or ~Escapable. This is just here to allow this silly edge case which
// should have been banned:
//
// protocol P where A == B { associatedtype A }
// extension P { typealias B = Int }
if (auto *proto = dyn_cast<ProtocolDecl>(extendedNominal)) {
if (extraReqs.empty() &&
!ext->getTrailingWhereClause()) {
InvertibleProtocolSet protos;
for (auto *inherited : proto->getAllInheritedProtocols()) {
if (auto kind = inherited->getInvertibleProtocolKind())
protos.insert(*kind);
}

if (protos == InvertibleProtocolSet::allKnown())
return extendedNominal->getGenericSignatureOfContext();
}
}

if (isa<BuiltinTupleDecl>(extendedNominal)) {
genericParams = ext->getGenericParams();
} else {
Expand All @@ -798,8 +821,6 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
if (ext->hasInvertibleLocalConformance())
inferInvertibleReqs = false;

collectAdditionalExtensionRequirements(ext->getExtendedType(), extraReqs);

} else {
llvm_unreachable("Unknown generic declaration kind");
}
Expand Down

0 comments on commit 493d6d1

Please sign in to comment.