Skip to content

Commit 767597d

Browse files
committed
Track previous diagnostic behavior
Switch from a fatal-state machine to a previous-behavior-state machine, which is more flexible in the presence of suppressible warnings.
1 parent dcb1924 commit 767597d

File tree

2 files changed

+23
-26
lines changed

2 files changed

+23
-26
lines changed

include/swift/AST/DiagnosticEngine.h

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -398,18 +398,14 @@ namespace swift {
398398
/// fatal error
399399
bool showDiagnosticsAfterFatalError = false;
400400

401+
/// \brief Whether a fatal error has occurred
402+
bool fatalErrorOccurred = false;
403+
401404
/// \brief Whether any error diagnostics have been emitted.
402405
bool anyErrorOccurred = false;
403406

404-
/// Fatal error tracking
405-
enum class FatalErrorState {
406-
None,
407-
JustEmitted,
408-
Fatal
409-
};
410-
411-
/// Sticky flag set to \c true when a fatal error is emitted.
412-
FatalErrorState fatalState = FatalErrorState::None;
407+
/// \brief Track the previous emitted Behavior, useful for notes
408+
Behavior previousBehavior = Behavior::Unspecified;
413409

414410
public:
415411
DiagnosticState() {}
@@ -418,17 +414,15 @@ namespace swift {
418414
Behavior getBehavior(const Diagnostic &);
419415

420416
bool hadAnyError() const { return anyErrorOccurred; }
421-
bool hasFatalErrorOccurred() const {
422-
return fatalState != FatalErrorState::None;
423-
}
417+
bool hasFatalErrorOccurred() const { return fatalErrorOccurred; }
424418

425419
void setShowDiagnosticsAfterFatalError(bool val = true) {
426420
showDiagnosticsAfterFatalError = val;
427421
}
428422

429423
void resetHadAnyError() {
430424
anyErrorOccurred = false;
431-
fatalState = FatalErrorState::None;
425+
fatalErrorOccurred = false;
432426
}
433427

434428
private:

lib/AST/DiagnosticEngine.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -452,30 +452,33 @@ static void formatDiagnosticText(StringRef InText,
452452
DiagnosticState::Behavior DiagnosticState::getBehavior(const Diagnostic &diag) {
453453
auto set = [this](DiagnosticState::Behavior lvl) {
454454
if (lvl == Behavior::Fatal) {
455-
fatalState = FatalErrorState::JustEmitted;
455+
fatalErrorOccurred = true;
456456
anyErrorOccurred = true;
457457
} else if (lvl == Behavior::Err) {
458458
anyErrorOccurred = true;
459459
}
460+
461+
previousBehavior = lvl;
460462
return lvl;
461463
};
462464

463465
auto diagKind = StoredDiagnosticInfos[(unsigned)diag.getID()].Kind;
464466

465-
if (fatalState != FatalErrorState::None) {
466-
bool shouldIgnore = true;
467-
if (diagKind == DiagnosticKind::Note)
468-
shouldIgnore = (fatalState == FatalErrorState::Fatal);
469-
else
470-
fatalState = FatalErrorState::Fatal;
471-
472-
if (shouldIgnore && !showDiagnosticsAfterFatalError) {
467+
// Notes relating to ignored diagnostics should also be ignored
468+
if (previousBehavior == Behavior::Ignore && diagKind == DiagnosticKind::Note)
469+
return set(Behavior::Ignore);
470+
471+
// Suppress diagnostics when in a fatal state, except for follow-on notes
472+
// about the original fatal diag
473+
if (fatalErrorOccurred) {
474+
bool emitAnyways = showDiagnosticsAfterFatalError ||
475+
(diagKind == DiagnosticKind::Note &&
476+
previousBehavior != Behavior::Ignore);
477+
if (!emitAnyways)
473478
return set(Behavior::Ignore);
474-
}
475-
}
476-
477-
if (isDiagnosticFatal(diag.getID()))
479+
} else if (isDiagnosticFatal(diag.getID())) {
478480
return set(Behavior::Fatal);
481+
}
479482

480483
// Re-map as appropriate
481484
switch (diagKind) {

0 commit comments

Comments
 (0)