Skip to content

[DiagnosticVerifier] Make DiagnosticVerifier a DiagnosticConsumer #28313

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 1 commit into from
Mar 31, 2020

Conversation

owenv
Copy link
Contributor

@owenv owenv commented Nov 17, 2019

Previously, DiagnosticVerifier hooked emission of llvm::SMDiagnostic to capture diagnostics for verification. This change makes DiagnosticVerifier a subclass of DiagnosticConsumer instead. This means that instead of checking expected diagnostics against the llvm::SMDiagnostics emitted by PrintedDiagnosticConsumer, it checks them directly against the DiagnosticInfos it receives from the DiagnosticEngine.

This is desirable for a couple reasons:

  • It allows us to verify information about diagnostics that's lost when a DiagnosticInfo is translated to an SMDiagnostic. This will allow adding verifier support for educational notes in a follow-up
  • It begins to reduce dependencies on SMDiagnostic. The current diagnostic pipeline looks like Diagnostic -> DiagnosticInfo -> SMDiagnostic -> Text Output when using the PrintingDiagnosticConsumer. Eventually I'd like to reduce that to just Diagnostic -> DiagnosticInfo -> Text Output. In addition to simplifying the diagnostics subsystem, this will make improving multi-byte character support in diagnostics much easier, and enable smaller QoL enhancements like https://bugs.swift.org/browse/SR-6024. (Edit: This will also allow running tests with -enable-experimental-diagnostic-formatting)

The downside of making this change now is that we lose test coverage of PrintingDiagnosticConsumer itself. Under the old system every test which used the verifier relied on it.

@owenv
Copy link
Contributor Author

owenv commented Nov 17, 2019

@swift-ci please test

@owenv owenv requested review from DougGregor and beccadax November 18, 2019 17:38
@owenv owenv force-pushed the verifier-consumer branch from 555b047 to 2bdaf1d Compare December 4, 2019 02:06
@owenv
Copy link
Contributor Author

owenv commented Dec 4, 2019

Was re-reviewing this and found a few additional cleanup opportunities

@owenv
Copy link
Contributor Author

owenv commented Dec 10, 2019

@swift-ci please test

@owenv owenv force-pushed the verifier-consumer branch 2 times, most recently from 5f2cefa to 8d5a866 Compare December 10, 2019 21:46
@owenv
Copy link
Contributor Author

owenv commented Dec 12, 2019

@brentdax do you mind taking a look at this?

@beccadax
Copy link
Contributor

@owenv I accidentally ended up commenting on this PR in #28964—sorry about that!

@owenv owenv force-pushed the verifier-consumer branch from 8d5a866 to b38b0b1 Compare January 21, 2020 00:15
@owenv
Copy link
Contributor Author

owenv commented Jan 21, 2020

@brentdax No problem! I'll respond to your comments from the other PR here:

Do we know why DiagnosticVerifier wasn't a DiagnosticConsumer before? I'm worried that this change might make the verifier not, for instance, compose with other diagnostic consumers the way it used to. Do -serialize-diagnostics-path and -emit-fixits-path in combination with -verify work the same way they used to? I'm also worried about whether other diagnostic-related features like -warnings-as-errors, -debug-diagnostic-names, or even -color-diagnostics will work the same way they used to. How do these things interact with this change?

I'm not sure why it wasn't a DiagnosticConsumer before. The one downside I do know of is I had to add the suppressOutput hack to PrintingDiagnosticConsumer, but I may be missing historical context somewhere.

The old verifier hooked the output of PrintingDiagnosticConsumer, and this one is independent of all the other consumers. As a result, -serialize-diagnostics-path and -emit-fixits-path continue to work because SerializedDiagnosticConsumer is unchanged. -warnings-as-errors overrides the diagnostic kind in DiagnosticsEngine before diagnostics reach consumers, so its behavior is also unchanged. -debug-diagnostic-names continues to work because the verifier looks for a substring instead of an exact match (and the old verifier already received the debug strings if the flag was passed).

I hadn't thought to test the color flags, it turns out the current verifier doesn't respect them. I've updated this PR to begin taking them into account.

Separately: Why is DiagnosticVerifier's full definition provided in this include/swift header? The other diagnostic consumers only declare a function to create an instance and hide the rest of the implementation, and the old -verify implementation also only exposed a few functions to set it up. Is there an architectural difference that forces DiagnosticVerifier to be different? If not, moving a lot of these declarations into the .cpp file, or at least into a separate header, might help us keep compile times down.

No particular reason, I looked over the code again and was able to move a decent number out of the header. CapturedDiagnosticInfo is still there because the vector can't have an incomplete type, and the three remaining private methods all need to be able to call DiagnosticConsumer::getRawLoc.

@owenv
Copy link
Contributor Author

owenv commented Jan 21, 2020

Is this comment still accurate with the refactoring you've done? I don't think the final processing actually happens in this if anymore.

Yeah, this comment was in the wrong place. I've moved it

@owenv owenv force-pushed the verifier-consumer branch from 6a7843d to c6ea47c Compare February 7, 2020 00:20
@owenv
Copy link
Contributor Author

owenv commented Feb 7, 2020

@swift-ci please smoke test

@owenv
Copy link
Contributor Author

owenv commented Feb 7, 2020

@brentdax I was able to extend the test coverage a bit to cover some of the edge cases you mentioned. Do you mind taking another look?

Also, since performance is relevant here, I ran the test suite locally with and without this change applied, and got 415s before and 430s after

@owenv
Copy link
Contributor Author

owenv commented Feb 7, 2020

@swift-ci please smoke test macOS

@owenv owenv force-pushed the verifier-consumer branch from c6ea47c to 317d944 Compare February 18, 2020 03:20
@owenv
Copy link
Contributor Author

owenv commented Feb 18, 2020

@swift-ci please smoke test

@owenv
Copy link
Contributor Author

owenv commented Feb 19, 2020

@brentdax bump

@owenv
Copy link
Contributor Author

owenv commented Feb 29, 2020

@swift-ci please test

@owenv
Copy link
Contributor Author

owenv commented Feb 29, 2020

@swift-ci please test Windows platform

@owenv owenv force-pushed the verifier-consumer branch from d464609 to 1738128 Compare March 4, 2020 23:18
@owenv
Copy link
Contributor Author

owenv commented Mar 4, 2020

I'm not quite sure how to resolve these conflicts with the new dependency verifier. @CodaFi does DependencyVerifier rely on hooking the emission of SMDiagnostics? I've been trying to move away from that approach in this PR because it blocks testing aspects of Swift diagnostics that can't be represented by SMDiagnostic, and couples the verifier to implementation details of PrintingDiagnosticConsumer.

@owenv
Copy link
Contributor Author

owenv commented Mar 6, 2020

@swift-ci please smoke test

@owenv owenv force-pushed the verifier-consumer branch from f29d0d9 to 658cca7 Compare March 10, 2020 16:43
@owenv
Copy link
Contributor Author

owenv commented Mar 10, 2020

@brentdax there's no rush, but do you mind taking another look at this when you have a chance? I think it's getting closer to being a viable replacement for the existing verifier

@owenv owenv force-pushed the verifier-consumer branch from 658cca7 to 88d3a6d Compare March 12, 2020 16:59
@owenv
Copy link
Contributor Author

owenv commented Mar 12, 2020

@swift-ci please smoke test

@owenv owenv force-pushed the verifier-consumer branch 2 times, most recently from 138d902 to 01a5c39 Compare March 20, 2020 19:24
@owenv
Copy link
Contributor Author

owenv commented Mar 20, 2020

@swift-ci test

@owenv owenv force-pushed the verifier-consumer branch from 01a5c39 to dfd9158 Compare March 23, 2020 00:11
@owenv
Copy link
Contributor Author

owenv commented Mar 23, 2020

@swift-ci test

// The verifier must be setup after CompilerInstance::setup is called above to
// ensure the input buffer IDs have been added.
std::unique_ptr<DiagnosticVerifier> verifier;
if (diagOpts.VerifyMode != DiagnosticOptions::NoVerify) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems like a really tricky initialization condition - maybe we should move the verifier instance onto CompilerInstance and set it up in the right place then.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea, moving it onto CompilerInstance seems to work well

// If we're in -verify mode, temporarily ignore errors. If verification
// failed, we'll still report an error correctly when finishDiagProcessing
// runs.
HadError = false;
Copy link
Contributor

Choose a reason for hiding this comment

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

Is universally resetting the error code here a good idea? Granted, it's probably not a good idea for the verifier to have been doing this in the first place, but I imagine we've grown quite a few tests that rely on this behavior.

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 moved this logic into finishDiagProcessing instead so we override the error code at the last possible moment, which I think makes this logic easier to understand.

addError(expected.MessageRange.begin(), "incorrect message found", fixIt);
} else if (I->getColumnNo() + 1 != (int)*expected.ColumnNo) {
} else if (I->Column != *expected.ColumnNo) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Were we off-by one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is just a consequence of operating on DiagnosticInfo instead of SMDiagnostic. I don't know why their column indexing is inconsistent, but I'm hesitant to change the behavior as part of this PR

Copy link
Contributor

@CodaFi CodaFi left a comment

Choose a reason for hiding this comment

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

A raft of stylistic points. I really appreciate you trying to improve this long-neglected critical component.

…bclass

Update DiagnosticVerifier to respect color flags

Improve DiagnosticVerifier test coverage

verifier updates to support new llvm stable branch
@owenv owenv force-pushed the verifier-consumer branch from dfd9158 to 465bab0 Compare March 28, 2020 19:40
@owenv
Copy link
Contributor Author

owenv commented Mar 28, 2020

@CodaFi thanks for all the feedback, this is really helpful! I believe I've addressed your initial points.

Copy link
Contributor

@CodaFi CodaFi left a comment

Choose a reason for hiding this comment

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

Nice and tidy! Let's get this merged.

@CodaFi
Copy link
Contributor

CodaFi commented Mar 30, 2020

@swift-ci test

@owenv
Copy link
Contributor Author

owenv commented Mar 30, 2020

@swift-ci please test Windows platform

@CodaFi
Copy link
Contributor

CodaFi commented Mar 31, 2020

⛵️

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.

3 participants