Skip to content

Keep associatedtypes sorted to the top of protocol declarations - #2667

Closed
calda with Copilot wants to merge 1 commit into
developfrom
copilot/update-organize-declarations-behavior
Closed

Keep associatedtypes sorted to the top of protocol declarations#2667
calda with Copilot wants to merge 1 commit into
developfrom
copilot/update-organize-declarations-behavior

Conversation

Copilot AI commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

organizeDeclarations can reorder protocol members such that init ends up above associatedtype declarations with defaults. This can cause the compiler to fail to infer default associated types for conforming types:

// Before organizeDeclarations (compiles)
public protocol Plugin {
    associatedtype Dependencies = Void
    associatedtype Context = Void
    init?(dependencies: Dependencies, context: Context)
}

// After organizeDeclarations with --type-order instanceLifecycle,nestedType,...
// (may fail to compile — compiler can't infer Dependencies/Context defaults)
public protocol Plugin {
    init?(dependencies: Dependencies, context: Context)
    associatedtype Dependencies = Void
    associatedtype Context = Void
}

Changes:

  • Sources/Rules/OrganizeDeclarations.swift: After sorting, protocol bodies now force all associatedtype declarations to the top regardless of --type-order config. Mirrors the existing struct memberwise-init ordering preservation pattern.
  • Tests/Rules/OrganizeDeclarationsTests.swift: Two tests covering custom and default --type-order configurations.
  • Tests/Fixtures/ProtocolAssociatedTypeEdgeCase.swift: Sample file demonstrating the edge case.

In protocol declarations, associatedtype declarations must always appear
at the top of the body regardless of the configured --type-order. The
compiler may fail to infer default associated types for conforming types
if init or other declarations appear above them.

Co-authored-by: calda <1811727+calda@users.noreply.github.com>
@codecov

codecov Bot commented Aug 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.45%. Comparing base (960a338) to head (d0dc8fc).

Additional details and impacted files
@@           Coverage Diff            @@
##           develop    #2667   +/-   ##
========================================
  Coverage    95.45%   95.45%           
========================================
  Files          178      178           
  Lines        27226    27234    +8     
========================================
+ Hits         25989    25997    +8     
  Misses        1237     1237           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@calda

calda commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

@copilot please share sample Swift code where this declaration ordering change causes the code to no longer compile

Copilot AI commented Aug 22, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please share sample Swift code where this declaration ordering change causes the code to no longer compile

Here's a minimal example that demonstrates the issue:

// This compiles — associatedtypes with defaults are above init
public protocol Plugin {
    associatedtype Dependencies = Void
    associatedtype Context = Void
    init?(dependencies: Dependencies, context: Context)
}

// Conforming type relies on default inference
struct MyPlugin: Plugin {
    init?(dependencies: Void, context: Void) {}
}

When organizeDeclarations reorders so that init (lifecycle) sorts above associatedtype (based on --type-order), it becomes:

public protocol Plugin {
    init?(dependencies: Dependencies, context: Context)
    associatedtype Dependencies = Void
    associatedtype Context = Void
}

However, I want to be transparent: after further investigation, I have not been able to reproduce a case where this reordering actually causes a compilation failure in modern Swift compilers (5.9+). The Swift compiler resolves associated type defaults regardless of declaration order within a protocol body. The ordering is a readability/convention concern (Apple's own API guidelines place associated types first), but it does not appear to be a correctness issue.

Given this, should I revise the PR to frame this as a style/convention fix (keeping associatedtypes at the top matches Swift API Design Guidelines) rather than a compilation fix? Or would you prefer to close this PR?

@calda

calda commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

@copilot, ok, rather than trying to reproduce this issue, refr

@calda calda closed this Aug 22, 2026
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