SwiftLint icon indicating copy to clipboard operation
SwiftLint copied to clipboard

False positive on duplicate_imports rule

Open aleksanderlorenc-lw opened this issue 7 months ago • 1 comments
trafficstars

New Issue Checklist

Bug Description

We have our project organized in a number of SPM Packages, in which we have types which overlap names from SwiftUI, e.g. Group.

To prefer the type coming from that package (instead of SwiftUI), we do:

import Package
import struct Package.Group
import SwiftUI

This however produces

warning: Duplicate Imports Violation: Imports should be unique (duplicate_imports)

Environment

  • SwiftLint version 0.59.1
  • Xcode version 16.2
  • Installation method used Standalone binary
  • Configuration file:
only_rules:
  - accessibility_trait_for_button
  - balanced_xctest_lifecycle
  - block_based_kvo
  - capture_variable
  - class_delegate_protocol
  - closing_brace
  - closure_parameter_position
  - closure_spacing
  - colon
  - comma
  - comma_inheritance
  - comment_spacing
  - compiler_protocol_init
  - computed_accessors_order
  - contains_over_filter_count
  - contains_over_filter_is_empty
  - contains_over_first_not_nil
  - contains_over_range_nil_comparison
  - convenience_type # Use caseless enum as a namespace
  - custom_rules
  - deployment_target
  - discarded_notification_center_observer
  - discouraged_assert
  - discouraged_direct_init
  - discouraged_object_literal
  - duplicate_conditions
  - duplicate_enum_cases
  - duplicate_imports
  - duplicated_key_in_dictionary_literal
  - dynamic_inline
  - empty_collection_literal
  - empty_count
  - empty_enum_arguments
  - empty_parentheses_with_trailing_closure
  - empty_string
  - empty_xctest_method
  - explicit_init
  - fallthrough
  - fatal_error_message
  - file_name_no_space
  - first_where
  - flatmap_over_map_reduce
  - for_where
  - generic_type_name
  - identical_operands
  - implicit_getter
  - inert_defer
  - invalid_swiftlint_command
  - is_disjoint
  - joined_default_parameter
  - large_tuple
  - last_where
  - leading_whitespace
  - legacy_cggeometry_functions
  - legacy_constant
  - legacy_constructor
  - legacy_hashing
  - legacy_multiple
  - legacy_nsgeometry_functions
  - legacy_random
  - literal_expression_end_indentation
  - local_doc_comment
  - lower_acl_than_parent
  - mark
  - modifier_order
  - multiline_function_chains
  - no_fallthrough_only
  - ns_number_init_as_function_reference
  - nsobject_prefer_isequal
  - operator_whitespace
  - optional_enum_case_matching
  - orphaned_doc_comment
  - overridden_super_call
  - prefer_self_in_static_references
  - prefer_zero_over_explicit_init
  - private_over_fileprivate
  - private_swiftui_state
  - private_unit_test
  - prohibited_interface_builder
  - prohibited_super_call
  - protocol_property_accessors_order
  - reduce_boolean
  - redundant_discardable_let
  - redundant_nil_coalescing
  - redundant_objc_attribute
  - redundant_optional_initialization
  - redundant_set_access_control
  - redundant_string_enum_value
  - redundant_type_annotation
  - redundant_void_return
  - return_arrow_whitespace
  - return_value_from_void_function
  - self_in_property_initialization 
  - shorthand_operator
  - shorthand_optional_binding
  - sorted_first_last
  - statement_position
  - static_operator
  - superfluous_disable_command
  - switch_case_alignment
  - toggle_bool
  - trailing_newline
  - trailing_semicolon
  - trailing_whitespace
  - typesafe_array_init
  - unavailable_condition
  - unavailable_function
  - unhandled_throwing_task  
  - unneeded_break_in_switch
  - unneeded_override
  - unneeded_parentheses_in_closure_argument
  - unneeded_synthesized_initializer
  - unused_capture_list
  - unused_closure_parameter
  - unused_control_flow_label
  - unused_declaration
  - unused_enumerated
  - unused_optional_binding
  - unused_setter_value
  - valid_ibinspectable
  - vertical_parameter_alignment
  - vertical_whitespace
  - void_function_in_ternary
  - void_return
  - weak_delegate
  - xct_specific_matcher
  - xctfail_message

large_tuple:
  warning: 5
  error: 5
deployment_target:
  iOS_deployment_target: 16
included:
  - ../App
  - ../Packages
excluded:
  - ../App/Generated
custom_rules:
  use_swiftgen_images:
    name: "SwiftGen Images"
    message: "Use swiftgen Images instead of UIImage(named:)"
    regex: "(UIImage\\(named:)"
    match_kinds: identifier
    severity: error
  api_use_model_generic: 
    name: "API model generic"
    regex: 'AppResponse<(.*?\b(]|>)?)>(.|\n){0,10}Model == \1'
    capture_group: 1
    match_kinds: typeidentifier
    message: "Use model generic eg. `AppResponse<Model>`"
    severity: error
  sf_safe_symbol:
    name: "Safe SFSymbol"
    message: "Use `SFSafeSymbols` via `systemSymbol` parameters for type safety."
    regex: "(Image\\(systemName:)|(NSImage\\(symbolName:)|(Label[^,]+?,\\s*systemImage:)|(UIApplicationShortcutIcon\\(systemImageName:)"
    severity: error

Are you using nested configurations? no

aleksanderlorenc-lw avatar Apr 23 '25 08:04 aleksanderlorenc-lw

This is actually the intended behavior. The assumption is that when you import Package, Package.Group is automatically visible as well.

That this resolves a name conflict isn't known to the rule as it cannot look into the modules to see all symbols. So in this case, probably the only way around that is to add a // swiftlint:disable command to the import struct ... line.

SimplyDanny avatar Jun 18 '25 09:06 SimplyDanny

This issue has been marked as stale because it has not seen any activity in the last 4 months. It is going to be closed soon if it stays inactive.

github-actions[bot] avatar Oct 20 '25 12:10 github-actions[bot]