Skip to content

[Batch Mode] Emit a non-specific error for all primaries lacking specific errors when a batch has errors. #16526

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
May 14, 2018

Conversation

davidungar
Copy link
Contributor

@davidungar davidungar commented May 11, 2018

rdar://problem/40167848 For primary in batch mode, emit a vague error diagnostic if the batch encountered an error and that primary has no other errors of its own.

@davidungar davidungar requested a review from jrose-apple May 11, 2018 04:01
@davidungar
Copy link
Contributor Author

@source-ci please smoke test

@davidungar
Copy link
Contributor Author

@jrose-apple Here is the first rough cut. Not sure if it should be just one or all serialized diagnostics files that receive the vague diagnostic.

@davidungar
Copy link
Contributor Author

@swift-ci please smoke test

@davidungar
Copy link
Contributor Author

"@source-ci"?! I must be tired.

@davidungar davidungar changed the title [Batch Mode] WIP emit fatal diag if all fatals suppressed [Batch Mode] Emit fatal diag if all fatals suppressed. May 11, 2018
@davidungar
Copy link
Contributor Author

@swift-ci please smoke test

@davidungar
Copy link
Contributor Author

@jrose-apple I think that this works, so the next step is probably for you to review. I would attach a radar number, but I'm not aware of one.

Copy link
Contributor

@jrose-apple jrose-apple left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for starting on this. I think you've solved a different problem, though (see comments).

By the way, "fatal error" already means something in our diagnostics system: an error where there's no point even emitting more diagnostics, because things are irrevocably broken. These are just normal errors we're talking about in this change.

@@ -235,6 +235,8 @@ WARNING(cannot_assign_value_to_conditional_compilation_flag,none,
ERROR(error_optimization_remark_pattern, none, "%0 in '%1'",
(StringRef, StringRef))

ERROR(error_compilation_failed,none, "compilation failed", ())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is too ambiguous. We need to say something about there being errors in other files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to a strawman: "some error occured in a file that was used in this one". Suggestions for a better message would be most welcome.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not necessarily true that the file was used in this one. This error comes up if any file in the batch resulted in an error in any file not in the batch.

@@ -101,6 +101,8 @@ class DiagnosticConsumer {

/// \returns true if an error occurred while finishing-up.
virtual bool finishProcessing() { return false; }

virtual bool hadOnlySuppressedFatalErrors() const { return false; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd really rather not change DiagnosticConsumer. Suppression is a feature of FileSpecificDiagnosticConsumer, not the diagnostics system in general.

}

bool FileSpecificDiagnosticConsumer::hadOnlySuppressedFatalErrors() const {
return WasAFatalDiagnosticSuppressed && !WasAFatalDiagnosticEmitted;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition isn't correct, either. We want to emit the generic error if any file did not receive any errors, not if all of them did not receive any errors.

@jrose-apple
Copy link
Contributor

Filed rdar://problem/40167848 for you.

@davidungar
Copy link
Contributor Author

davidungar commented May 11, 2018 via email

@davidungar davidungar changed the title [Batch Mode] Emit fatal diag if all fatals suppressed. [Batch Mode] Emit error diagnostic for a primary file that has errors only in non-primaries. May 11, 2018
@davidungar davidungar force-pushed the compilation-failed branch from fdea616 to b4dce82 Compare May 13, 2018 03:54
@davidungar
Copy link
Contributor Author

@swift-ci please smoke test

@davidungar
Copy link
Contributor Author

@jrose-apple To satisfy the other constraints, I had to add a parameter to finishProcessing, the SourceManager. That's because, in order to insert the non-specific error, the source manager must be passed down. It does work as desired, I think. Needs polishing, comments, etc.

@davidungar
Copy link
Contributor Author

And there’s a const cast, sigh.

@@ -235,6 +235,8 @@ WARNING(cannot_assign_value_to_conditional_compilation_flag,none,
ERROR(error_optimization_remark_pattern, none, "%0 in '%1'",
(StringRef, StringRef))

ERROR(error_some_error_occured_in_a_file_that_was_used_by_this_one,none, "some error occured in a file that was used by this one", ())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, this still isn't the correct description. All we know is that an error occurred somewhere—maybe by another file in this batch, maybe in a file used by this file, maybe in a file used by another file in the batch. That is, because dia files are per-input in batch mode, we need this error even if no diagnostics are suppressed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed (I think).

Optional<ConsumerSpecificInformation *>
ConsumerSpecificInfoForSubsequentNotes = None;

bool WasAnErrorSuppressed = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed, but I did had a flag hasAnErrorBeenConsumed.

std::pair<CharSourceRange, DiagnosticConsumer *>;
// The commented-out consts are there because the data does not change
// but the swap method gets called on this structure.
struct ConsumerSpecificInformation {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One consequence of putting the flag in with the mapping like this is that the same consumer might get multiple copies of the dummy error, one for each range (file) it's covering. We're not reusing consumers that way, so it doesn't matter, but I thought I'd bring it up and see what you thought.

(I was originally thinking it'd be a SmallPtrSet<DiagnosticConsumer *, N> that tracked all of the consumers that actually received non-note diagnostics. That would avoid the const_cast, but at the practical, run-time cost of an extra lookup.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the separation of concerns in your scheme; I never thought about reusing the consumers. I would rather put the flag in the consumer, and let a diagnostic consumer know if it had seen an error. But I got the impression that you disliked adding that functionality to the general consumer & I can see that. For now, I would prefer sticking with the current scheme.


private:
void addNonSpecificErrors(SourceManager &SM);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: this needs either a doc comment or a better name (or both).

DiagnosticInfo Info;
Info.ID = diagnostic.getID();
Info.Ranges = diagnostic.getRanges();
Info.FixIts = diagnostic.getFixIts();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We know there are no ranges or fix-its here, so it's probably better just to omit this.

// Ensure there was an error:
// RUN: %FileCheck -check-prefix=NO-COMPILATION-FAILED %s <%t.main.txt
// RUN: %FileCheck -check-prefix=NO-COMPILATION-FAILED %s <%t.empty.txt
// NO-COMPILATION-FAILED-NOT: compilation failed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You changed the text of the error, so this isn't up to date anymore. (A hazard of negative checks!)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Fixed.


func test(x: SomeType) {
nonexistant(); // create a fatal error here
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a regular error!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@@ -0,0 +1,26 @@
// To avoid redundant diagnostics showing up in Xcode, batch-mode must suppress diagnostics in
// non-primary files.
// But if the only errors are suppressed ones, a nonspecific error must be emitted
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned above, I think I was misleading about "suppression". This is something important even for errors that do get emitted, just for another file in the batch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the verbiage.

@davidungar
Copy link
Contributor Author

@swift-ci please smoke test

@davidungar davidungar changed the title [Batch Mode] Emit error diagnostic for a primary file that has errors only in non-primaries. [Batch Mode] Emit a non-specific error for all primaries lacking specific errors when a batch has errors. May 14, 2018
@davidungar
Copy link
Contributor Author

@swift-ci please clean smoke test linux platform

1 similar comment
@davidungar
Copy link
Contributor Author

@swift-ci please clean smoke test linux platform

@davidungar
Copy link
Contributor Author

@jrose-apple OK, I think I've made the needed fixes and pushed.

@davidungar
Copy link
Contributor Author

@swift-ci please smoke test linux platform

Copy link
Contributor

@jrose-apple jrose-apple left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I think this is the logic I was thinking of! Did you get a chance to try it in Xcode with a real error?

if (!info.hasAnErrorBeenEmitted && info.consumer) {
produceNonSpecificError(info.consumer, SM);
info.hasAnErrorBeenEmitted = true;
HasAnErrorBeenConsumed = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line should be unnecessary since HasAnErrorBeenConsumed is guarding this section.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I must be losing focus.

@@ -235,6 +235,8 @@ WARNING(cannot_assign_value_to_conditional_compilation_flag,none,
ERROR(error_optimization_remark_pattern, none, "%0 in '%1'",
(StringRef, StringRef))

ERROR(error_an_error_occurred,none, "an error occurred", ())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still too vague; imagine how it would look to a user. I still think my phrasing is reasonable, something like "compilation stopped due to errors in other files".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about "error(s) in other file(s) halted compilation"?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like the funny pluralization isn't buying us anything, and it also seems weird to me to use active tense for this. My mental model is that the compiler chose to stop compiling this file because of errors in that file. But maybe others don't share that view.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I liked the ambiguous pluralization because it was more accurate. Could be one, could be many errors. But in the interest of time, I can live with the plural. I'll passivate the message, too.

@@ -0,0 +1,20 @@
// Batch-mode has no good place to emit diagnostics that occur in non-primary files
// because then cannot be locatlized to a particular primary's serialized diagnostics file.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "locatlized" (and "then"). That's also not a great word because it makes me think of the internationalization localization. But the description is no longer accurate anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. I'm getting terser as the evening wears on.

//
// RUN: rm -f %t.*

// RUN: not %target-swift-frontend -typecheck -primary-file %s -serialize-diagnostics-path %t.main.dia -primary-file %S/../Inputs/empty.swift -serialize-diagnostics-path %t.empty.dia %S/Inputs/serialized-diagnostics-batch-mode-suppression-helper.swift 2> %t.stderr.txt
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is no longer testing non-primary errors…but it still should! We need both tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, now testing both.

@davidungar
Copy link
Contributor Author

@swift-ci please smoke test

@davidungar
Copy link
Contributor Author

@swift-ci please smoke test


// RUN: %FileCheck -check-prefix=NO-GENERAL-ERROR-OCCURRED %s <%t.main.txt
// RUN: %FileCheck -check-prefix=GENERAL-ERROR-OCCURRED %s <%t.empty.txt
// GENERAL-ERROR-OCCURRED: compilation stopped by errors in other files
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this to really be testing that the non-primary is causing the message, you'll have to not have an error in either primary.

diag::error_compilation_stopped_by_errors_in_other_files);

// Stolen from DiagnosticEngine::emitDiagnostic
DiagnosticInfo Info;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: You have two things named "Info" now. (That said, this function could get away with just taking a DiagnosticConsumer &.)

@davidungar davidungar merged commit 9d08b8c into swiftlang:master May 14, 2018
davidungar pushed a commit to davidungar/swift that referenced this pull request May 14, 2018
[Batch Mode] Emit a non-specific error for all primaries lacking specific errors when a batch has errors.
davidungar pushed a commit to davidungar/swift that referenced this pull request May 14, 2018
[Batch Mode] Emit a non-specific error for all primaries lacking specific errors when a batch has errors.
davidungar pushed a commit that referenced this pull request May 14, 2018
…rror-swift-4.2-4-30-2018-branch

[Batch mode] <rdar://40167848> Merge pull request #16526 from davidungar/compilation-failed
@davidungar davidungar deleted the compilation-failed branch June 14, 2019 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants