`unused_import: require_explicit_imports: true` requires explicit importing of "hidden" modules whose names begin with an underscore
Nobody has claimed this yet.
- Dominant language
- Swift
- Stars
- 19.7k
- Forks
- 2.3k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 11
Description
New Issue Checklist
- I've Updated SwiftLint to the latest version.
- I've searched for existing GitHub issues.
Bug Description
unused_import: require_explicit_imports: true requires explicit importing of "hidden" modules whose names begin with an underscore, e.g., _DarwinFoundation1, which seems to be available on Xcode 26 on macOS 26, but not on Xcode 16.4 on macOS 15.6.1.
I'm guessing that all modules whose names begin with an underscore are "hidden", and thus not guaranteed to be available in different toolchain versions.
Instead of requiring that they be imported, the rule should only require the lowest module whose name does not start with an underscore. e.g., if Darwin makes _DarwinFoundation1, _DarwinFoundation2, & _DarwinFoundation3 available, and no modules whose names don't start with an underscore are closer in the module tree than Darwin to the hidden modules, then require importing Darwin instead of those 3.
// This triggers a violation:
private import Darwin
func test() {
floor(123 / 1000)
}
Unfortunately, I just noticed that the problem exists for other modules whose names don't start with an underscore.
Besides ignoring all modules whose name begins with an underscore, you should also be able to configure leaf modules without specifying exactly what modules they can transitively provide. I should be able to just say, e.g., that Darwin is a leaf module; if a module is transitively provided by Darwin, regardless of its name, do not require that it be explicitly imported.
Mention the command or other SwiftLint integration method that caused the issue. Include stack traces or command output.
$ swiftlint analyze --strict --quiet --reporter relative-path --compiler-log-path /path/to/Xcode.log
Environment
- SwiftLint 0.61.0
- Xcode 26.0.1 (17A400)
- Installation Homebrew core
- Configuration file:
---
excluded:
- .build/
- .idea/
- .swiftpm/
opt_in_rules:
- all
analyzer_rules:
- all
disabled_rules:
- contrasted_opening_brace
- explicit_acl
- explicit_enum_raw_value
- explicit_self
- explicit_top_level_acl
- explicit_type_interface
- file_header
- no_extension_access_modifier
- no_grouping_extension
- no_magic_numbers
- prefixed_toplevel_constant
- sorted_enum_cases
- strict_fileprivate
- vertical_whitespace_between_cases
- void_function_in_ternary
attributes:
always_on_line_above: ['@MainActor', '@OptionGroup']
closure_body_length:
warning: 35
cyclomatic_complexity:
ignores_case_statements: true
warning: 11
deployment_target:
macOS_deployment_target: 10.15
macOSApplicationExtension_deployment_target: 10.15
iOS_deployment_target: 99
iOSApplicationExtension_deployment_target: 99
tvOS_deployment_target: 99
tvOSApplicationExtension_deployment_target: 99
watchOS_deployment_target: 99
watchOSApplicationExtension_deployment_target: 99
explicit_init:
include_bare_init: true
file_length:
ignore_comment_only_lines: true
file_name:
excluded: [Finder.swift, SpotlightInstalledApps.swift]
file_types_order:
order:
- main_type
- supporting_type
- extension
- preview_provider
- library_content_provider
function_body_length:
warning: 75
indentation_width:
indentation_width: 2
include_multiline_strings: false
line_length:
ignores_multiline_strings: true
multiline_arguments:
first_argument_location: next_line
non_optional_string_data_conversion:
include_variables: true
number_separator:
minimum_length: 6
opening_brace:
ignore_multiline_statement_conditions: true
operator_usage_whitespace:
skip_aligned_constants: false
prefer_key_path:
restrict_to_standard_functions: false
private_over_fileprivate:
validate_extensions: true
redundant_type_annotation:
consider_default_literal_types_redundant: true
trailing_comma:
mandatory_comma: true
trailing_whitespace:
ignores_comments: false
type_contents_order:
order:
- case
- associated_type
- type_alias
- subtype
- type_property
- instance_property
- ib_inspectable
- ib_outlet
- initializer
- deinitializer
- type_method
- view_life_cycle_method
- ib_action
- other_method
- subscript
unneeded_override:
affect_initializers: true
unused_import:
require_explicit_imports: true
Are you using nested configurations? No
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the unused_import behavior with the provided swiftlint analyze command, Xcode environment, and configuration. Trace the unused_import rule's module-resolution entry point and compare diagnostics for underscore-prefixed and transitively provided modules. Done means the expected import requirement is defined and covered for hidden modules and configurable leaf modules.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100