Skip to content

Suppress certain warnings in inactive #if regions without relying on IfConfigDecl #76327

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

Conversation

DougGregor
Copy link
Member

For a few categories of warnings, we currently look through inactive code (represented by IfConfigDecl) to try to determine whether there are other configurations of code that might not have the warning. If we find evidence of that, we suppress the warning. This includes, e.g.,

  • Warnings about variables that are set but never used
  • Warnings about mutable variables that are never mutated
  • Warnings about do..catch blocks with no "try" or "throw" inside them

For example, we don't warn about the lack of try/throw in this code:

do {
  #if DEBUG
  try foo()
  #endif
} catch {
  // ...
}

even if DEBUG is not set.

Reimplement this suppression mechanism in terms of the pure syntax tree with SwiftIfConfig deciding which regions are inactive. This eliminates a dependency on having the inactive clauses represented in an IfConfigDecl as well as expanding the suppression to "unparsed" code:

do {
  #if compiler(>=7.0)
  try foo()
  #endif
} catch {
  // ...
}

Rather than potentially computing ConfiguredRegions multiple times in
ASTGen and other queries, cache the result in the ExportedSourceFile.

This is temporary; we should bring up a Swift equivalent to the
request-evaluator (or bridge to the C++ one) to manage state like
this.
Rather than walking into the inactive regions of IfConfigDecls looking for
references to a declaration before we diagnose it, go to the syntax
tree and look through inactive *and unparsed* regions for identifier
tokens that match. If we find one, suppress the diagnostic.

This reduces our dependency on IfConfigDecl in the AST, and also makes
the same suppression work with code in unparsed regions that had no
representation in IfConfigDecl.
In the warning about having no try/throw within the body of a do..catch,
replace the walk of the inactive clauses of IfConfigDecl with a syntactic
check of inactive and unparsed regions to look for 'try' and 'throw'
keywords.

This both eliminates a dependency on IfConfigDecl and expands the
usefulness of this warning suppression to unparsed code.
@DougGregor
Copy link
Member Author

@swift-ci please smoke test

@DougGregor
Copy link
Member Author

@swift-ci please smoke test

Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

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

Only looked at the swift-syntax parts.

/// Search in inactive/unparsed code to look for evidence that something that
/// looks unused is actually used in some configurations.
private enum InactiveCodeChecker {
case name(String)
Copy link
Member

Choose a reason for hiding this comment

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

Should this take an Identifier already instead of a String?

Suggested change
case name(String)
case name(Identifier)

Copy link
Member Author

Choose a reason for hiding this comment

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

Identifier needs either SyntaxText in an arena, or a StaticString. I don't really have either here because I'm coming from a bridged StringRef.

return false
}

for token in syntax.tokens(viewMode: .sourceAccurate) {
Copy link
Member

Choose a reason for hiding this comment

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

Using a SyntaxVisitor instead of tokens(viewMode:) is currently faster because it has performance optimizations to reuse memory allocations, in case this is relevant here.

Copy link
Member Author

Choose a reason for hiding this comment

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

It's harder to stop the visitor from running when we find something, though, whereas I can easily "break" out of loop that walks over tokens.

@DougGregor DougGregor merged commit 42809af into swiftlang:main Sep 7, 2024
3 checks passed
@DougGregor DougGregor deleted the suppress-warnings-in-inactive-regions-without-ifconfigdecl branch September 7, 2024 17:16
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