From f4c5cd9299374294164b477a951419d8208d0e1a Mon Sep 17 00:00:00 2001 From: Mx-Iris Date: Fri, 28 Aug 2026 11:14:29 +0800 Subject: [PATCH 1/2] fix(dump): separate conditional-conformance where-clause requirements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `ProtocolConformanceDumper.declaration` emitted every conditional requirement back to back, so a conformance carrying two or more conditions rendered as `where A: FirstProtocolA: SecondProtocol` — not valid Swift. Follow the separator contract the repository's other two requirement loops already have (`ProtocolDumper`'s inherited-protocol clause and `TargetGenericContext.dumpGenericRequirements`). Only the `dump` path was affected; `interface` renders the same clause through `SwiftDeclarationPrinter`, whose loop was already correct. The dump snapshot had frozen the malformed output since the dumper was written (d45a91b6, 2025-08-14); its corrected form is the regression test — it fails on the old dumper and passes on the new one. --- Sources/SwiftDump/Dumper/ProtocolConformanceDumper.swift | 6 +++++- .../conditionalConformanceVariantsSnapshot.1.txt | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Sources/SwiftDump/Dumper/ProtocolConformanceDumper.swift b/Sources/SwiftDump/Dumper/ProtocolConformanceDumper.swift index 0f2c8dc5..2128dce9 100644 --- a/Sources/SwiftDump/Dumper/ProtocolConformanceDumper.swift +++ b/Sources/SwiftDump/Dumper/ProtocolConformanceDumper.swift @@ -48,8 +48,12 @@ package struct ProtocolConformanceDumper: Conforme Space() } - for conditionalRequirement in dumped.conditionalRequirements { + for (offset, conditionalRequirement) in dumped.conditionalRequirements.offsetEnumerated() { try await conditionalRequirement.dump(resolver: demangleResolver, in: machO) + if !offset.isEnd { + Standard(",") + Space() + } } } } diff --git a/Tests/SwiftDumpTests/Snapshots/__Snapshots__/SymbolTestsCoreDumpSnapshotTests/conditionalConformanceVariantsSnapshot.1.txt b/Tests/SwiftDumpTests/Snapshots/__Snapshots__/SymbolTestsCoreDumpSnapshotTests/conditionalConformanceVariantsSnapshot.1.txt index 98aeff14..ac930a0c 100644 --- a/Tests/SwiftDumpTests/Snapshots/__Snapshots__/SymbolTestsCoreDumpSnapshotTests/conditionalConformanceVariantsSnapshot.1.txt +++ b/Tests/SwiftDumpTests/Snapshots/__Snapshots__/SymbolTestsCoreDumpSnapshotTests/conditionalConformanceVariantsSnapshot.1.txt @@ -47,5 +47,5 @@ extension SymbolTestsCore.ConditionalConformanceVariants.ConditionalContainerTes method descriptor for static Swift.Comparable.> infix(A, A) -> Swift.Bool } extension SymbolTestsCore.ConditionalConformanceVariants.ConditionalContainerTest: SymbolTestsCore.ConditionalConformanceVariants.ConditionalFirstProtocol where A: SymbolTestsCore.ConditionalConformanceVariants.ConditionalFirstProtocol {} -extension SymbolTestsCore.ConditionalConformanceVariants.ConditionalContainerTest: SymbolTestsCore.ConditionalConformanceVariants.ConditionalSecondProtocol where A: SymbolTestsCore.ConditionalConformanceVariants.ConditionalFirstProtocolA: SymbolTestsCore.ConditionalConformanceVariants.ConditionalSecondProtocol {} -extension SymbolTestsCore.ConditionalConformanceVariants.ConditionalContainerTest: SymbolTestsCore.ConditionalConformanceVariants.ConditionalThirdProtocol where A: SymbolTestsCore.ConditionalConformanceVariants.ConditionalFirstProtocolA: SymbolTestsCore.ConditionalConformanceVariants.ConditionalSecondProtocolA: SymbolTestsCore.ConditionalConformanceVariants.ConditionalThirdProtocol {} \ No newline at end of file +extension SymbolTestsCore.ConditionalConformanceVariants.ConditionalContainerTest: SymbolTestsCore.ConditionalConformanceVariants.ConditionalSecondProtocol where A: SymbolTestsCore.ConditionalConformanceVariants.ConditionalFirstProtocol, A: SymbolTestsCore.ConditionalConformanceVariants.ConditionalSecondProtocol {} +extension SymbolTestsCore.ConditionalConformanceVariants.ConditionalContainerTest: SymbolTestsCore.ConditionalConformanceVariants.ConditionalThirdProtocol where A: SymbolTestsCore.ConditionalConformanceVariants.ConditionalFirstProtocol, A: SymbolTestsCore.ConditionalConformanceVariants.ConditionalSecondProtocol, A: SymbolTestsCore.ConditionalConformanceVariants.ConditionalThirdProtocol {} \ No newline at end of file From b487ec305895e825e6a992e8ac9255661c989bed Mon Sep 17 00:00:00 2001 From: Mx-Iris Date: Fri, 28 Aug 2026 18:01:24 +0800 Subject: [PATCH 2/2] release: 0.17.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps BundledVersion to 0.17.1 and adds the changelog for the single fix that landed on next after 0.17.0: `dump` emitted a conditional conformance's `where` requirements with no separator between them, so any conformance carrying two or more conditions rendered invalid Swift. A patch number is what this warrants — one behavioural fix in one rendering path, no API change, no dependency change, no snapshot formatVersion change. ProjectEvolutionLog's per-section version annotations were re-checked as its maintenance rule asks at every bump and need no edit: the last section (PR #118 review fixes) ships in 0.17.0, and a single-line separator fix does not warrant a section of its own. --- Changelogs/0.17.1.md | 18 ++++++++++++++++++ Sources/swift-section/Version.swift | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 Changelogs/0.17.1.md diff --git a/Changelogs/0.17.1.md b/Changelogs/0.17.1.md new file mode 100644 index 00000000..ab61d20b --- /dev/null +++ b/Changelogs/0.17.1.md @@ -0,0 +1,18 @@ +# 0.17.1 + +A patch release on top of `0.17.0`. One fix, and it only affects `dump`. + +1. **Conditional conformances with more than one condition print valid Swift again.** The `where` clause ran its requirements together with no separator — `extension Box: Hashable where A: EquatableA: Hashable` instead of `where A: Equatable, A: Hashable`. A conformance with exactly one condition was never affected, and neither was `interface`, which renders the same clause through a different printer. + +The bug had been there since the conditional-conformance clause was first dumped (August 2025). It survived that long because this repository's own dump snapshot had frozen the malformed line as the expected output; the snapshot is corrected in the same commit and is now the regression test. + +## Compatibility + +- No API additions, removals or renames. No snapshot `formatVersion` change. +- Pinned dependencies are unchanged from `0.17.0`. +- The only output change is the one above: a comma and a space now separate each condition. + +## Requirements + +- Swift 6.2+ +- Xcode 26.0+ diff --git a/Sources/swift-section/Version.swift b/Sources/swift-section/Version.swift index 3fd37350..9b812f0a 100644 --- a/Sources/swift-section/Version.swift +++ b/Sources/swift-section/Version.swift @@ -2,5 +2,5 @@ // When bumping: also add Changelogs/.md, then tag the release with the same string. // Verified by .github/workflows/version-check.yml (PR) and .github/workflows/release.yml (tag). enum BundledVersion { - static let value = "0.17.0" + static let value = "0.17.1" }