swiftlang / swift

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

[SR-15403] Result builder generic inference does not work #57717

Open stephencelis opened 2 years ago

stephencelis commented 2 years ago
Previous ID SR-15403
Radar None
Original Reporter @stephencelis
Type Bug
Environment Swift 5.5
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 5 | |Component/s | Compiler | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: 697cecc0c7d7a2b891e974ca48770122

Issue Description:

Result builders seem to have a problem inferring generics. In the following example, the generic should be well-understood but must be explicitly specified:

struct Foo<T> {}

@resultBuilder
enum Builder {
  static func buildBlock<T>(_ components: Foo<T>...) -> Foo<T> {
    .init()
  }
}

extension Foo {
  func build(@Builder build: () -> Foo) -> Foo {
    return build()
  }
}

func f() {
  let f = Foo<Int>().build {
    Foo<Int>()
    Foo() // error: Cannot convert value of type 'Foo<_>' to expected argument type 'Foo<Int>'
  }
}
stephencelis commented 2 years ago

/cc @slavapestov You've been pretty active on generics so I wonder if you'd know what was going on here? We're pushing our overloads and @_disfavoredOverload to the limits to try to work around this issue in swift-parsing, and our workarounds make for a pretty bad library user experience 🙁

stephencelis commented 2 years ago

I found this thread saying it's intended behavior: https://forums.swift.org/t/function-builder-cannot-infer-generic-parameters-even-though-direct-call-to-buildblock-can/35886

A pretty big bummer 🙁 Not sure if there are ways around the behavior. Even introducing a generic at the builder level (e.g., @ParserBuilder\<Input>) doesn't seem to propagate the generic through.

stephencelis commented 2 years ago

I may not understand the thread, but towards the end, @DougGregor seems to say that a feature like buildPartialBlock could unlock this kind of fluent inference again, but I tried a snapshot and it still doesn't work. Should I report such an enhancement to buildPartialBlock separately?