Skip to content

Commit abc9512

Browse files
committed
ci: A" fix-shape validation target (canonical-root respell) in the Windows repro
Run 28776276301 verified: cross-package typealias-sugar variant fires the identical assertion + frame on Swift 6.3.3 AND 6.4-dev a42409e978ff428 (single-file CLEAN on both) — Option B's 6.4-fixes-it premise is refuted for this shape. RespellModule is CrashModule with ONLY the two downcasts spelled through the canonical root (any ISO_32000.…): CLEAN on 6.3.3 validates a one-token-per-site production fix at PDF.HTML.Context+Rendering.swift:267/:283.
1 parent 69c302a commit abc9512

3 files changed

Lines changed: 125 additions & 8 deletions

File tree

.github/repro/cross-package/crash/Package.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,18 @@ let package = Package(
2323
.enableUpcomingFeature("InternalImportsByDefault"),
2424
.enableUpcomingFeature("MemberImportVisibility"),
2525
]
26-
)
26+
),
27+
.target(
28+
name: "RespellModule",
29+
dependencies: [
30+
.product(name: "BasePDF", package: "base")
31+
],
32+
swiftSettings: [
33+
.enableUpcomingFeature("ExistentialAny"),
34+
.enableUpcomingFeature("InternalImportsByDefault"),
35+
.enableUpcomingFeature("MemberImportVisibility"),
36+
]
37+
),
2738
],
2839
swiftLanguageModes: [.v6]
2940
)
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// A″ fix-shape validation: IDENTICAL to CrashModule except the two
2+
// existential downcasts (and only those) are respelled through the
3+
// CANONICAL namespace root `ISO_32000` instead of the `PDF` typealias.
4+
// Declarations still extend via the `PDF` alias (declaration parity with
5+
// production). If this target is CLEAN on Windows 6.3.3 while CrashModule
6+
// fires, the typealias sugar in the WRITTEN type at the downcast site is
7+
// the trigger, and the production fix is a one-token respell at
8+
// PDF.HTML.Context+Rendering.swift:267/:283.
9+
10+
public import BasePDF
11+
12+
extension PDF {
13+
public enum HTML {}
14+
}
15+
16+
extension PDF.HTML {
17+
public enum Style {}
18+
19+
public struct Configuration {
20+
public init() {}
21+
}
22+
}
23+
24+
extension PDF.HTML.Style {
25+
public enum Context {}
26+
27+
public protocol Modifier {
28+
func apply(to context: inout PDF.Context, configuration: PDF.HTML.Configuration)
29+
}
30+
}
31+
32+
extension PDF.HTML.Style.Context {
33+
public protocol Modifier {
34+
func apply(to context: inout PDF.HTML.Context)
35+
}
36+
}
37+
38+
extension PDF.HTML {
39+
public struct Context {
40+
public var pdf: PDF.Context
41+
public var configuration: PDF.HTML.Configuration
42+
43+
public init() {
44+
self.pdf = PDF.Context()
45+
self.configuration = PDF.HTML.Configuration()
46+
}
47+
48+
public mutating func apply(inlineStyle property: Any) -> Bool {
49+
let unwrapped: Any
50+
let mirror = Mirror(reflecting: property)
51+
if mirror.displayStyle == .optional {
52+
guard let first = mirror.children.first else { return false }
53+
unwrapped = first.value
54+
} else {
55+
unwrapped = property
56+
}
57+
58+
var handled = false
59+
60+
// Canonical-root spelling — the only difference from CrashModule.
61+
if let modifier = unwrapped as? any ISO_32000.HTML.Style.Modifier {
62+
modifier.apply(to: &pdf, configuration: configuration)
63+
handled = true
64+
}
65+
66+
if let htmlModifier = unwrapped as? any ISO_32000.HTML.Style.Context.Modifier {
67+
htmlModifier.apply(to: &self)
68+
handled = true
69+
}
70+
71+
return handled
72+
}
73+
}
74+
}
75+
76+
public struct Bold: PDF.HTML.Style.Modifier {
77+
public init() {}
78+
public func apply(to context: inout PDF.Context, configuration: PDF.HTML.Configuration) {
79+
context.value += 1
80+
}
81+
}
82+
83+
public struct PageBreak: PDF.HTML.Style.Context.Modifier {
84+
public init() {}
85+
public func apply(to context: inout PDF.HTML.Context) {
86+
context.pdf.value += 1
87+
}
88+
}
89+
90+
public func exercise() -> Int {
91+
var context = PDF.HTML.Context()
92+
_ = context.apply(inlineStyle: Bold())
93+
_ = context.apply(inlineStyle: Optional.some(PageBreak()) as Any)
94+
return context.pdf.value
95+
}

.github/workflows/windows-existential-repro.yml

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,15 @@ name: Windows existential repro
1313
# Per swiftlang/swift#86202 (the `any HTML.View` sibling), cross-package
1414
# + namespace-typealias sugar are load-bearing ingredients; the written
1515
# existential carries TypeAliasType sugar at its root, which is the
16-
# non-canonical type the mangler chokes on. 6.4 carries typealias-
17-
# existential debug-info fixes (45547be3f8f, 6f60adf009c, 2934386efde)
18-
# absent from 6.3.
16+
# non-canonical type the mangler chokes on. VERIFIED 2026-07-06 (run
17+
# 28776276301): STILL FIRING on 6.3.3 AND on 6.4-dev a42409e978ff428 —
18+
# the 6.4 typealias-existential debug-info fixes (45547be3f8f,
19+
# 6f60adf009c, 2934386efde) do NOT cover this shape; single-file CLEAN
20+
# on both (cross-package + alias sugar are load-bearing);
21+
# 3. respell-canonical — identical to (2) except the two downcasts are
22+
# spelled through the canonical root (`any ISO_32000.…`). CLEAN here
23+
# while (2) fires validates the surgical production fix: respell the
24+
# written existential type at the two crash-site downcasts.
1925
#
2026
# Reading the legs together (per variant):
2127
# 6.3.3 FIRING + 6.4 CLEAN → the 6.4 fix is empirically confirmed for that
@@ -89,12 +95,17 @@ jobs:
8995
Write-Host $out1
9096
Write-Host "::notice title=single-file::$disp1 on Swift ${{ matrix.swift-version }}"
9197
92-
$out2 = & swift build -c debug --package-path '.github/repro/cross-package/crash' 2>&1 | Out-String
98+
$out2 = & swift build -c debug --package-path '.github/repro/cross-package/crash' --target CrashModule 2>&1 | Out-String
9399
$disp2 = Get-Disposition -Output $out2 -Code $LASTEXITCODE
94100
Write-Host $out2
95101
Write-Host "::notice title=cross-package::$disp2 on Swift ${{ matrix.swift-version }}"
96102
97-
Write-Host "DISPOSITION MATRIX (Swift ${{ matrix.swift-version }}): single-file=$disp1 cross-package=$disp2"
98-
if (($disp1 -eq 'CLEAN') -and ($disp2 -eq 'CLEAN')) { exit 0 }
99-
if (($disp1 -eq 'INCONCLUSIVE') -or ($disp2 -eq 'INCONCLUSIVE')) { exit 1 }
103+
$out3 = & swift build -c debug --package-path '.github/repro/cross-package/crash' --target RespellModule 2>&1 | Out-String
104+
$disp3 = Get-Disposition -Output $out3 -Code $LASTEXITCODE
105+
Write-Host $out3
106+
Write-Host "::notice title=respell-canonical::$disp3 on Swift ${{ matrix.swift-version }}"
107+
108+
Write-Host "DISPOSITION MATRIX (Swift ${{ matrix.swift-version }}): single-file=$disp1 cross-package=$disp2 respell-canonical=$disp3"
109+
if (($disp1 -eq 'CLEAN') -and ($disp2 -eq 'CLEAN') -and ($disp3 -eq 'CLEAN')) { exit 0 }
110+
if (($disp1 -eq 'INCONCLUSIVE') -or ($disp2 -eq 'INCONCLUSIVE') -or ($disp3 -eq 'INCONCLUSIVE')) { exit 1 }
100111
exit 2

0 commit comments

Comments
 (0)