Skip to content

Generic struct using type pack can't store closure using same type pack in property #68369

@martialln

Description

@martialln

Description
The following code doesn't compile on the last toolchain

struct Foo<each T> {
    let foo: (repeat each T) -> Void

    init(
        fn: @escaping (repeat each T) -> Void
    ) {
        self.foo = fn
    }
}

Compiler respond the following message with Xcode 15.0 beta 8 (15A5229m) and swift-DEVELOPMENT-SNAPSHOT-2023-09-04-a toolchain

error: type of expression is ambiguous without a type annotation
        self.foo = fn
        ~~~~~~~~~^~~~

Steps to reproduce

  • Compile source code with -typecheck flag
  • It fails

Expected behavior

  • Code should compile

Output of the same command with -debug-constraints:

---Constraint solving at [Sources/main.swift:7:9 - line:7:20]---
  (overload set choice binding $T0 := @lvalue Foo<repeat each T>)
  (overload set choice binding $T1 := @lvalue ($T3) -> Void [each T := $T2])
  (overload set choice binding $T4 := (repeat each T) -> Void)

---Initial constraints for the given expression---
(assign_expr type='()' location=Sources/main.swift:7:18 range=[Sources/main.swift:7:9 - line:7:20]
  (unresolved_dot_expr type='@lvalue ($T3) -> Void' location=Sources/main.swift:7:14 range=[Sources/main.swift:7:9 - line:7:14] field 'foo' function_ref=unapplied
    (declref_expr type='@lvalue Foo<repeat each T>' location=Sources/main.swift:7:9 range=[Sources/main.swift:7:9 - line:7:9] decl=main.(file).Foo.init(fn:).self@Sources/main.swift:4:5 function_ref=unapplied))
  (declref_expr type='(repeat each T) -> Void' location=Sources/main.swift:7:20 range=[Sources/main.swift:7:20 - line:7:20] decl=main.(file).Foo.init(fn:).fn@Sources/main.swift:5:9 function_ref=unapplied))

Score: <default 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>
Type Variables:
  $T0 as @lvalue Foo<repeat each T> @ locator@0x1350e2000 [DeclRef@Sources/main.swift:7:9]
  $T1 as @lvalue ($T3) -> Void @ locator@0x1350e2078 [UnresolvedDot@Sources/main.swift:7:14 → member]
  $T2 as Pack{repeat each T} @ locator@0x1350e2138 [UnresolvedDot@Sources/main.swift:7:14 → member → generic parameter 'each T']
  $T3 [allows bindings to: pack expansion] [with possible bindings: (supertypes of) repeat each T] [defaults: repeat $T2] @ locator@0x1350e2298 [UnresolvedDot@Sources/main.swift:7:14 → member → pack expansion type (repeat $T2)]
  $T4 as (repeat each T) -> Void @ locator@0x1350e24b8 [DeclRef@Sources/main.swift:7:20]
  $T5 as ($T3) -> Void @ locator@0x1350e2500 [UnresolvedDot@Sources/main.swift:7:14]
Active Constraints:
  $T2 conforms to _Copyable @ locator@0x1350e2138 [UnresolvedDot@Sources/main.swift:7:14 → member → generic parameter 'each T']
  $T3 can fallback to repeat $T2 @ locator@0x1350e2298 [UnresolvedDot@Sources/main.swift:7:14 → member → pack expansion type (repeat $T2)]
Inactive Constraints:
  repeat each T subtype $T3 @ locator@0x1350e2580 [Assign@Sources/main.swift:7:18 → function argument]
Resolved overloads:
  selected overload set choice self: $T0 == @lvalue Foo<repeat each T> for locator@0x1350e2000 [DeclRef@Sources/main.swift:7:9]
  selected overload set choice @lvalue Foo<repeat each T>.foo: $T1 == @lvalue ($T3) -> Void for locator@0x1350e2078 [UnresolvedDot@Sources/main.swift:7:14 → member]
  selected overload set choice fn: $T4 == (repeat each T) -> Void for locator@0x1350e24b8 [DeclRef@Sources/main.swift:7:20]
Opened types:
  locator@0x1350e2078 [UnresolvedDot@Sources/main.swift:7:14 → member] opens 'each T' (each τ_0_0) -> $T2
Opened pack expansion types:
  repeat $T2 opens to $T3

  (considering: $T2 conforms to _Copyable @ locator@0x1350e2138 [UnresolvedDot@Sources/main.swift:7:14 → member → generic parameter 'each T']
    (simplification result:
      (removed constraint: $T2 conforms to _Copyable @ locator@0x1350e2138 [UnresolvedDot@Sources/main.swift:7:14 → member → generic parameter 'each T'])
    )
    (outcome: simplified)
  )
  (considering: $T3 can fallback to repeat $T2 @ locator@0x1350e2298 [UnresolvedDot@Sources/main.swift:7:14 → member → pack expansion type (repeat $T2)]
    (simplification result:
    )
    (outcome: unsolved)
  )
  (Potential Binding(s):
    ($T3 [allows bindings to: pack expansion] [with possible bindings: (supertypes of) repeat each T] [defaults: repeat $T2])
  )
  (attempting type variable binding $T3 := repeat $T2
    (considering: $T3 can fallback to repeat $T2 @ locator@0x1350e2298 [UnresolvedDot@Sources/main.swift:7:14 → member → pack expansion type (repeat $T2)]
      (simplification result:
        (removed constraint: $T3 can fallback to repeat $T2 @ locator@0x1350e2298 [UnresolvedDot@Sources/main.swift:7:14 → member → pack expansion type (repeat $T2)])
      )
      (outcome: simplified)
    )
    (considering: repeat each T subtype $T3 @ locator@0x1350e2580 [Assign@Sources/main.swift:7:18 → function argument]
      (simplification result:
        (failed constraint each T same-shape $T2 @ locator@0x1350e2658 [Assign@Sources/main.swift:7:18 → function argument → pack shape])
        (removed constraint: repeat each T subtype $T3 @ locator@0x1350e2580 [Assign@Sources/main.swift:7:18 → function argument])
        (failed constraint repeat each T subtype $T3 @ locator@0x1350e2580 [Assign@Sources/main.swift:7:18 → function argument])
      )
      (outcome: error)
    )
  )

---Solver statistics---
Total number of scopes explored: 2
Maximum depth reached while exploring solutions: 2
Time: 6.790000e-01ms
---Attempting to salvage and emit diagnostics---
  (considering: $T2 conforms to _Copyable @ locator@0x1350e2138 [UnresolvedDot@Sources/main.swift:7:14 → member → generic parameter 'each T']
    (simplification result:
      (removed constraint: $T2 conforms to _Copyable @ locator@0x1350e2138 [UnresolvedDot@Sources/main.swift:7:14 → member → generic parameter 'each T'])
    )
    (outcome: simplified)
  )
  (considering: $T3 can fallback to repeat $T2 @ locator@0x1350e2298 [UnresolvedDot@Sources/main.swift:7:14 → member → pack expansion type (repeat $T2)]
    (simplification result:
    )
    (outcome: unsolved)
  )
  (Potential Binding(s):
    ($T3 [allows bindings to: pack expansion] [with possible bindings: (supertypes of) repeat each T] [defaults: repeat $T2])
  )
  (attempting type variable binding $T3 := repeat $T2
    (considering: repeat each T subtype $T3 @ locator@0x1350e2580 [Assign@Sources/main.swift:7:18 → function argument]
      (simplification result:
    (attempting fix [fix: skip same-shape requirement] @ locator@0x1350e2658 [Assign@Sources/main.swift:7:18 → function argument → pack shape])
    (increasing 'applied fix' score by 1 @ locator@0x1350e2658 [Assign@Sources/main.swift:7:18 → function argument → pack shape])
        (removed constraint: repeat each T subtype $T3 @ locator@0x1350e2580 [Assign@Sources/main.swift:7:18 → function argument])
        (failed constraint repeat each T subtype $T3 @ locator@0x1350e2580 [Assign@Sources/main.swift:7:18 → function argument])
      )
      (outcome: error)
    )
  )
Sources/main.swift:7:18: error: type of expression is ambiguous without a type annotation
        self.foo = fn
        ~~~~~~~~~^~~~
error: fatalError

Environment

  • Swift compiler version info: Apple Swift version 5.9-dev (LLVM 91de708cf253c77, Swift cfd070f)
  • Xcode version info Xcode: 15.0 Build version 15A5229m
  • Deployment target: arm64-apple-macosx13.0

Metadata

Metadata

Assignees

Labels

assignmentsFeature → expressions: assignmentsbugA deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itselfexpressionsFeature: expressionsfunction typesFeature → types: function typesgenericsFeature: generic declarations and typesparameter packsFeature → generics: Parameter packspropertiesFeature: propertiesswift 6.0type checkerArea → compiler: Semantic analysistypesFeature: typesunexpected errorBug: Unexpected error

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions