Skip to content

Conversation

tshortli
Copy link
Contributor

@tshortli tshortli commented Sep 8, 2025

Enable the language feature flag for SE-0444. This instructs the compiler to be stricter about requiring import declarations in order to access member declarations.

Also, replace #if swift(>=6.0) guards with #if compiler(>=6.0). All uses of internal import were previously guarded with #if swift(>=6.0), presumably to handle differences in compiler support for internal import. However, #if swift(>=) is not the correct directive to use for this purpose, as it primarily tests the language mode that is enabled. These existing conditionals never evaluated true when building this package since it is not configured to build with Swift 6 enabled. Instead, use #if compiler(>=6.0) which correctly predicates the imports on only the compiler version.

@tshortli tshortli force-pushed the member-import-visibility branch 2 times, most recently from 28c0940 to 24c3dbd Compare September 8, 2025 17:15
#else
@testable import struct ArgumentParser.CompletionShell
#endif
@testable import ArgumentParser
Copy link
Contributor

Choose a reason for hiding this comment

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

Why does this file need @testable

Copy link
Contributor Author

Choose a reason for hiding this comment

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

/Users/allan/Downloads/swift-argument-parser/Tests/ArgumentParserExampleTests/MathExampleTests.swift:252:23: error: 'format' is inaccessible due to 'internal' protection level
      expected: shell.format(completions: [
                      ^~~~~~
ArgumentParser.CompletionShell.format:2:15: note: 'format(completions:)' declared here
internal func format(completions: [String]) -> String}
              ^
/Users/allan/Downloads/swift-argument-parser/Tests/ArgumentParserExampleTests/MathExampleTests.swift:258:25: error: 'shellEnvironmentVariableName' is inaccessible due to 'internal' protection level
        CompletionShell.shellEnvironmentVariableName: shell.rawValue
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
ArgumentParser.CompletionShell.shellEnvironmentVariableName:2:21: note: 'shellEnvironmentVariableName' declared here
internal static let shellEnvironmentVariableName: String}
                    ^
/Users/allan/Downloads/swift-argument-parser/Tests/ArgumentParserExampleTests/MathExampleTests.swift:264:23: error: 'format' is inaccessible due to 'internal' protection level
      expected: shell.format(completions: [
                      ^~~~~~
ArgumentParser.CompletionShell.format:2:15: note: 'format(completions:)' declared here
internal func format(completions: [String]) -> String}
              ^
/Users/allan/Downloads/swift-argument-parser/Tests/ArgumentParserExampleTests/MathExampleTests.swift:270:25: error: 'shellEnvironmentVariableName' is inaccessible due to 'internal' protection level
        CompletionShell.shellEnvironmentVariableName: shell.rawValue
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
ArgumentParser.CompletionShell.shellEnvironmentVariableName:2:21: note: 'shellEnvironmentVariableName' declared here
internal static let shellEnvironmentVariableName: String}
                    ^
/Users/allan/Downloads/swift-argument-parser/Tests/ArgumentParserExampleTests/MathExampleTests.swift:276:23: error: 'format' is inaccessible due to 'internal' protection level
      expected: shell.format(completions: [
                      ^~~~~~
ArgumentParser.CompletionShell.format:2:15: note: 'format(completions:)' declared here
internal func format(completions: [String]) -> String}
              ^
/Users/allan/Downloads/swift-argument-parser/Tests/ArgumentParserExampleTests/MathExampleTests.swift:281:25: error: 'shellEnvironmentVariableName' is inaccessible due to 'internal' protection level
        CompletionShell.shellEnvironmentVariableName: shell.rawValue
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
ArgumentParser.CompletionShell.shellEnvironmentVariableName:2:21: note: 'shellEnvironmentVariableName' declared here
internal static let shellEnvironmentVariableName: String}
                    ^

#if swift(>=6.0)
#if compiler(>=6.0)
internal import ArgumentParserToolInfo
internal import Foundation
Copy link
Contributor

Choose a reason for hiding this comment

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

im curious what is using foundation from this file

Copy link
Contributor Author

Choose a reason for hiding this comment

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

/Users/allan/Downloads/swift-argument-parser/Sources/ArgumentParser/Completions/CompletionsGenerator.swift:160:9: error: instance method 'replacingOccurrences(of:with:options:range:)' is not available due to missing import of defining module 'Foundation'
      : replacingOccurrences(of: "'", with: "'\\''")
        ^
/Users/allan/Downloads/swift-argument-parser/Sources/ArgumentParser/Completions/CompletionsGenerator.swift:14:1: note: add import of module 'Foundation'
//internal import Foundation
^
/Users/allan/Downloads/swift-argument-parser/Sources/ArgumentParser/Completions/CompletionsGenerator.swift:165:5: error: instance method 'replacingOccurrences(of:with:options:range:)' is not available due to missing import of defining module 'Foundation'
    replacingOccurrences(of: "-", with: "_")
    ^
/Users/allan/Downloads/swift-argument-parser/Sources/ArgumentParser/Completions/CompletionsGenerator.swift:14:1: note: add import of module 'Foundation'
//internal import Foundation
^

@rauhul
Copy link
Contributor

rauhul commented Sep 8, 2025

@swift-ci test

Enable the language feature flag for SE-0444. This instructs the compiler to
be stricter about requiring import declarations in order to access member
declarations.
All uses of `internal import` were previously garuded with `#if swift(>=6.0)`,
presumably to handle differences in compiler support for `internal import`.
However, `#if swift(>=)` is not the correct directive to use for this purpose,
as it primarily tests the language mode that is enabled. These existing
conditionals never evaluated true when building this package since it is not
configured to build with Swift 6 enabled. Instead, use `#if compiler(>=6.0)`
which correctly predicates the imports on only the compiler version.
@tshortli tshortli force-pushed the member-import-visibility branch from 24c3dbd to 33ae082 Compare September 8, 2025 18:02
@rauhul
Copy link
Contributor

rauhul commented Sep 8, 2025

@swift-ci test

@rauhul rauhul enabled auto-merge (squash) September 8, 2025 18:03
@rauhul rauhul merged commit 4f680a7 into apple:main Sep 8, 2025
29 checks passed
@tshortli tshortli deleted the member-import-visibility branch September 8, 2025 18:06
@rgoldberg
Copy link
Contributor

@tshortli Quick questions: the SE-0444 doc indicates that MemberImportVisibility was implemented in Swift 6.1; will enabling it affect a project when it is being compiled by an older version of the Swift compiler (6.0-)? I assume not.

If 6.0- compilers won't be affected, would enabling this flag for a project that can be built by Swift 6.0- compilers allow for certain code to compile on 6.1+, but not compile on 6.0- due to clashing implicitly imported symbols?

If that's the case, why even enable it now for Swift Argument Parser (SAP)? Would it make sense to enable it only after SAP requires 6.1+ for compilation?

Thanks for any insight you can provide. Sorry if I'm mistaken, but I've only enabled an experimental (though not upcoming) feature when all Swift compilers that should be able to compile my code support the feature.

@tshortli
Copy link
Contributor Author

Quick questions: the SE-0444 doc indicates that MemberImportVisibility was implemented in Swift 6.1; will enabling it affect a project when it is being compiled by an older version of the Swift compiler (6.0-)? I assume not.

If the compiler does not recognize the feature identifier specified with -enable-upcoming-feature and -enable-experimental-feature then it ignores flag entirely. Building ArgumentParser with -enable-upcoming-feature MemberImportVisibility when building with an older toolchain won't have any effect.

If 6.0- compilers won't be affected, would enabling this flag for a project that can be built by Swift 6.0- compilers allow for certain code to compile on 6.1+, but not compile on 6.0- due to clashing implicitly imported symbols?

The source code will still be compatible with the older toolchains, because MemberImportVisibility simply requires that additional explicit imports be added to source code where previously those imports were only transitive. There shouldn't be any new ambiguities introduced by new imports just for older toolchains since those ambiguities would also be present with newer toolchains and therefore prevent the imports from being added in the first place.

If that's the case, why even enable it now for Swift Argument Parser (SAP)? Would it make sense to enable it only after SAP requires 6.1+ for compilation?

No, I don't think it makes sense. Practically speaking that requirement would be very far away, and in the meantime we won't get the benefit in build environments that use newer compilers.

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