Skip to content

Sema: Associated type inference regressions, round 4 #71575

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

Merged
merged 4 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
890 changes: 672 additions & 218 deletions lib/Sema/AssociatedTypeInference.cpp

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion test/Generics/associated_type_where_clause.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %target-typecheck-verify-swift -swift-version 4
// RUN: %target-typecheck-verify-swift -swift-version 4 -enable-experimental-associated-type-inference
// RUN: %target-typecheck-verify-swift -swift-version 4 -disable-experimental-associated-type-inference

func needsSameType<T>(_: T.Type, _: T.Type) {}

Expand Down
3 changes: 2 additions & 1 deletion test/Sema/where_clause_across_module_boundaries.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -emit-module -o %t/ModuleA.swiftmodule %S/Inputs/where_clause_across_module_boundaries_module.swift
// RUN: %target-typecheck-verify-swift -I %t
// RUN: %target-typecheck-verify-swift -I %t -enable-experimental-associated-type-inference
// RUN: %target-typecheck-verify-swift -I %t -disable-experimental-associated-type-inference

// https://github.com/apple/swift/issues/58084
// Associated Type Inference fails across module boundaries
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %target-typecheck-verify-swift
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
// RUN: not %target-typecheck-verify-swift -disable-experimental-associated-type-inference

protocol Q {}

Expand Down
103 changes: 99 additions & 4 deletions test/decl/protocol/req/associated_type_inference_stdlib_4.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,107 @@
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA1
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA2
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA3
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA4
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA5
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA6
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA7
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA8
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA9
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA10
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA11
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA12
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA13
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA14

// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA1
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA2
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA3
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA4
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA5
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA6
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA7
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA8
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA9
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA10
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA11
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA12
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA13
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA14

#if A1

// The 'for' loop has to come first, to force Sequence.makeIterator().
for x in S() { _ = x }

#elseif A2

func f<T: Sequence>(_: T.Type) -> T.Element.Type { fatalError() }
let x: String.Type = f(S.self)

#elseif A3

func f<T: Sequence>(_: T.Type) -> T.Iterator.Type { fatalError() }
let x: IndexingIterator<S>.Type = f(S.self)

#elseif A4

func f<T: Sequence>(_: T.Type) -> T.Iterator.Element.Type { fatalError() }
let x: String.Type = f(S.self)

#elseif A5

func f<T: Collection>(_: T.Type) -> T.Element.Type { fatalError() }
let x: String.Type = f(S.self)

#elseif A6

func f<T: Collection>(_: T.Type) -> T.Index.Type { fatalError() }
let x: Int.Type = f(S.self)

#elseif A7

func f<T: Collection>(_: T.Type) -> T.SubSequence.Type { fatalError() }
let x: Slice<S>.Type = f(S.self)

#elseif A8

func f<T: Collection>(_: T.Type) -> T.SubSequence.Element.Type { fatalError() }
let x: String.Type = f(S.self)

#elseif A9

func f<T: Collection>(_: T.Type) -> T.SubSequence.Index.Type { fatalError() }
let x: Int.Type = f(S.self)

#elseif A10

func f<T: Collection>(_: T.Type) -> T.SubSequence.Iterator.Type { fatalError() }
let x: IndexingIterator<Slice<S>>.Type = f(S.self)

#elseif A11

func f<T: Collection>(_: T.Type) -> T.Indices.Type { fatalError() }
let x: Range<Int>.Type = f(S.self)

#elseif A12

func f<T: Collection>(_: T.Type) -> T.Indices.Element.Type { fatalError() }
let x: Int.Type = f(S.self)

#elseif A13

func f<T: Collection>(_: T.Type) -> T.Indices.SubSequence.Type { fatalError() }
let x: Range<Int>.Type = f(S.self)

#elseif A14

func f<T: Collection>(_: T.Type) -> T.SubSequence.Indices.Type { fatalError() }
let x: Range<Int>.Type = f(S.self)

#endif

struct S: RandomAccessCollection {
public var startIndex: Int { 0 }
public var endIndex: Int { 0 }
public subscript(position: Int) -> Int { 0 }
public subscript(position: Int) -> String { "" }
}

106 changes: 106 additions & 0 deletions test/decl/protocol/req/associated_type_inference_stdlib_4a.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA1
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA2
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA3
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA4
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA5
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA6
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA7
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA8
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA9
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA10
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA11
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA12
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA13
// RUN: %target-swift-frontend -emit-silgen %s -disable-experimental-associated-type-inference -DA14

// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA1
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA2
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA3
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA4
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA5
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA6
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA7
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA8
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA9
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA10
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA11
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA12
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA13
// RUN: %target-swift-frontend -emit-silgen %s -enable-experimental-associated-type-inference -DA14

#if A1

for x in G<String>() { _ = x }

#elseif A2

func f<T: Sequence>(_: T.Type) -> T.Element.Type { fatalError() }
let x: String.Type = f(G<String>.self)

#elseif A3

func f<T: Sequence>(_: T.Type) -> T.Iterator.Type { fatalError() }
let x: IndexingIterator<G<String>>.Type = f(G<String>.self)

#elseif A4

func f<T: Sequence>(_: T.Type) -> T.Iterator.Element.Type { fatalError() }
let x: String.Type = f(G<String>.self)

#elseif A5

func f<T: Collection>(_: T.Type) -> T.Element.Type { fatalError() }
let x: String.Type = f(G<String>.self)

#elseif A6

func f<T: Collection>(_: T.Type) -> T.Index.Type { fatalError() }
let x: Int.Type = f(G<String>.self)

#elseif A7

func f<T: Collection>(_: T.Type) -> T.SubSequence.Type { fatalError() }
let x: Slice<G<String>>.Type = f(G<String>.self)

#elseif A8

func f<T: Collection>(_: T.Type) -> T.SubSequence.Element.Type { fatalError() }
let x: String.Type = f(G<String>.self)

#elseif A9

func f<T: Collection>(_: T.Type) -> T.SubSequence.Index.Type { fatalError() }
let x: Int.Type = f(G<String>.self)

#elseif A10

func f<T: Collection>(_: T.Type) -> T.SubSequence.Iterator.Type { fatalError() }
let x: IndexingIterator<Slice<G<String>>>.Type = f(G<String>.self)

#elseif A11

func f<T: Collection>(_: T.Type) -> T.Indices.Type { fatalError() }
let x: Range<Int>.Type = f(G<String>.self)

#elseif A12

func f<T: Collection>(_: T.Type) -> T.Indices.Element.Type { fatalError() }
let x: Int.Type = f(G<String>.self)

#elseif A13

func f<T: Collection>(_: T.Type) -> T.Indices.SubSequence.Type { fatalError() }
let x: Range<Int>.Type = f(G<String>.self)

#elseif A14

func f<T: Collection>(_: T.Type) -> T.SubSequence.Indices.Type { fatalError() }
let x: Range<Int>.Type = f(G<String>.self)

#endif

struct G<Element>: RandomAccessCollection {
public var startIndex: Int { 0 }
public var endIndex: Int { 0 }
public subscript(position: Int) -> Element { fatalError() }
}
3 changes: 2 additions & 1 deletion test/decl/protocol/req/issue-10831.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %target-typecheck-verify-swift
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
// RUN: not %target-typecheck-verify-swift -disable-experimental-associated-type-inference

struct G<T> {}

Expand Down
10 changes: 8 additions & 2 deletions test/decl/protocol/req/rdar122587920.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference -DNEW
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference -DOLD

struct S<Element> {}

Expand Down Expand Up @@ -27,4 +27,10 @@ extension S: Collection {
}
}

// The old behavior didn't make much sense.

#if NEW
let x: S<Int>.Type = S<Int>.Iterator.self
#elseif OLD
let x: IndexingIterator<S<Int>>.Type = S<Int>.Iterator.self
#endif
35 changes: 35 additions & 0 deletions test/decl/protocol/req/rdar122589094.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference

protocol P1 {
associatedtype A

func f1(_: C) -> A
func f2(_: A, _: C)

typealias C = S1<Self>
}

struct S1<T> {}

protocol P2: P1 where A == B {
associatedtype B

func g1(_: C) -> B
func g2(_: B, _: C)
}

extension P2 {
func f1(_: C) -> B { fatalError() }
func f2(_: B, _: C) { fatalError() }
}

extension P2 {
func g2(_: B, _: C) {}
}

struct S2: P2 {
func g1(_: C) -> Int {
fatalError()
}
}
49 changes: 49 additions & 0 deletions test/decl/protocol/req/rdar122596633-1.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference

public protocol P1 {
associatedtype A = Void

func makeA() -> A
func consumeA(a: inout A)
}

extension P1 where A == Void {
// Don't consider this witness in the 'S2: P1' conformance below.
public func makeA() -> A { fatalError() }
}

public struct S1: P1 {}

public protocol P2: P1 where A == B.A {
associatedtype B: P1
var base: B { get }
}

extension P2 {
public func makeA() -> B.A { fatalError() }
public func consumeA(a: inout B.A) {}
}

extension S1: P2 {
public var base: S2 { fatalError() }
}

public struct S2 {}

public struct S3 {}

extension S2: P1 {
public typealias A = S3
}

public protocol P3: P1 where A == S3 {}

extension P3 {
public func makeA() -> A { fatalError() }
public func consumeA(a: inout A) {}
}

extension S2: P3 {}

let x: S3.Type = S2.A.self
32 changes: 32 additions & 0 deletions test/decl/protocol/req/rdar122596633-2.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// RUN: %target-typecheck-verify-swift -disable-experimental-associated-type-inference -disable-availability-checking
// RUN: %target-typecheck-verify-swift -enable-experimental-associated-type-inference -disable-availability-checking

public protocol P<A> {
associatedtype A
associatedtype B: P

func makeA() -> A
var b: B { get }
}

extension P where A == B.A {
public func makeA() -> B.A {
fatalError()
}
}

public struct S: P {
public var b: some P<Int> {
return G<Int>()
}
}

public struct G<A>: P {
public func makeA() -> A { fatalError() }
public var b: Never { fatalError() }
}

extension Never: P {
public func makeA() -> Never { fatalError() }
public var b: Never { fatalError() }
}