Skip to content

Commit 3df206b

Browse files
authored
Merge pull request swiftlang#74746 from hamishknight/confirmance-6.0
[6.0] [Sema] Pass down ProtocolConformance to DerivedConformance
2 parents 0ef287a + 1e1af1a commit 3df206b

File tree

6 files changed

+30
-61
lines changed

6 files changed

+30
-61
lines changed

lib/Sema/AssociatedTypeInference.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2488,20 +2488,16 @@ AssociatedTypeInference::computeDefaultTypeWitness(
24882488
}
24892489

24902490
static std::pair<Type, TypeDecl *>
2491-
deriveTypeWitness(DeclContext *DC,
2492-
NominalTypeDecl *TypeDecl,
2493-
AssociatedTypeDecl *AssocType) {
2491+
deriveTypeWitness(const NormalProtocolConformance *Conformance,
2492+
NominalTypeDecl *TypeDecl, AssociatedTypeDecl *AssocType) {
24942493
auto *protocol = cast<ProtocolDecl>(AssocType->getDeclContext());
24952494

24962495
auto knownKind = protocol->getKnownProtocolKind();
24972496

24982497
if (!knownKind)
24992498
return std::make_pair(nullptr, nullptr);
25002499

2501-
auto Decl = DC->getInnermostDeclarationDeclContext();
2502-
2503-
DerivedConformance derived(TypeDecl->getASTContext(), Decl, TypeDecl,
2504-
protocol);
2500+
DerivedConformance derived(Conformance, TypeDecl, protocol);
25052501
switch (*knownKind) {
25062502
case KnownProtocolKind::RawRepresentable:
25072503
return std::make_pair(derived.deriveRawRepresentable(AssocType), nullptr);
@@ -2535,7 +2531,7 @@ AssociatedTypeInference::computeDerivedTypeWitness(
25352531
return std::make_pair(Type(), nullptr);
25362532

25372533
// Try to derive the type witness.
2538-
auto result = deriveTypeWitness(dc, derivingTypeDecl, assocType);
2534+
auto result = deriveTypeWitness(conformance, derivingTypeDecl, assocType);
25392535
if (!result.first)
25402536
return std::make_pair(Type(), nullptr);
25412537

lib/Sema/DerivedConformanceEquatableHashable.cpp

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -952,20 +952,6 @@ getHashValueRequirement(ASTContext &C) {
952952
return nullptr;
953953
}
954954

955-
static ProtocolConformance *
956-
getHashableConformance(const Decl *parentDecl) {
957-
ASTContext &C = parentDecl->getASTContext();
958-
const auto IDC = cast<IterableDeclContext>(parentDecl);
959-
auto hashableProto = C.getProtocol(KnownProtocolKind::Hashable);
960-
for (auto conformance: IDC->getLocalConformances(
961-
ConformanceLookupKind::NonStructural)) {
962-
if (conformance->getProtocol() == hashableProto) {
963-
return conformance;
964-
}
965-
}
966-
return nullptr;
967-
}
968-
969955
bool DerivedConformance::canDeriveHashable(NominalTypeDecl *type) {
970956
// FIXME: This is not actually correct. We cannot promise to always
971957
// provide a witness here in all cases. Unfortunately, figuring out
@@ -984,21 +970,18 @@ void DerivedConformance::tryDiagnoseFailedHashableDerivation(
984970
}
985971

986972
ValueDecl *DerivedConformance::deriveHashable(ValueDecl *requirement) {
987-
ASTContext &C = ConformanceDecl->getASTContext();
988-
989973
// var hashValue: Int
990-
if (requirement->getBaseName() == C.Id_hashValue) {
974+
if (requirement->getBaseName() == Context.Id_hashValue) {
991975
// We always allow hashValue to be synthesized; invalid cases are diagnosed
992976
// during hash(into:) synthesis.
993977
return deriveHashable_hashValue(*this);
994978
}
995979

996980
// Hashable.hash(into:)
997-
if (requirement->getBaseName() == C.Id_hash) {
981+
if (requirement->getBaseName() == Context.Id_hash) {
998982
// Start by resolving hashValue conformance.
999-
auto hashValueReq = getHashValueRequirement(C);
1000-
auto conformance = getHashableConformance(ConformanceDecl);
1001-
auto hashValueDecl = conformance->getWitnessDecl(hashValueReq);
983+
auto hashValueReq = getHashValueRequirement(Context);
984+
auto hashValueDecl = Conformance->getWitnessDecl(hashValueReq);
1002985
if (!hashValueDecl) {
1003986
// We won't derive hash(into:) if hashValue cannot be resolved.
1004987
// The hashValue failure will produce a diagnostic elsewhere.
@@ -1010,7 +993,7 @@ ValueDecl *DerivedConformance::deriveHashable(ValueDecl *requirement) {
1010993

1011994
// Refuse to synthesize Hashable if type isn't a struct or enum, or if it
1012995
// has non-Hashable stored properties/associated values.
1013-
auto hashableProto = C.getProtocol(KnownProtocolKind::Hashable);
996+
auto hashableProto = Context.getProtocol(KnownProtocolKind::Hashable);
1014997
if (!canDeriveConformance(getConformanceContext(), Nominal,
1015998
hashableProto)) {
1016999
ConformanceDecl->diagnose(diag::type_does_not_conform,

lib/Sema/DerivedConformances.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,23 @@ using namespace swift;
2828

2929
enum NonconformingMemberKind { AssociatedValue, StoredProperty };
3030

31-
DerivedConformance::DerivedConformance(ASTContext &ctx, Decl *conformanceDecl,
32-
NominalTypeDecl *nominal,
33-
ProtocolDecl *protocol)
34-
: Context(ctx), ConformanceDecl(conformanceDecl), Nominal(nominal),
35-
Protocol(protocol) {
36-
assert(getConformanceContext()->getSelfNominalTypeDecl() == nominal);
31+
DerivedConformance::DerivedConformance(
32+
const NormalProtocolConformance *conformance, NominalTypeDecl *nominal,
33+
ProtocolDecl *protocol)
34+
: Context(nominal->getASTContext()), Conformance(conformance),
35+
Nominal(nominal), Protocol(protocol) {
36+
auto *DC = Conformance->getDeclContext();
37+
ConformanceDecl = DC->getInnermostDeclarationDeclContext();
38+
assert(ConformanceDecl);
39+
assert(DC->getSelfNominalTypeDecl() == nominal);
3740
}
3841

3942
DeclContext *DerivedConformance::getConformanceContext() const {
40-
return cast<DeclContext>(ConformanceDecl);
43+
return Conformance->getDeclContext();
4144
}
4245

4346
ModuleDecl *DerivedConformance::getParentModule() const {
44-
return cast<DeclContext>(ConformanceDecl)->getParentModule();
47+
return getConformanceContext()->getParentModule();
4548
}
4649

4750
void DerivedConformance::addMembersToConformanceContext(
@@ -279,7 +282,7 @@ void DerivedConformance::diagnoseIfSynthesisUnsupportedForDecl(
279282
ValueDecl *DerivedConformance::getDerivableRequirement(NominalTypeDecl *nominal,
280283
ValueDecl *requirement) {
281284
// Note: whenever you update this function, also update
282-
// TypeChecker::deriveProtocolRequirement.
285+
// deriveProtocolRequirement.
283286
ASTContext &ctx = nominal->getASTContext();
284287
const auto name = requirement->getName();
285288

lib/Sema/DerivedConformances.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,12 @@ class DerivedConformance {
5555

5656
public:
5757
ASTContext &Context;
58+
const NormalProtocolConformance *Conformance;
5859
Decl *ConformanceDecl;
5960
NominalTypeDecl *Nominal;
6061
ProtocolDecl *Protocol;
6162

62-
DerivedConformance(ASTContext &ctx, Decl *conformanceDecl,
63+
DerivedConformance(const NormalProtocolConformance *conformance,
6364
NominalTypeDecl *nominal, ProtocolDecl *protocol);
6465

6566
/// Retrieve the context in which the conformance is declared (either the

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4499,9 +4499,9 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
44994499
return ResolveWitnessResult::ExplicitFailed;
45004500
}
45014501

4502-
static ValueDecl *deriveProtocolRequirement(DeclContext *DC,
4503-
NominalTypeDecl *TypeDecl,
4504-
ValueDecl *Requirement) {
4502+
static ValueDecl *
4503+
deriveProtocolRequirement(const NormalProtocolConformance *Conformance,
4504+
NominalTypeDecl *TypeDecl, ValueDecl *Requirement) {
45054505
// Note: whenever you update this function, also update
45064506
// DerivedConformance::getDerivableRequirement.
45074507
const auto protocol = cast<ProtocolDecl>(Requirement->getDeclContext());
@@ -4510,12 +4510,12 @@ static ValueDecl *deriveProtocolRequirement(DeclContext *DC,
45104510
if (!derivableKind)
45114511
return nullptr;
45124512

4513+
auto *DC = Conformance->getDeclContext();
45134514
const auto Decl = DC->getInnermostDeclarationDeclContext();
45144515
if (Decl->isInvalid())
45154516
return nullptr;
45164517

4517-
DerivedConformance derived(TypeDecl->getASTContext(), Decl, TypeDecl,
4518-
protocol);
4518+
DerivedConformance derived(Conformance, TypeDecl, protocol);
45194519

45204520
switch (*derivableKind) {
45214521
case KnownDerivableProtocolKind::RawRepresentable:
@@ -4596,7 +4596,8 @@ ResolveWitnessResult ConformanceChecker::resolveWitnessViaDerivation(
45964596
}
45974597

45984598
// Attempt to derive the witness.
4599-
auto derived = deriveProtocolRequirement(DC, derivingTypeDecl, requirement);
4599+
auto derived =
4600+
deriveProtocolRequirement(Conformance, derivingTypeDecl, requirement);
46004601

46014602
if (!derived) {
46024603
return ResolveWitnessResult::ExplicitFailed;

lib/Sema/TypeChecker.h

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -826,21 +826,6 @@ void checkConformancesInContext(IterableDeclContext *idc);
826826
/// Check that the type of the given property conforms to NSCopying.
827827
ProtocolConformanceRef checkConformanceToNSCopying(VarDecl *var);
828828

829-
/// Derive an implicit declaration to satisfy a requirement of a derived
830-
/// protocol conformance.
831-
///
832-
/// \param DC The declaration context where the conformance was
833-
/// defined, either the type itself or an extension
834-
/// \param TypeDecl The type for which the requirement is being derived.
835-
/// \param Requirement The protocol requirement.
836-
///
837-
/// \returns nullptr if the derivation failed, or the derived declaration
838-
/// if it succeeded. If successful, the derived declaration is added
839-
/// to TypeDecl's body.
840-
ValueDecl *deriveProtocolRequirement(DeclContext *DC,
841-
NominalTypeDecl *TypeDecl,
842-
ValueDecl *Requirement);
843-
844829
/// \name Name lookup
845830
///
846831
/// Routines that perform name lookup.

0 commit comments

Comments
 (0)