Skip to content

Commit 3cee2af

Browse files
committed
Remove Cascading Verification from the Dependency Verifier`
Now that the frontend no longer produces these edges, we do not need to assert about them.
1 parent 62555ec commit 3cee2af

File tree

7 files changed

+165
-241
lines changed

7 files changed

+165
-241
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -399,22 +399,14 @@ REMARK(interface_file_lock_timed_out,none,
399399
"timed out waiting to acquire lock file for module interface '%0'", (StringRef))
400400

401401
// Dependency Verifier Diagnostics
402-
ERROR(dependency_cascading_mismatch,none,
403-
"expected %select{non-cascading|cascading}0 dependency; found "
404-
"%select{non-cascading|cascading}1 dependency instead",
405-
(bool, bool))
406-
ERROR(potential_dependency_cascading_mismatch,none,
407-
"expected %select{non-cascading|cascading}0 potential member dependency; "
408-
"found %select{non-cascading|cascading}1 potential member dependency "
409-
"instead", (bool, bool))
410402
ERROR(missing_member_dependency,none,
411403
"expected "
412404
"%select{%error|provided|member|potential member|dynamic member}0 "
413405
"dependency does not exist: %1",
414406
(/*Expectation::Kind*/uint8_t, StringRef))
415407
ERROR(unexpected_dependency,none,
416-
"unexpected %0 %select{%error|%error|member|potential member|dynamic member}1 "
417-
"dependency: %2", (StringRef, /*Expectation::Kind*/uint8_t, StringRef))
408+
"unexpected %select{%error|%error|member|potential member|dynamic member}0 "
409+
"dependency: %1", (/*Expectation::Kind*/uint8_t, StringRef))
418410
ERROR(unexpected_provided_entity,none,
419411
"unexpected provided entity: %0", (StringRef))
420412
ERROR(negative_expectation_violated,none,

lib/Frontend/DependencyVerifier.cpp

Lines changed: 77 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -38,36 +38,33 @@ namespace {
3838
/// attached near the relevant declaration and takes one of the following forms:
3939
///
4040
/// // expected-provides {{ProvidedName}}
41-
/// // expected-private-member {{some.User.member}}
41+
/// // expected-member {{some.User.member}}
4242
///
4343
/// An expectation contains additional information about the expectation
4444
/// \c Kind, which matches one of the few kinds of dependency entry that are
45-
/// currently representable in the dependency graph, and an expectation
46-
/// \c Scope which must either be \c private or \c cascading.
45+
/// currently representable in the dependency graph.
4746
///
48-
/// As not all combinations of scopes and kinds makes sense, and to ease the addition of further
49-
/// combinations of the two, the supported set of expectations is given by the following matrix:
47+
/// As not all combinations of scopes and kinds makes sense, and to ease the
48+
/// addition of further combinations of the two, the supported set of
49+
/// expectations is given by the following matrix:
5050
///
5151
#define EXPECTATION_MATRIX \
52-
MATRIX_ENTRY("expected-no-dependency", None, Negative) \
53-
MATRIX_ENTRY("expected-provides", None, Provides) \
54-
MATRIX_ENTRY("expected-private-superclass", Private, Superclass) \
55-
MATRIX_ENTRY("expected-cascading-superclass", Cascading, Superclass) \
56-
MATRIX_ENTRY("expected-private-conformance", Private, Conformance) \
57-
MATRIX_ENTRY("expected-cascading-conformance", Cascading, Conformance) \
58-
MATRIX_ENTRY("expected-private-member", Private, Member) \
59-
MATRIX_ENTRY("expected-cascading-member", Cascading, Member) \
60-
MATRIX_ENTRY("expected-private-dynamic-member", Private, DynamicMember) \
61-
MATRIX_ENTRY("expected-cascading-dynamic-member", Cascading, DynamicMember)
52+
MATRIX_ENTRY("expected-no-dependency", Negative) \
53+
MATRIX_ENTRY("expected-provides", Provides) \
54+
MATRIX_ENTRY("expected-superclass", Superclass) \
55+
MATRIX_ENTRY("expected-conformance", Conformance) \
56+
MATRIX_ENTRY("expected-member", Member) \
57+
MATRIX_ENTRY("expected-dynamic-member", DynamicMember) \
6258
///
63-
/// To add a new supported combination, update \c Expectation::Kind and
64-
/// \c Expectation::Scope, then define a new \c MATRIX_ENTRY with the following information:
59+
/// To add a new supported combination, update \c Expectation::Kind
60+
/// then define a new \c MATRIX_ENTRY with the following information:
6561
///
66-
/// MATRIX_ENTRY(<Expectation-Selector-String>, Expectation::Scope, Expectation::Kind)
62+
/// MATRIX_ENTRY(<Expectation-Selector-String>, Expectation::Kind)
6763
///
68-
/// Where \c <Expectation-Selector-String> matches the grammar for an expectation. The
69-
/// verifier's parsing routines use this matrix to automatically keep the parser in harmony with the
70-
/// internal representation of the expectation.
64+
/// Where \c <Expectation-Selector-String> matches the grammar for an
65+
/// expectation. The verifier's parsing routines use this matrix to
66+
/// automatically keep the parser in harmony with the internal representation of
67+
/// the expectation.
7168
struct Expectation {
7269
public:
7370
enum class Kind : uint8_t {
@@ -80,41 +77,25 @@ struct Expectation {
8077
DynamicMember,
8178
};
8279

83-
enum class Scope : uint8_t {
84-
/// There is no scope information associated with this expectation.
85-
///
86-
/// This is currently only true of negative expectations and provides expectations.
87-
None,
88-
/// The dependency does not cascade.
89-
Private,
90-
/// The dependency cascades.
91-
Cascading,
92-
};
93-
9480
/// The full range of the "expected-foo {{}}".
9581
const char *ExpectedStart, *ExpectedEnd = nullptr;
9682

9783
/// Additional information about the expectation.
9884
struct {
9985
Expectation::Kind Kind;
100-
Expectation::Scope Scope;
10186
} Info;
10287

10388
/// The raw input buffer for the message text, the part in the {{...}}
10489
StringRef MessageRange;
10590

10691
public:
10792
Expectation(const char *estart, const char *eend, Expectation::Kind k,
108-
Expectation::Scope f, StringRef r)
109-
: ExpectedStart(estart), ExpectedEnd(eend), Info{k, f}, MessageRange(r) {
110-
assert(ExpectedStart <= MessageRange.data() &&
111-
"Message range appears before expected start!");
112-
assert(MessageRange.data()+MessageRange.size() <= ExpectedEnd &&
113-
"Message range extends beyond expected end!");
114-
}
115-
116-
bool isCascading() const {
117-
return Info.Scope == Expectation::Scope::Cascading;
93+
StringRef r)
94+
: ExpectedStart(estart), ExpectedEnd(eend), Info{k}, MessageRange(r) {
95+
assert(ExpectedStart <= MessageRange.data() &&
96+
"Message range appears before expected start!");
97+
assert(MessageRange.data() + MessageRange.size() <= ExpectedEnd &&
98+
"Message range extends beyond expected end!");
11899
}
119100
};
120101

@@ -214,43 +195,27 @@ struct Obligation {
214195

215196
private:
216197
StringRef name;
217-
std::pair<Expectation::Kind, Expectation::Scope> info;
198+
Expectation::Kind kind;
218199
State state;
219200

220201
public:
221-
Obligation(StringRef name, Expectation::Kind k, Expectation::Scope f)
222-
: name(name), info{k, f}, state(State::Owed) {
202+
Obligation(StringRef name, Expectation::Kind k)
203+
: name(name), kind{k}, state(State::Owed) {
223204
assert(k != Expectation::Kind::Negative &&
224205
"Cannot form negative obligation!");
225206
}
226207

227-
Expectation::Scope getScope() const { return info.second; }
228-
Expectation::Kind getKind() const { return info.first; }
208+
Expectation::Kind getKind() const { return kind; }
229209
StringRef getName() const { return name; }
230-
bool getCascades() const {
231-
return info.second == Expectation::Scope::Cascading;
232-
}
233-
StringRef describeCascade() const {
234-
switch (info.second) {
235-
case Expectation::Scope::None:
236-
llvm_unreachable("Cannot describe obligation with no cascade info");
237-
case Expectation::Scope::Private:
238-
return "non-cascading";
239-
case Expectation::Scope::Cascading:
240-
return "cascading";
241-
}
242-
llvm_unreachable("invalid expectation scope");
243-
}
244210

245211
StringRef renderAsFixit(ASTContext &Ctx) const {
246212
llvm::StringRef selector =
247-
#define MATRIX_ENTRY(SELECTOR, SCOPE, KIND) \
248-
if (getKind() == Expectation::Kind::KIND && \
249-
getScope() == Expectation::Scope::SCOPE) { \
250-
return SELECTOR; \
251-
}
213+
#define MATRIX_ENTRY(SELECTOR, KIND) \
214+
if (getKind() == Expectation::Kind::KIND) { \
215+
return SELECTOR; \
216+
}
252217

253-
[this]() -> StringRef {
218+
[this]() -> StringRef {
254219
EXPECTATION_MATRIX
255220
return "";
256221
}();
@@ -267,8 +232,7 @@ struct Obligation {
267232
return FullfillmentToken{};
268233
}
269234
FullfillmentToken fail() {
270-
assert(state == State::Owed &&
271-
"Cannot fail an obligation more than once!");
235+
assert(state == State::Owed && "Cannot fail an obligation more than once!");
272236
state = State::Failed;
273237
return FullfillmentToken{};
274238
}
@@ -372,19 +336,17 @@ bool DependencyVerifier::parseExpectations(
372336
const char *DiagnosticLoc = MatchStart.data();
373337

374338
Expectation::Kind ExpectedKind;
375-
Expectation::Scope ExpectedScope;
376339
{
377-
#define MATRIX_ENTRY(EXPECTATION_SELECTOR, SCOPE, KIND) \
340+
#define MATRIX_ENTRY(EXPECTATION_SELECTOR, KIND) \
378341
.StartsWith(EXPECTATION_SELECTOR, [&]() { \
379342
ExpectedKind = Expectation::Kind::KIND; \
380-
ExpectedScope = Expectation::Scope::SCOPE; \
381343
MatchStart = MatchStart.substr(strlen(EXPECTATION_SELECTOR)); \
382344
})
383345

384346
// clang-format off
385-
llvm::StringSwitch<llvm::function_ref<void(void)>>{MatchStart}
386-
EXPECTATION_MATRIX
387-
.Default([]() {})();
347+
llvm::StringSwitch<llvm::function_ref<void(void)>>{MatchStart}
348+
EXPECTATION_MATRIX
349+
.Default([]() {})();
388350
// clang-format on
389351
#undef MATRIX_ENTRY
390352
}
@@ -412,13 +374,11 @@ bool DependencyVerifier::parseExpectations(
412374
AfterEnd = AfterEnd.substr(AfterEnd.find_first_not_of(" \t"));
413375
const char *ExpectedEnd = AfterEnd.data();
414376

415-
416377
// Strip out the trailing whitespace.
417378
while (isspace(ExpectedEnd[-1]))
418379
--ExpectedEnd;
419380

420-
Expectations.emplace_back(DiagnosticLoc, ExpectedEnd,
421-
ExpectedKind, ExpectedScope,
381+
Expectations.emplace_back(DiagnosticLoc, ExpectedEnd, ExpectedKind,
422382
MatchStart.slice(2, End));
423383
}
424384
return false;
@@ -427,50 +387,37 @@ bool DependencyVerifier::parseExpectations(
427387
bool DependencyVerifier::constructObligations(const SourceFile *SF,
428388
ObligationMap &Obligations) {
429389
auto &Ctx = SF->getASTContext();
430-
Ctx.evaluator.enumerateReferencesInFile(
431-
SF, [&](const auto &reference) {
432-
const auto isCascadingUse = false;
433-
using NodeKind = evaluator::DependencyCollector::Reference::Kind;
434-
switch (reference.kind) {
435-
case NodeKind::Empty:
436-
case NodeKind::Tombstone:
437-
llvm_unreachable("Cannot enumerate dead dependency!");
438-
439-
case NodeKind::PotentialMember: {
440-
auto key = copyQualifiedTypeName(Ctx, reference.subject);
441-
Obligations.insert({Obligation::Key::forPotentialMember(key),
442-
{"", Expectation::Kind::PotentialMember,
443-
isCascadingUse ? Expectation::Scope::Cascading
444-
: Expectation::Scope::Private}});
445-
}
446-
break;
447-
case NodeKind::UsedMember: {
448-
auto demContext = copyQualifiedTypeName(Ctx, reference.subject);
449-
auto name = reference.name.userFacingName();
450-
auto key = Ctx.AllocateCopy((demContext + "." + name).str());
451-
Obligations.insert({Obligation::Key::forMember(key),
452-
{key, Expectation::Kind::Member,
453-
isCascadingUse ? Expectation::Scope::Cascading
454-
: Expectation::Scope::Private}});
455-
}
456-
break;
457-
case NodeKind::Dynamic: {
458-
auto key = Ctx.AllocateCopy(reference.name.userFacingName());
459-
Obligations.insert({Obligation::Key::forDynamicMember(key),
460-
{"", Expectation::Kind::DynamicMember,
461-
isCascadingUse ? Expectation::Scope::Cascading
462-
: Expectation::Scope::Private}});
463-
}
464-
break;
465-
case NodeKind::TopLevel: {
466-
auto key = Ctx.AllocateCopy(reference.name.userFacingName());
467-
Obligations.insert({Obligation::Key::forProvides(key),
468-
{key, Expectation::Kind::Provides,
469-
Expectation::Scope::None}});
470-
}
471-
break;
472-
}
473-
});
390+
Ctx.evaluator.enumerateReferencesInFile(SF, [&](const auto &reference) {
391+
using NodeKind = evaluator::DependencyCollector::Reference::Kind;
392+
switch (reference.kind) {
393+
case NodeKind::Empty:
394+
case NodeKind::Tombstone:
395+
llvm_unreachable("Cannot enumerate dead dependency!");
396+
397+
case NodeKind::PotentialMember: {
398+
auto key = copyQualifiedTypeName(Ctx, reference.subject);
399+
Obligations.insert({Obligation::Key::forPotentialMember(key),
400+
{"", Expectation::Kind::PotentialMember}});
401+
} break;
402+
case NodeKind::UsedMember: {
403+
auto demContext = copyQualifiedTypeName(Ctx, reference.subject);
404+
auto name = reference.name.userFacingName();
405+
auto key = Ctx.AllocateCopy((demContext + "." + name).str());
406+
Obligations.insert(
407+
{Obligation::Key::forMember(key), {key, Expectation::Kind::Member}});
408+
} break;
409+
case NodeKind::Dynamic: {
410+
auto key = Ctx.AllocateCopy(reference.name.userFacingName());
411+
Obligations.insert({Obligation::Key::forDynamicMember(key),
412+
{"", Expectation::Kind::DynamicMember}});
413+
} break;
414+
case NodeKind::TopLevel: {
415+
auto key = Ctx.AllocateCopy(reference.name.userFacingName());
416+
Obligations.insert({Obligation::Key::forProvides(key),
417+
{key, Expectation::Kind::Provides}});
418+
} break;
419+
}
420+
});
474421

475422
return false;
476423
}
@@ -480,7 +427,6 @@ bool DependencyVerifier::verifyObligations(
480427
ObligationMap &OM, llvm::StringMap<Expectation> &NegativeExpectations) {
481428
auto &diags = SF->getASTContext().Diags;
482429
for (auto &expectation : ExpectedDependencies) {
483-
const bool wantsCascade = expectation.isCascading();
484430
if (expectation.Info.Kind == Expectation::Kind::Negative) {
485431
// We'll verify negative expectations separately.
486432
NegativeExpectations.insert({expectation.MessageRange, expectation});
@@ -490,29 +436,14 @@ bool DependencyVerifier::verifyObligations(
490436
matchExpectationOrFail(
491437
OM, expectation,
492438
[&](Obligation &O) {
493-
const auto haveCascade = O.getCascades();
494439
switch (expectation.Info.Kind) {
495440
case Expectation::Kind::Negative:
496441
llvm_unreachable("Should have been handled above!");
497442
case Expectation::Kind::Member:
498-
if (haveCascade != wantsCascade) {
499-
diagnose(diags, expectation.MessageRange.begin(),
500-
diag::dependency_cascading_mismatch, wantsCascade,
501-
haveCascade);
502-
return O.fail();
503-
} else {
504-
return O.fullfill();
505-
}
443+
return O.fullfill();
506444
case Expectation::Kind::PotentialMember:
507445
assert(O.getName().empty());
508-
if (haveCascade != wantsCascade) {
509-
diagnose(diags, expectation.MessageRange.begin(),
510-
diag::potential_dependency_cascading_mismatch,
511-
wantsCascade, haveCascade);
512-
return O.fail();
513-
} else {
514-
return O.fullfill();
515-
}
446+
return O.fullfill();
516447
case Expectation::Kind::Provides:
517448
case Expectation::Kind::DynamicMember:
518449
return O.fullfill();
@@ -564,13 +495,14 @@ bool DependencyVerifier::diagnoseUnfulfilledObligations(
564495
case Expectation::Kind::Member:
565496
case Expectation::Kind::DynamicMember:
566497
case Expectation::Kind::PotentialMember:
567-
diags.diagnose(Loc, diag::unexpected_dependency, p.describeCascade(),
568-
static_cast<uint8_t>(p.getKind()), key)
569-
.fixItInsert(Loc, p.renderAsFixit(Ctx));
498+
diags
499+
.diagnose(Loc, diag::unexpected_dependency,
500+
static_cast<uint8_t>(p.getKind()), key)
501+
.fixItInsert(Loc, p.renderAsFixit(Ctx));
570502
break;
571503
case Expectation::Kind::Provides:
572504
diags.diagnose(Loc, diag::unexpected_provided_entity, p.getName())
573-
.fixItInsert(Loc, p.renderAsFixit(Ctx));
505+
.fixItInsert(Loc, p.renderAsFixit(Ctx));
574506
break;
575507
}
576508
});

0 commit comments

Comments
 (0)