Skip to content

Commit 884c475

Browse files
committed
Sema: Replace ASTContext::addDelayedMissingWitnesses() with ASTContext::addDelayedMissingWitness()
Instead of passing a unique_ptr of an opaque type back and forth, let's just push elements onto an std::vector. For now this change is completely NFC, but further simplifications will become possible shortly.
1 parent 6671a64 commit 884c475

File tree

5 files changed

+71
-79
lines changed

5 files changed

+71
-79
lines changed

include/swift/AST/ASTContext.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ namespace swift {
123123
class Pattern;
124124
enum PointerTypeKind : unsigned;
125125
class PrecedenceGroupDecl;
126+
struct RequirementMatch;
126127
class TupleTypeElt;
127128
class EnumElementDecl;
128129
class ProtocolDecl;
@@ -1317,6 +1318,19 @@ class ASTContext final {
13171318
std::function<void(NormalProtocolConformance *)> Callback;
13181319
};
13191320

1321+
/// Describes a missing witness during conformance checking.
1322+
class MissingWitness {
1323+
public:
1324+
/// The requirement that is missing a witness.
1325+
ValueDecl *requirement;
1326+
1327+
/// The set of potential matching witnesses.
1328+
std::vector<RequirementMatch> matches;
1329+
1330+
MissingWitness(ValueDecl *requirement,
1331+
ArrayRef<RequirementMatch> matches);
1332+
};
1333+
13201334
/// Check whether current context has any errors associated with
13211335
/// ill-formed protocol conformances which haven't been produced yet.
13221336
///
@@ -1339,13 +1353,13 @@ class ASTContext final {
13391353
takeDelayedConformanceDiags(NormalProtocolConformance const* conformance);
13401354

13411355
/// Add delayed missing witnesses for the given normal protocol conformance.
1342-
void addDelayedMissingWitnesses(
1356+
void addDelayedMissingWitness(
13431357
NormalProtocolConformance *conformance,
1344-
std::unique_ptr<MissingWitnessesBase> missingWitnesses);
1358+
MissingWitness missingWitness);
13451359

13461360
/// Retrieve the delayed missing witnesses for the given normal protocol
13471361
/// conformance.
1348-
std::unique_ptr<MissingWitnessesBase>
1362+
std::vector<MissingWitness>
13491363
takeDelayedMissingWitnesses(NormalProtocolConformance *conformance);
13501364

13511365
/// Produce a specialized conformance, which takes a generic

lib/AST/ASTContext.cpp

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "swift/AST/PropertyWrappers.h"
4747
#include "swift/AST/ProtocolConformance.h"
4848
#include "swift/AST/RawComment.h"
49+
#include "swift/AST/RequirementMatch.h"
4950
#include "swift/AST/SILLayout.h"
5051
#include "swift/AST/SearchPathOptions.h"
5152
#include "swift/AST/SemanticAttrs.h"
@@ -205,12 +206,19 @@ namespace {
205206
/// are discarded, since we'll emit them again when we compile the file as
206207
/// a primary file.
207208
struct DelayedConformanceDiags {
208-
/// We set this if we've ever seen an error diagnostic here.
209-
bool HadError = false;
210-
211209
/// The delayed conformance diagnostics that have not been emitted yet.
212210
/// Never actually emitted for a secondary file.
213211
std::vector<ASTContext::DelayedConformanceDiag> Diags;
212+
213+
/// Any missing witnesses that need to be diagnosed.
214+
std::vector<ASTContext::MissingWitness> MissingWitnesses;
215+
216+
/// We set this if we've ever seen an error diagnostic here.
217+
unsigned HadError : 1;
218+
219+
DelayedConformanceDiags() {
220+
HadError = false;
221+
}
214222
};
215223

216224
}
@@ -379,13 +387,6 @@ struct ASTContext::Implementation {
379387
llvm::DenseMap<NormalProtocolConformance *, ::DelayedConformanceDiags>
380388
DelayedConformanceDiags;
381389

382-
/// Map from normal protocol conformances to missing witnesses that have
383-
/// been delayed until the conformance is fully checked, so that we can
384-
/// issue a fixit that fills the entire protocol stub.
385-
llvm::DenseMap<
386-
NormalProtocolConformance *, std::unique_ptr<MissingWitnessesBase>>
387-
DelayedMissingWitnesses;
388-
389390
/// Stores information about lazy deserialization of various declarations.
390391
llvm::DenseMap<const Decl *, LazyContextData *> LazyContexts;
391392

@@ -2774,7 +2775,10 @@ bool ASTContext::hasDelayedConformanceErrors(
27742775
return false;
27752776
}
27762777

2777-
MissingWitnessesBase::~MissingWitnessesBase() { }
2778+
ASTContext::MissingWitness::MissingWitness(ValueDecl *requirement,
2779+
ArrayRef<RequirementMatch> matches)
2780+
: requirement(requirement),
2781+
matches(matches.begin(), matches.end()) { }
27782782

27792783
void ASTContext::addDelayedConformanceDiag(
27802784
NormalProtocolConformance *conformance, bool isError,
@@ -2822,20 +2826,21 @@ void ASTContext::addDelayedConformanceDiag(
28222826
diagnostics.Diags.push_back({isError, callback});
28232827
}
28242828

2825-
void ASTContext::addDelayedMissingWitnesses(
2829+
void ASTContext::addDelayedMissingWitness(
28262830
NormalProtocolConformance *conformance,
2827-
std::unique_ptr<MissingWitnessesBase> missingWitnesses) {
2828-
getImpl().DelayedMissingWitnesses[conformance] = std::move(missingWitnesses);
2831+
ASTContext::MissingWitness missingWitness) {
2832+
auto &diagnostics = getImpl().DelayedConformanceDiags[conformance];
2833+
diagnostics.MissingWitnesses.push_back(missingWitness);
28292834
}
28302835

2831-
std::unique_ptr<MissingWitnessesBase>
2836+
std::vector<ASTContext::MissingWitness>
28322837
ASTContext::takeDelayedMissingWitnesses(
28332838
NormalProtocolConformance *conformance) {
2834-
std::unique_ptr<MissingWitnessesBase> result;
2835-
auto known = getImpl().DelayedMissingWitnesses.find(conformance);
2836-
if (known != getImpl().DelayedMissingWitnesses.end()) {
2837-
result = std::move(known->second);
2838-
getImpl().DelayedMissingWitnesses.erase(known);
2839+
std::vector<ASTContext::MissingWitness> result;
2840+
auto known = getImpl().DelayedConformanceDiags.find(conformance);
2841+
if (known != getImpl().DelayedConformanceDiags.end()) {
2842+
auto &diagnostics = known->second;
2843+
std::swap(result, diagnostics.MissingWitnesses);
28392844
}
28402845
return result;
28412846
}
@@ -2845,7 +2850,8 @@ ASTContext::takeDelayedConformanceDiags(NormalProtocolConformance const* cnfrm){
28452850
std::vector<ASTContext::DelayedConformanceDiag> result;
28462851
auto known = getImpl().DelayedConformanceDiags.find(cnfrm);
28472852
if (known != getImpl().DelayedConformanceDiags.end()) {
2848-
std::swap(result, known->second.Diags);
2853+
auto &diagnostics = known->second;
2854+
std::swap(result, diagnostics.Diags);
28492855
}
28502856
return result;
28512857
}

lib/Sema/CSDiagnostics.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3453,7 +3453,7 @@ bool ContextualFailure::tryProtocolConformanceFixIt(
34533453
{
34543454
llvm::SmallString<128> Text;
34553455
llvm::raw_svector_ostream SS(Text);
3456-
llvm::SetVector<MissingWitness> missingWitnesses;
3456+
llvm::SetVector<ASTContext::MissingWitness> missingWitnesses;
34573457
for (auto protocol : missingProtocols) {
34583458
auto conformance = NormalProtocolConformance(
34593459
nominal->getDeclaredType(), protocol, SourceLoc(), nominal,

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1802,7 +1802,7 @@ class swift::MultiConformanceChecker {
18021802
llvm::SmallVector<ValueDecl*, 16> UnsatisfiedReqs;
18031803
llvm::SmallVector<ConformanceChecker, 4> AllUsedCheckers;
18041804
llvm::SmallVector<NormalProtocolConformance*, 4> AllConformances;
1805-
llvm::SetVector<MissingWitness> MissingWitnesses;
1805+
llvm::SetVector<ASTContext::MissingWitness> MissingWitnesses;
18061806
llvm::SmallPtrSet<ValueDecl *, 8> CoveredMembers;
18071807

18081808
/// Check one conformance.
@@ -2068,17 +2068,13 @@ checkIndividualConformance(NormalProtocolConformance *conformance,
20682068
bool issueFixit) {
20692069
PrettyStackTraceConformance trace("type-checking", conformance);
20702070

2071-
std::vector<MissingWitness> revivedMissingWitnesses;
2071+
std::vector<ASTContext::MissingWitness> revivedMissingWitnesses;
20722072
switch (conformance->getState()) {
20732073
case ProtocolConformanceState::Incomplete:
20742074
if (conformance->isInvalid()) {
20752075
// Revive registered missing witnesses to handle it below.
2076-
if (auto delayed = getASTContext().takeDelayedMissingWitnesses(
2077-
conformance)) {
2078-
revivedMissingWitnesses = std::move(
2079-
static_cast<DelayedMissingWitnesses *>(
2080-
delayed.get())->missingWitnesses);
2081-
}
2076+
revivedMissingWitnesses = getASTContext().takeDelayedMissingWitnesses(
2077+
conformance);
20822078

20832079
// If we have no missing witnesses for this invalid conformance, the
20842080
// conformance is invalid for other reasons, so emit diagnosis now.
@@ -2875,7 +2871,7 @@ diagnoseMatch(ModuleDecl *module, NormalProtocolConformance *conformance,
28752871

28762872
ConformanceChecker::ConformanceChecker(
28772873
ASTContext &ctx, NormalProtocolConformance *conformance,
2878-
llvm::SetVector<MissingWitness> &GlobalMissingWitnesses)
2874+
llvm::SetVector<ASTContext::MissingWitness> &GlobalMissingWitnesses)
28792875
: WitnessChecker(ctx, conformance->getProtocol(), conformance->getType(),
28802876
conformance->getDeclContext()),
28812877
Conformance(conformance), Loc(conformance->getLoc()),
@@ -3662,12 +3658,12 @@ printRequirementStub(ValueDecl *Requirement, DeclContext *Adopter,
36623658
/// NoStubRequirements.
36633659
static void
36643660
printProtocolStubFixitString(SourceLoc TypeLoc, ProtocolConformance *Conf,
3665-
ArrayRef<MissingWitness> MissingWitnesses,
3661+
ArrayRef<ASTContext::MissingWitness> MissingWitnesses,
36663662
std::string &FixitString,
36673663
llvm::SetVector<ValueDecl*> &NoStubRequirements) {
36683664
llvm::raw_string_ostream FixitStream(FixitString);
36693665
std::for_each(MissingWitnesses.begin(), MissingWitnesses.end(),
3670-
[&](const MissingWitness &Missing) {
3666+
[&](const ASTContext::MissingWitness &Missing) {
36713667
if (!printRequirementStub(
36723668
Missing.requirement, Conf->getDeclContext(), Conf->getType(),
36733669
TypeLoc, FixitStream)) {
@@ -3679,10 +3675,10 @@ printProtocolStubFixitString(SourceLoc TypeLoc, ProtocolConformance *Conf,
36793675
/// Filter the given array of protocol requirements and produce a new vector
36803676
/// containing the non-conflicting requirements to be implemented by the given
36813677
/// \c Adoptee type.
3682-
static llvm::SmallVector<MissingWitness, 4>
3678+
static llvm::SmallVector<ASTContext::MissingWitness, 4>
36833679
filterProtocolRequirements(
3684-
ArrayRef<MissingWitness> MissingWitnesses, Type Adoptee) {
3685-
llvm::SmallVector<MissingWitness, 4> Filtered;
3680+
ArrayRef<ASTContext::MissingWitness> MissingWitnesses, Type Adoptee) {
3681+
llvm::SmallVector<ASTContext::MissingWitness, 4> Filtered;
36863682
if (MissingWitnesses.empty()) {
36873683
return Filtered;
36883684
}
@@ -3733,12 +3729,12 @@ filterProtocolRequirements(
37333729

37343730
/// Prune the set of missing witnesses for the given conformance, eliminating
37353731
/// any requirements that do not actually need to satisfied.
3736-
static ArrayRef<MissingWitness> pruneMissingWitnesses(
3732+
static ArrayRef<ASTContext::MissingWitness> pruneMissingWitnesses(
37373733
ConformanceChecker &checker,
37383734
ProtocolDecl *proto,
37393735
NormalProtocolConformance *conformance,
3740-
ArrayRef<MissingWitness> missingWitnesses,
3741-
SmallVectorImpl<MissingWitness> &scratch) {
3736+
ArrayRef<ASTContext::MissingWitness> missingWitnesses,
3737+
SmallVectorImpl<ASTContext::MissingWitness> &scratch) {
37423738
if (missingWitnesses.empty()) {
37433739
return missingWitnesses;
37443740
}
@@ -3831,7 +3827,7 @@ bool ConformanceChecker::
38313827
diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind, bool Delayed) {
38323828
auto LocalMissing = getLocalMissingWitness();
38333829

3834-
SmallVector<MissingWitness, 4> MissingWitnessScratch;
3830+
SmallVector<ASTContext::MissingWitness, 4> MissingWitnessScratch;
38353831
LocalMissing = pruneMissingWitnesses(
38363832
*this, Proto, Conformance, LocalMissing, MissingWitnessScratch);
38373833

@@ -3860,7 +3856,7 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind, bool Delayed) {
38603856

38613857
const auto InsertFixit = [](
38623858
NormalProtocolConformance *Conf, SourceLoc ComplainLoc, bool EditorMode,
3863-
llvm::SmallVector<MissingWitness, 4> MissingWitnesses) {
3859+
llvm::SmallVector<ASTContext::MissingWitness, 4> MissingWitnesses) {
38643860
DeclContext *DC = Conf->getDeclContext();
38653861
// The location where to insert stubs.
38663862
SourceLoc FixitLocation;
@@ -3974,9 +3970,9 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind, bool Delayed) {
39743970
// If the diagnostics are suppressed, we register these missing witnesses
39753971
// for later revisiting.
39763972
Conformance->setInvalid();
3977-
getASTContext().addDelayedMissingWitnesses(
3978-
Conformance,
3979-
std::make_unique<DelayedMissingWitnesses>(MissingWitnesses));
3973+
for (auto Missing : MissingWitnesses) {
3974+
getASTContext().addDelayedMissingWitness(Conformance, Missing);
3975+
}
39803976
} else {
39813977
auto Loc = this->Loc;
39823978
getASTContext().addDelayedConformanceDiag(Conformance, true,
@@ -6914,7 +6910,7 @@ TypeWitnessAndDecl
69146910
TypeWitnessRequest::evaluate(Evaluator &eval,
69156911
NormalProtocolConformance *conformance,
69166912
AssociatedTypeDecl *requirement) const {
6917-
llvm::SetVector<MissingWitness> MissingWitnesses;
6913+
llvm::SetVector<ASTContext::MissingWitness> MissingWitnesses;
69186914
ConformanceChecker checker(requirement->getASTContext(), conformance,
69196915
MissingWitnesses);
69206916
checker.resolveSingleTypeWitness(requirement);
@@ -6933,7 +6929,7 @@ Witness
69336929
ValueWitnessRequest::evaluate(Evaluator &eval,
69346930
NormalProtocolConformance *conformance,
69356931
ValueDecl *requirement) const {
6936-
llvm::SetVector<MissingWitness> MissingWitnesses;
6932+
llvm::SetVector<ASTContext::MissingWitness> MissingWitnesses;
69376933
ConformanceChecker checker(requirement->getASTContext(), conformance,
69386934
MissingWitnesses);
69396935
checker.resolveSingleWitness(requirement);

lib/Sema/TypeCheckProtocol.h

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "TypeChecker.h"
2222
#include "swift/AST/AccessScope.h"
23+
#include "swift/AST/ASTContext.h"
2324
#include "swift/AST/RequirementEnvironment.h"
2425
#include "swift/AST/RequirementMatch.h"
2526
#include "swift/AST/Type.h"
@@ -323,31 +324,6 @@ enum class MissingWitnessDiagnosisKind {
323324
class AssociatedTypeInference;
324325
class MultiConformanceChecker;
325326

326-
/// Describes a missing witness during conformance checking.
327-
class MissingWitness {
328-
public:
329-
/// The requirement that is missing a witness.
330-
ValueDecl *requirement;
331-
332-
/// The set of potential matching witnesses.
333-
std::vector<RequirementMatch> matches;
334-
335-
MissingWitness(ValueDecl *requirement,
336-
ArrayRef<RequirementMatch> matches)
337-
: requirement(requirement),
338-
matches(matches.begin(), matches.end()) { }
339-
};
340-
341-
/// Capture missing witnesses that have been delayed and will be stored
342-
/// in the ASTContext for later.
343-
class DelayedMissingWitnesses : public MissingWitnessesBase {
344-
public:
345-
std::vector<MissingWitness> missingWitnesses;
346-
347-
DelayedMissingWitnesses(ArrayRef<MissingWitness> missingWitnesses)
348-
: missingWitnesses(missingWitnesses.begin(), missingWitnesses.end()) { }
349-
};
350-
351327
/// The protocol conformance checker.
352328
///
353329
/// This helper class handles most of the details of checking whether a
@@ -371,7 +347,7 @@ class ConformanceChecker : public WitnessChecker {
371347
/// Keep track of missing witnesses, either type or value, for later
372348
/// diagnosis emits. This may contain witnesses that are external to the
373349
/// protocol under checking.
374-
llvm::SetVector<MissingWitness> &GlobalMissingWitnesses;
350+
llvm::SetVector<ASTContext::MissingWitness> &GlobalMissingWitnesses;
375351

376352
/// Keep track of the slice in GlobalMissingWitnesses that is local to
377353
/// this protocol under checking.
@@ -447,7 +423,7 @@ class ConformanceChecker : public WitnessChecker {
447423
/// the chosen type witnesses.
448424
void ensureRequirementsAreSatisfied();
449425

450-
ArrayRef<MissingWitness> getLocalMissingWitness() {
426+
ArrayRef<ASTContext::MissingWitness> getLocalMissingWitness() {
451427
return GlobalMissingWitnesses.getArrayRef().
452428
slice(LocalMissingWitnessesStartIndex,
453429
GlobalMissingWitnesses.size() - LocalMissingWitnessesStartIndex);
@@ -469,7 +445,7 @@ class ConformanceChecker : public WitnessChecker {
469445
void emitDelayedDiags();
470446

471447
ConformanceChecker(ASTContext &ctx, NormalProtocolConformance *conformance,
472-
llvm::SetVector<MissingWitness> &GlobalMissingWitnesses);
448+
llvm::SetVector<ASTContext::MissingWitness> &GlobalMissingWitnesses);
473449

474450
~ConformanceChecker();
475451

@@ -895,8 +871,8 @@ void diagnoseConformanceFailure(Type T,
895871
namespace llvm {
896872

897873
template<>
898-
struct DenseMapInfo<swift::MissingWitness> {
899-
using MissingWitness = swift::MissingWitness;
874+
struct DenseMapInfo<swift::ASTContext::MissingWitness> {
875+
using MissingWitness = swift::ASTContext::MissingWitness;
900876
using RequirementPointerTraits = DenseMapInfo<swift::ValueDecl *>;
901877

902878
static inline MissingWitness getEmptyKey() {

0 commit comments

Comments
 (0)