Slide 1

Slide 1 text

プログラムは思った通りには動かない、 書いた通りに動く 作者不詳

Slide 2

Slide 2 text

const a = '1'; const b = 2; const c = a + b; console.log(c); // 3? ❌ 🤔

Slide 3

Slide 3 text

const a = '1'; const b = 2; const c = a + b; console.log(c); // '12' 🤮

Slide 4

Slide 4 text

const a = 1; const b = 2; const c = a + b; console.log(c); // 3 😇

Slide 5

Slide 5 text

import Foundation import SamplePackage @main struct Runner { static func main() { SamplePackage.run { print("Hello, world!") } let result = SamplePackage.greeting { "c" } print(result == "C: c") } } import Testing @testable import SamplePackage @Test func run() async throws { SamplePackage.run { print("Hello, world!") } } @Test func greeting() async throws { let result = SamplePackage.greeting { "c" } #expect(result == "C: c") } ※サンプルコードです。実際のコードとは関係ありません。

Slide 6

Slide 6 text

import Foundation import SamplePackage @main struct Runner { static func main() { SamplePackage.run { print("Hello, world!") } let result = SamplePackage.greeting { "c" } print(result == "C: c") } } import Testing @testable import SamplePackage @Test func run() async throws { SamplePackage.run { print("Hello, world!") } } @Test func greeting() async throws { let result = SamplePackage.greeting { "c" } #expect(result == "C: c") } ※サンプルコードです。実際のコードとは関係ありません。

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

書いた通りに動いていない… だと…?

Slide 10

Slide 10 text

OSのバージョン差異 ライブラリ Xcode/Swift のバージョン差異 のバージョン差異

Slide 11

Slide 11 text

_人人人人人人人人_ > 全て同じ条件 <  ̄Y^Y^Y^Y^YY^Y^ ̄

Slide 12

Slide 12 text

🤔

Slide 13

Slide 13 text

// swift-tools-version: 6.3 import PackageDescription let package = Package( name: "iOSDC2026_SampleRunner", products: [], dependencies: [ .package(name: "iOSDC2026_Sample", path: "../"), ], targets: [ .executableTarget( name: "SampleRunner", dependencies: [ .product( name: "SamplePackage", package: "iOSDC2026_Sample" ), ], swiftSettings: [ .enableUpcomingFeature("ForwardTrailingClosures"), ], ), ], swiftLanguageModes: [.v5] ) // swift-tools-version: 6.3 import PackageDescription let package = Package( name: "iOSDC2026_Sample", products: [ .library( name: "SamplePackage", targets: ["SamplePackage"] ), ], targets: [ .target( name: "SamplePackage", ), .testTarget( name: "SamplePackageTests", dependencies: ["SamplePackage"] ), ], swiftLanguageModes: [.v5] )

Slide 14

Slide 14 text

お分かりいただけただろうか

Slide 15

Slide 15 text

// swift-tools-version: 6.3 import PackageDescription let package = Package( name: "iOSDC2026_SampleRunner", products: [], dependencies: [ .package(name: "iOSDC2026_Sample", path: "../"), ], targets: [ .executableTarget( name: "SampleRunner", dependencies: [ .product( name: "SamplePackage", package: "iOSDC2026_Sample" ), ], swiftSettings: [ .enableUpcomingFeature("ForwardTrailingClosures"), ], ), ], swiftLanguageModes: [.v5] ) // swift-tools-version: 6.3 import PackageDescription let package = Package( name: "iOSDC2026_Sample", products: [ .library( name: "SamplePackage", targets: ["SamplePackage"] ), ], targets: [ .target( name: "SamplePackage", ), .testTarget( name: "SamplePackageTests", dependencies: ["SamplePackage"] ), ], swiftLanguageModes: [.v5] )

Slide 16

Slide 16 text

フラグが…ない…

Slide 17

Slide 17 text

完

Slide 18

Slide 18 text

解説

Slide 19

Slide 19 text

解説 ForwardTrailingClosures(SE-0286、Swift 5.8+) public func run( _ a: (() -> Void)? = nil, _ b: (() -> Void)? = nil, _ c: (() -> Void)? = nil, ) { if let a { print("\u{001B}[31mRunning A\u{001B}[0m") a() } if let b { print("\u{001B}[32mRunning B\u{001B}[0m") b() } if let c { print("\u{001B}[33mRunning C\u{001B}[0m") c() } } run { print("Hello, world!") } ForwardTrailingClosures = NO ForwardTrailingClosures = YES

Slide 20

Slide 20 text

解説 Upcoming Feature Flagsはコンパイルに渡すフラグ • 各モジュールはUpcoming Feature Flagsの情報を持たない • モジュール間で分割可能 ForwardTrailingClosures YES ForwardTrailingClosures NO A B

Slide 21

Slide 21 text

対策(同じ挙動にしたい場合) 全モジュールに適用する-Package内の全targetに適用 let package = Package( name: "SamplePackage", products: [], dependencies: [~], targets: [ .target( name: "FeatureA", dependencies: [~], swiftSettings: [ .enableUpcomingFeature("ForwardTrailingClosures"), ], ), .target( name: "FeatureB", dependencies: [~], swiftSettings: [ .enableUpcomingFeature("ForwardTrailingClosures"), ], ), .target( name: "FeatureC", dependencies: [~], swiftSettings: [ .enableUpcomingFeature("ForwardTrailingClosures"), ], ), … ], )

Slide 22

Slide 22 text

対策(同じ挙動にしたい場合) 全モジュールに適用する-Package内の全targetに適用 let package = Package( name: "SamplePackage", products: [], dependencies: [~], targets: [ .target( name: "FeatureA", dependencies: [~], ), .target( name: "FeatureB", dependencies: [~], ), .target( name: "FeatureC", dependencies: [~], ), … ], ) package.targets.forEach { $0.swiftSettings = [ .enableUpcomingFeature("ForwardTrailingClosures"), ] }

Slide 23

Slide 23 text

対策(同じ挙動にしたい場合) 全モジュールに適用する-複数Packageを跨ぐ場合 • 仕組みで検知するのは難しい🥺

Slide 24

Slide 24 text

そこでAIの出番🤖

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

まとめ • 書いたとおりに動いていないと思っていたけど結局書いた通りに動いていた • Package.swiftやxcodeprojのBuild Settingsも疑おう • そもそもそんな変な実装するな

Slide 27

Slide 27 text

もう対応終わってるし! なんならSwift 6対応できてるし! 😤

Slide 28

Slide 28 text

NonisolatedNonsendingByDefault ImmutableWeakCaptures MemberImportVisibility Swift 7対応が待ってます😇 InferIsolatedConformances InternalImportsByDefault ExistentialAny

Slide 29

Slide 29 text

Self Introduction • 417.72KI • Twitter: @417̲72ki • GitHub: 417-72KI • Icon by: @fredii • Working at: (REDACTED)

Slide 30

Slide 30 text

おまけ

Slide 31

Slide 31 text

コンパイル時に評価される過程 SILで差分確認 $ swiftc -emit-silgen -swift-version 5 sample.swift > sample-5.sil $ swiftc -emit-silgen -swift-version 6 sample.swift > sample-6.sil import Foundation public func run( _ a: (() -> Void)? = nil, _ b: (() -> Void)? = nil, _ c: (() -> Void)? = nil, ) {} run { print("Hello world!") }

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

プログラムは思った通りには動かない。 書いた通りに動k... 動かない...だと...? 2026/09/13 iOSDC 2026 Day 2