swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.28k stars 10.33k forks source link

[SR-15193] Exponential Compile Times in result builder bodies #57515

Open swift-ci opened 2 years ago

swift-ci commented 2 years ago
Previous ID SR-15193
Radar rdar://problem/83163551
Original Reporter juliand665 (JIRA User)
Type Bug

Attachment: Download

Environment Xcode Version 13.0 beta 5 (13A5212g)
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: 6bc7c08c62ec6c54a384b4147c747c2f

Issue Description:

I first ran into this in a SwiftUI body getter involving some math that completely refused to compile in reasonable time, even after giving it a full 5 minutes. I've since whittled it down to a relatively minimal example, involving implicit CGFloat–Double conversion.

I've attached a project exhibiting the issue, but I'll add the relevant code here for completeness:

import Foundation
//import SwiftUI

// not necessary but avoids dependency on existing result builders
@resultBuilder
enum Builder<T> {
    static func buildBlock(_ components: Never...) -> Never {
        switch components.first! {}
    }
}

@Builder<Never> func compute() -> Never {
// alternatively, if you'd rather avoid the custom builder:
//@ViewBuilder func compute() -> some View {
    let width: CGFloat = 100.0
    let spacePerBox = width + width
    let _ = floor(spacePerBox + spacePerBox)
    let _ = width / spacePerBox
    let _ = width / spacePerBox
    let _ = width / spacePerBox
    let _ = width / spacePerBox
    let _ = width / spacePerBox
    let _ = width / spacePerBox
    let _ = width / spacePerBox
    let _ = width / spacePerBox
    let _ = width / spacePerBox
    // each additional one of these lines doubles compile times
}

Removing the explicit CGFloat type annotation from width (letting it default to Double) avoids the issue, as well as simplifying the line using floor, or specifying spacePerBox's type.

typesanitizer commented 2 years ago

cc @xedin

@swift-ci create