swiftwasm / swift

WebAssembly support for the Swift programming language
https://swiftwasm.org
1.28k stars 28 forks source link

Compiler crash for Parameter Packs: `Incorrect reconstructed type` #5563

Closed Kyle-Ye closed 5 months ago

Kyle-Ye commented 5 months ago

I'm adding WASM CI to some of my packages. And I noticed some Parameter Packs related compiler crash here. (The feature was introduced in Swift 5.9)

Incorrect reconstructed type for $s11OpenSwiftUI9TupleViewVyxxQp_tGD
Original type:
(bound_generic_struct_type decl=OpenSwiftUI.(file).TupleView@/home/runner/work/OpenSwiftUI/OpenSwiftUI/Sources/OpenSwiftUI/Views/View/TODO/TupleView.swift:11:15
  (tuple_type num_elements=1
    (tuple_type_elt
      (pack_expansion_type
        (pattern=generic_type_param_type depth=0 index=0 pack)
        (count=generic_type_param_type depth=0 index=0 pack)))))
Reconstructed type:
(bound_generic_struct_type decl=OpenSwiftUI.(file).TupleView@/home/runner/work/OpenSwiftUI/OpenSwiftUI/Sources/OpenSwiftUI/Views/View/TODO/TupleView.swift:11:15
  (pack_expansion_type
    (pattern=generic_type_param_type depth=0 index=0 pack)
    (count=generic_type_param_type depth=0 index=0 pack)))
Generic signature: <each τ_0_0 where repeat each τ_0_0 : View>

The reproducible code

@_disfavoredOverload
@_alwaysEmitIntoClient
public static func buildBlock<each Content>(_ content: repeat each Content) -> TupleView<(repeat each Content)> where repeat each Content: View {
    TupleView((repeat each content))
}

See full log here https://github.com/OpenSwiftUIProject/OpenSwiftUI/actions/runs/7640702278/job/20816373359?pr=27

kateinoigakukun commented 5 months ago

The log URL you attached seems something different to me

Kyle-Ye commented 5 months ago

The log URL you attached seems something different to me

Fixed.

Kyle-Ye commented 5 months ago

Add more swift version for a test:

kateinoigakukun commented 5 months ago

I think that's because we build compilers with assertions conservatively. Your code triggered ABI violation assertion, so I think it's slightly broken on other platforms as well at runtime even it passes compilation.

Kyle-Ye commented 5 months ago

I think that's because we build compilers with assertions conservatively. Your code triggered ABI violation assertion, so I think it's slightly broken on other platforms as well at runtime even it passes compilation.

I thought we only have stable ABI on Darwin platform 🤔.

Your code triggered ABI violation assertion

Which rule do I break? I can normally run Unit Tests target of the package on Linux, macOS and iOS. They all seem fine.

kateinoigakukun commented 5 months ago

It's an issue in compiler that misses type coercion for nested unpacked tuple. Please try replacing TupleView((repeat each content)) with TupleView(repeat each content).

Kyle-Ye commented 5 months ago
 TupleView((repeat each content))

Such code is invalid and will cause a compiler error here.

image

A note for the interface of TupleView

@frozen
public struct TupleView<T>: PrimitiveView {
    public var value: T
    @inlinable public init(_ value: T) { self.value = value }
    public typealias Body = Never
}
kateinoigakukun commented 5 months ago

Sorry, I couldn't reproduce on my end. I think disabling the assertion by adding -Xfrontend -enable-round-trip-debug-types options would be best for you. If you need more help from me, would you mind making a minimum reproducible code?

Kyle-Ye commented 5 months ago

-Xfrontend -enable-round-trip-debug-types

Thanks. I'll give it a try.

would you mind making a minimum reproducible code?

I believe the following snipest can reproduce it.

public protocol View {
    associatedtype Body: View
    @ViewBuilder
    @MainActor
    var body: Self.Body { get }
}

extension Never: View { public var body: Never { fatalError() } }

protocol PrimitiveView: View where Body == Never {}

extension PrimitiveView {
    public var body: Never { fatalError() }
}

@frozen
public struct TupleView<T>: PrimitiveView {
    public var value: T
    @inlinable public init(_ value: T) { self.value = value }
    public typealias Body = Never
}

@resultBuilder
public enum ViewBuilder {
    @_alwaysEmitIntoClient
    public static func buildExpression<Content>(_ content: Content) -> Content where Content: View {
        content
    }

    @_alwaysEmitIntoClient
    public static func buildBlock<Content>(_ content: Content) -> Content where Content: View {
        content
    }

    @_disfavoredOverload
    @_alwaysEmitIntoClient
    public static func buildBlock<each Content>(_ content: repeat each Content) -> TupleView < (repeat each Content)> where repeat each Content: View {
        TupleView((repeat each content))
    }
}
kateinoigakukun commented 5 months ago

Thanks, but it doesn't reproduce. Please ensure that swiftc -frontend -c check.swift -target wasm32-unknown-wasi can reproduce it.

Kyle-Ye commented 5 months ago

Thanks, but it doesn't reproduce. Please ensure that swiftc -frontend -c check.swift -target wasm32-unknown-wasi can reproduce it.

Haven't installed Wasm Swift SDK locally before. I'll give it a shot this weekend and report the minimum reproducible code later.

Kyle-Ye commented 5 months ago

Add more swift version for a test:

  • x86_64 Ubuntu 22 + wasm-5.9.1-RELEASE ❌
  • x86_64 Ubuntu 22 + wasm-5.10-SNAPSHOT-2024-01-22-a ❌
  • x86_64 Ubuntu 22 + wasm-DEVELOPMENT-SNAPSHOT-2024-01-22-a ✅
  1. Using a local wasm-5.9.1-RELEASE SDK + Xcode 15.2 gives more error here
    
    Building for debugging...
    /Applications/Xcode-15.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/System/Library/Frameworks/Foundation.framework/Modules/Foundation.swiftmodule/arm64e-apple-macos.swiftinterface:3944:141: error: cannot specialize non-generic type 'Collection' (aka 'OpaquePointer')
    public mutating func replaceSubrange(_ subrange: Swift.Range<Foundation.AttributedString.UnicodeScalarView.Index>, with newElements: some Collection<UnicodeScalar>)
                                                                                                                                            ^         ~~~~~~~~~~~~~~~

/Applications/Xcode-15.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/System/Library/Frameworks/Foundation.framework/Modules/Foundation.swiftmodule/arm64e-apple-macos.swiftinterface:11963:137: error: cannot specialize non-generic type 'Collection' (aka 'OpaquePointer') public mutating func replaceSubrange(_ subrange: Swift.Range, with newElements: some Collection) ^ ~~~

/Applications/Xcode-15.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk/usr/lib/swift/OSLog.swiftmodule/arm64e-apple-macos.swiftinterface:5:8: error: failed to build module 'Foundation'; this SDK is not supported by the compiler (the SDK is built with 'Apple Swift version 5.9.2 (swiftlang-5.9.2.2.11 clang-1500.1.0.2.2)', while this compiler is 'SwiftWasm Swift version 5.9.1 (swift-5.9.1-RELEASE)'). Please select a toolchain which matches the SDK. import Foundation



This compile error would be fixed in Swift 5.9.2

2. Using a local wasm-5.10-SNAPSHOT-2024-01-22-a SDK + Xcode 15.2 works fine and can not reproduce the issue.

- arm64 macOS 14 + Xcode 14.2 + wasm-5.10-SNAPSHOT-2024-01-22-a ✅

I'd like to try the same env of the CI - Ubuntu 22 here. But my Linux env is aarch64 Ubuntu 22 and there is no such wasm SDK to download currently.

![image](https://github.com/swiftwasm/swift/assets/43724855/ac6de6ca-94be-4ae7-be9c-31df98f6ab75)

I'll set up a x86_64 Ubuntu 22 to give it a try.
Kyle-Ye commented 5 months ago

Thanks, but it doesn't reproduce. Please ensure that swiftc -frontend -c check.swift -target wasm32-unknown-wasi can reproduce it.

Set up a x86_64 Ubuntu 22 locally and I can reproduce the bug both with OpenSwiftUI package and the snippets package I post above with swift build command (The same command I'm using for CI).

DemoKit.zip

Using swiftc -frontend -c check.swift -target wasm32-unknown-wasi gives a warning here and give a .o output as success. Do you know what should I do to make swift build also success here?

kyle@ubuntu-amd64:/DemoKit/Sources/DemoKit$ swift --version
SwiftWasm Swift version 5.9.1 (swift-5.9.1-RELEASE)
Target: x86_64-unknown-linux-gnu
kyle@ubuntu-amd64:/DemoKit/Sources/DemoKit$ swiftc -frontend -c DemoKit.swift -target wasm32-unknown-wasi
<unknown>:0: warning: glibc not found for 'wasm32-unknown-wasi'; C stdlib may be unavailable
kyle@ubuntu-amd64:/DemoKit/Sources/DemoKit$ l
DemoKit.o  DemoKit.swift

In summary, the current build matrix:

// `swift build` result for DemoKit package
x86_64 Ubuntu 22 + wasm-5.9.1-RELEASE ❌
x86_64 Ubuntu 22 + wasm-5.10-SNAPSHOT-2024-01-22-a ❌
x86_64 Ubuntu 22 + wasm-DEVELOPMENT-SNAPSHOT-2024-01-22-a ✅
arm64 macOS 14 + Xcode 14.2 + wasm-5.9.1-RELEASE ❓ (Blocked by other issue waiting for a wasm-5.9.2-RELEASE)
arm64 macOS 14 + Xcode 14.2 + wasm-5.10-SNAPSHOT-2024-01-22-a ✅

On my side, I'm consider using macOS container as CI or use the latest wasm-DEVELOPMENT-SNAPSHOT + Ubuntu as a workaround while waiting for a upstream investigation.

kateinoigakukun commented 5 months ago

At this moment, please use swift build -Xswiftc -Xfrontend -Xswiftc -disable-round-trip-debug-types. The root issue is an upstream compiler bug and it's not completely related to Wasm target. Also it's already fixed in main branch.

Kyle-Ye commented 5 months ago

At this moment, please use swift build -Xswiftc -Xfrontend -Xswiftc -disable-round-trip-debug-types. The root issue is an upstream compiler bug and it's not completely related to Wasm target. Also it's already fixed in main branch.

Thanks. It works. I'll update my CI script to fix it.