Skip to content

Commit 8db8f0c

Browse files
committed
Sema: Simplify opened existential types in solution
1 parent 59bce81 commit 8db8f0c

File tree

6 files changed

+189
-1
lines changed

6 files changed

+189
-1
lines changed

lib/Sema/CSSolver.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,10 @@ Solution ConstraintSystem::finalize() {
169169
}
170170

171171
// Remember the opened existential types.
172-
for (const auto &openedExistential : OpenedExistentialTypes) {
172+
for (auto &openedExistential : OpenedExistentialTypes) {
173+
openedExistential.second = simplifyType(openedExistential.second)
174+
->castTo<OpenedArchetypeType>();
175+
173176
assert(solution.OpenedExistentialTypes.count(openedExistential.first) == 0||
174177
solution.OpenedExistentialTypes[openedExistential.first]
175178
== openedExistential.second &&

test/Constraints/issue-64621.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
protocol Wrapper<T> {
4+
associatedtype T
5+
6+
func get()
7+
}
8+
9+
func foo<R>(_: R) -> any Wrapper<R> {}
10+
11+
func test() {
12+
foo(0).get()
13+
}

test/Constraints/rdar120791071.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
struct S<A> {
4+
let v:any P<A>
5+
func map<B> (_ f:(A) -> B) -> S<B> {
6+
v.map(f).k()
7+
}
8+
}
9+
10+
protocol P<A> {
11+
associatedtype A
12+
func map<D> (_ g:(A) -> D) -> any P<D>
13+
func k() -> S<A>
14+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// RUN: %target-swift-frontend -emit-ir %s
2+
3+
protocol Context: Sendable {}
4+
5+
protocol Service<ServiceContext> {
6+
associatedtype ServiceContext: Context
7+
}
8+
9+
protocol Builder<BuilderContext> {
10+
associatedtype BuilderContext: Context
11+
12+
init(context: BuilderContext?)
13+
14+
func withContextReducer(
15+
reducer: @escaping @Sendable (_ context: BuilderContext?) async -> BuilderContext?
16+
) -> Self
17+
18+
19+
func build() -> Result<any Service<BuilderContext>, Error>
20+
}
21+
22+
final actor ServiceImplementation<ServiceContext: Context>: Service {
23+
var currentContext: ServiceContext?
24+
25+
init(initialContext: ServiceContext?) {
26+
currentContext = initialContext
27+
}
28+
}
29+
30+
final class BuilderImplementation<BuilderContext: Context>: Builder {
31+
var initialContext: BuilderContext? = nil
32+
33+
init(context: BuilderContext?) {
34+
initialContext = context
35+
}
36+
37+
func withContextReducer(
38+
reducer: @escaping @Sendable (_ context: BuilderContext?) async -> BuilderContext?
39+
) -> Self {
40+
return self
41+
}
42+
43+
func build() -> Result<any Service<BuilderContext>, Error> {
44+
return .success(
45+
ServiceImplementation(
46+
initialContext: initialContext
47+
)
48+
)
49+
}
50+
}
51+
52+
enum BuilderFactory {
53+
// The generic parameter here makes the swift compiler crash
54+
static func create<T: Context>(context: T?) -> any Builder<T> {
55+
return BuilderImplementation(context: context)
56+
}
57+
}
58+
59+
60+
struct DemoContext: Context {
61+
let someValue: Int?
62+
63+
public init(someValue: Int? = nil) {
64+
self.someValue = someValue
65+
}
66+
}
67+
68+
public func testBuilding() {
69+
let builderResult: Result<any Service<DemoContext>, Error> = BuilderFactory.create(context: DemoContext())
70+
.withContextReducer(
71+
reducer: { (context: DemoContext?) -> DemoContext? in context }
72+
)
73+
.build()
74+
}
75+
76+
testBuilding()
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// RUN: %target-swift-frontend -emit-ir %s
2+
3+
public protocol P1 {}
4+
5+
public protocol P2 {
6+
associatedtype A1
7+
var id: String { get }
8+
}
9+
10+
public protocol P3<A2> {
11+
associatedtype A2
12+
func execute() -> A2
13+
}
14+
15+
public protocol P4<A3>: P3 {
16+
associatedtype A3: P1
17+
}
18+
19+
public protocol P5<A3>: P4 {}
20+
21+
public protocol P6 {
22+
func insert<A3: P1>(id: String, _ value: A3, replace: Bool) -> any P5<A3>
23+
func remove<A4: P2>(with key: A4) where A4.A1: P1
24+
}
25+
26+
extension P6 {
27+
public func persist<A4: P2>(_ value: A4.A1?, for key: A4) where A4.A1: P1 {
28+
guard let value else {
29+
self.remove(with: key)
30+
return
31+
}
32+
33+
_ = self.insert(id: key.id, value).execute()
34+
}
35+
36+
public func insert<A3: P1>(id: String, _ value: A3) -> any P5<A3> {
37+
self.insert(id: id, value, replace: true)
38+
}
39+
}
40+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// RUN: %target-swift-frontend -emit-ir %s
2+
3+
public typealias OnValue<Value> = () -> Value
4+
5+
public protocol SubjectProtocol<Value> {
6+
associatedtype Value
7+
8+
func value() -> Value
9+
func onValue(_ onValue: @escaping OnValue<Value>) -> any SubjectProtocol<Value>
10+
}
11+
12+
class Subject<Value>: SubjectProtocol {
13+
var _onValue: OnValue<Value>?
14+
15+
init(_ onValue: OnValue<Value>?) {
16+
self._onValue = onValue
17+
}
18+
19+
func value() -> Value {
20+
if let onValue = self._onValue {
21+
return onValue()
22+
} else {
23+
fatalError("Require Implementation")
24+
}
25+
}
26+
27+
func onValue(_ onValue: @escaping OnValue<Value>) -> any SubjectProtocol<Value> {
28+
let subject = Subject(self._onValue)
29+
subject._onValue = onValue
30+
31+
return subject
32+
}
33+
}
34+
35+
public func ExistentialSubject<Value>() -> any SubjectProtocol<Value> {
36+
Subject(nil)
37+
}
38+
39+
public func DebugSubject() {
40+
ExistentialSubject().onValue { 0 }
41+
}
42+

0 commit comments

Comments
 (0)