Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-14694] Slow code completion inside result builders #57044

Closed
ahoppen opened this issue Jun 1, 2021 · 2 comments
Closed

[SR-14694] Slow code completion inside result builders #57044

ahoppen opened this issue Jun 1, 2021 · 2 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. code completion Area → source tooling: code completion found by stress tester Flag: An issue found by the SourceKit stress tester performance source tooling Area: IDE support, SourceKit, and other source tooling

Comments

@ahoppen
Copy link
Collaborator

ahoppen commented Jun 1, 2021

Previous ID SR-14694
Radar rdar://78780957
Original Reporter @ahoppen
Type Bug
Status Resolved
Resolution Done
Additional Detail from JIRA
Votes 0
Component/s CodeCompletion
Labels Bug, FoundByStressTester
Assignee @ahoppen
Priority Medium

md5: ac7228a49cece0fd73e3e2a6fe76cb0b

Issue Description:

This has become a catch-all radar for slow completion inside result builders. Look at issues in the stress tester’s XFails (https://github.com/apple/swift-source-compat-suite/blob/main/sourcekit-xfails.json) attributed to this bug for more examples. One reduced example is described below.


The test case below takes ~90seconds to report a completion but it will eventually come up with the right answer.

// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=COMPLETE

public protocol View2 {
    associatedtype Body : View2
    @ViewBuilder2 var body: Self.Body { get }
}

extension View2 {
  @inlinable public func frame(width: Int? = nil, height: Int? = nil) -> Never { fatalError() }
}

extension Never : View2 {}

struct EmptyView2: View2 {
  var body: Never {
    fatalError()
  }

  typealias Body = Never
}

extension Optional : View2 where Wrapped: View2 {
  public var body: Never {
    fatalError()
  }
}

@resultBuilder public struct ViewBuilder2 {
  public static func buildBlock() -> Never { fatalError() }
  public static func buildBlock<Content>(_ content: Content) -> Content where Content : View2 { fatalError() }
  public static func buildIf<Content>(_ content: Content?) -> Content? where Content : View2 { fatalError() }
  public static func buildEither<TrueContent>(first: TrueContent) -> TrueContent where TrueContent : View2 { fatalError() }
  public static func buildEither<TrueContent, FalseContent>(second: FalseContent) -> TrueContent where TrueContent : View2, FalseContent : View2 { fatalError() }
  public static func buildBlock<C0, C1>(_ c0: C0, _ c1: C1) -> C0 where C0 : View2, C1 : View2 { fatalError() }
  public static func buildBlock<C0, C1, C2>(_ c0: C0, _ c1: C1, _ c2: C2) -> C0 where C0 : View2, C1 : View2, C2 : View2 { fatalError() }
  public static func buildBlock<C0, C1, C2, C3>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3) -> C0 where C0 : View2, C1 : View2, C2 : View2, C3 : View2 { fatalError() }
}

public struct List2<SelectionValue, Content> where SelectionValue : Hashable {
    public init(selection: Set<SelectionValue>?, @ViewBuilder2 content: () -> Content) { fatalError() }
    public init(selection: SelectionValue?, @ViewBuilder2 content: () -> Content) { fatalError() }
}

extension List2 where SelectionValue == Never {
    public init(@ViewBuilder2 content: () -> Content) { fatalError() }
}

struct MoviesList {
    struct Props {
      let searchedKeywords: [Int]?
    }
    private var headerView: some View2 { EmptyView2() }
    private var movieSection: some View2 { EmptyView2() }
    private var peoplesSection: some View2 { EmptyView2() }

    private var keywordsSection: some View2 { return EmptyView2() }

    private var searchField: some View2 { return EmptyView2() }

    func body(props: Props) {
        _ = List2 {
            if true {
                searchField
            }

            if true {
                headerView
            }

            if true {
                if props.#^COMPLETE^#searchedKeywords != nil {
                    keywordsSection
                }
            }

            if true {
                peoplesSection
            } else {
                movieSection
            }
        }
    }
}
@ahoppen
Copy link
Collaborator Author

ahoppen commented Jun 11, 2021

Fixing this would reduce the time the stress tester takes to run by ~20 minutes because we won’t be hitting a request timeout 4 times.

@ahoppen
Copy link
Collaborator Author

ahoppen commented Mar 24, 2022

Fixed by migrating more things to solver-based implementation (most likely #41917 was the solution).

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@AnthonyLatsis AnthonyLatsis added the source tooling Area: IDE support, SourceKit, and other source tooling label Feb 6, 2023
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. code completion Area → source tooling: code completion found by stress tester Flag: An issue found by the SourceKit stress tester performance source tooling Area: IDE support, SourceKit, and other source tooling
Projects
None yet
Development

No branches or pull requests

2 participants