Skip to content

Conversation

@taka-2120
Copy link

Resolves #86059

What I did

  • Exclude declarations on searching the usage
  • Add a test case

switch self {
case .name(let name):
if let identifier = token.identifier, identifier.name == name {
// Skip if this is a declaration
Copy link
Contributor

Choose a reason for hiding this comment

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

hi @taka-2120 – thanks for taking a look into fixing this issue. i'm not personally familiar with the relevant code here, but i do find it a little unexpected that the change to resolve the issue would be located here. i would have expected something in MiscDiagnostics to have to change since i thought that was where the warnings were coming from. could you help me better understand what this is effectively doing please?

Copy link
Author

Choose a reason for hiding this comment

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

Hi @jamieQ, thank you for reviewing.

As you noted, the warning we're coming from MiscDiagnostics, and the code I changed indirectly called from MiscDiagnostics.

search(syntax:, configuredRegions:) is called in inactiveCodeContainsReference (swift_ASTGen_inactiveCodeContainsReference). swift_ASTGen_inactiveCodeContainsReference called in VarDeclUsageChecker in MiscDiagnostics.

The search method is used for checking active references of the .name .
However, the problem was that compiler mistakingly recognize the definitions in #if true are used in the definitions in #else .
I implemented the code ignoring definitions for that reason.

Copy link
Contributor

Choose a reason for hiding this comment

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

@DougGregor it looks to me like the change here #76327 is responsible for the difference in diagnostic suppression starting in 6.1. i think that was a behavioral change at the time, at least for some diagnostics like the ones mentioned here and within the linked issue.

setting aside the exact implementation details, do you think adjusting the handling such that the check for references within inactive regions excludes new declarations with the same name (which i think is what's going on here) makes sense?

@grynspan
Copy link
Contributor

grynspan commented Jan 3, 2026

Can you give a concrete example of a problem this PR solves?

@taka-2120
Copy link
Author

Can you give a concrete example of a problem this PR solves?

@grynspan
Thank you for commenting. Here is an example of this problem.

Even when values defined in a #if are never used, no no_usage warnings are emitted if the same definitions also exist in an inactive #else branch.

func g() {
    #if true
    var x = 0           // no warning – unexpected
    weak var y: F?      // no warning – unexpected
    let z = 0           // no warning – unexpected
    #else
    var x = 0           // no warning – expected
    weak var y: F?      // no warning – expected
    let z = 0           // no warning – expected
    #endif
}

However, if the definitions in the #else branch are removed, no_usage warnings are emitted as expected.

func g() {
    #if true
    var x = 0           // warning – expected
    weak var y: F?      // warning – expected
    let z = 0           // warning – expected
    #endif
}

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.

[6.1 regression]: #if directives may suppress some warning emissions

3 participants