mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
SIL: Fix signature of reabstraction thunk involving parameterized existential
Fixes https://github.com/swiftlang/swift/issues/74569 Fixes rdar://problem/130402282
This commit is contained in:
@@ -136,7 +136,7 @@ GenericSignature swift::buildGenericSignatureWithCapturedEnvironments(
|
||||
case GenericEnvironment::Kind::OpenedExistential: {
|
||||
auto constraint = genericEnv->getOpenedExistentialType();
|
||||
if (auto existential = constraint->getAs<ExistentialType>())
|
||||
constraint = existential->getConstraintType();
|
||||
constraint = existential->getConstraintType()->mapTypeOutOfContext();
|
||||
collector.addOpenedExistential(constraint);
|
||||
continue;
|
||||
}
|
||||
|
||||
15
test/SILGen/parameterized_existentials_reabstraction.swift
Normal file
15
test/SILGen/parameterized_existentials_reabstraction.swift
Normal file
@@ -0,0 +1,15 @@
|
||||
// RUN: %target-swift-emit-silgen -disable-availability-checking %s | %FileCheck %s
|
||||
|
||||
protocol P<A> {
|
||||
associatedtype A
|
||||
associatedtype B
|
||||
var function: () -> B { get }
|
||||
}
|
||||
|
||||
func f<A>(p: any P<A>) {
|
||||
_ = p.function()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil hidden [ossa] @$s40parameterized_existentials_reabstraction1f1pyAA1P_px1ARts_XP_tlF : $@convention(thin) <A> (@in_guaranteed any P<A>) -> () {
|
||||
|
||||
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s1B40parameterized_existentials_reabstraction1PPQyd__Iegr_ypIegr_1AQyd__RszAbCRd__r__lTR : $@convention(thin) <τ_0_0><τ_1_0 where τ_0_0 == τ_1_0.A, τ_1_0 : P> (@guaranteed @callee_guaranteed () -> @out τ_1_0.B) -> @out Any {
|
||||
14
validation-test/compiler_crashers_2_fixed/issue-74569.swift
Normal file
14
validation-test/compiler_crashers_2_fixed/issue-74569.swift
Normal file
@@ -0,0 +1,14 @@
|
||||
// RUN: %target-swift-frontend -emit-ir %s -disable-availability-checking
|
||||
|
||||
protocol Cache<Object> {
|
||||
associatedtype Object
|
||||
associatedtype Snapshot: Sequence<Object>
|
||||
|
||||
func entries(_ body: (Snapshot) -> Void) -> AsyncStream<Object>
|
||||
}
|
||||
|
||||
func readFromCacheImpl<T>(cache: any Cache<T>) async {
|
||||
let updateStream = cache.entries { _ in }
|
||||
|
||||
for await _ in updateStream {}
|
||||
}
|
||||
61
validation-test/compiler_crashers_2_fixed/issue-74729.swift
Normal file
61
validation-test/compiler_crashers_2_fixed/issue-74729.swift
Normal file
@@ -0,0 +1,61 @@
|
||||
// RUN: %target-swift-frontend -emit-ir %s -disable-availability-checking
|
||||
|
||||
protocol ContextDescriptor: Sendable { }
|
||||
|
||||
protocol OutcomeDescriptor: Sendable { }
|
||||
|
||||
protocol ResultDescriptor: Sendable { }
|
||||
|
||||
protocol ErasedReducer<Context>: Sendable {
|
||||
associatedtype Context: ContextDescriptor
|
||||
associatedtype TriggerOutcome: OutcomeDescriptor
|
||||
associatedtype Result: ResultDescriptor
|
||||
|
||||
var name: String { get }
|
||||
var function: @Sendable (_ context: Context?, _ trigger: TriggerOutcome) -> Result { get }
|
||||
}
|
||||
|
||||
protocol Reducer<Context, TriggerOutcome>: ErasedReducer {
|
||||
var name: String { get }
|
||||
var function: @Sendable (_ context: Context?, _ trigger: TriggerOutcome) -> Result { get }
|
||||
}
|
||||
|
||||
struct ExampleContext: ContextDescriptor { }
|
||||
|
||||
struct ExampleOutcome: OutcomeDescriptor { }
|
||||
|
||||
struct ExampleResult: ResultDescriptor { }
|
||||
|
||||
struct ExampleReducer<Context: ContextDescriptor, TriggerOutcome: OutcomeDescriptor, Result: ResultDescriptor>: Reducer {
|
||||
let name: String
|
||||
let function: @Sendable (_ context: Context?, _ trigger: TriggerOutcome) -> Result
|
||||
}
|
||||
|
||||
class ExampleService<Context: ContextDescriptor> {
|
||||
let reducers: [any ErasedReducer<Context>]
|
||||
|
||||
public init(reducers: [any ErasedReducer<Context>]) {
|
||||
self.reducers = reducers
|
||||
}
|
||||
|
||||
func reduce<TriggerOutcome: OutcomeDescriptor>(outcome: TriggerOutcome, context: Context) -> (any ResultDescriptor)? {
|
||||
// This line appears to be what's causing the crash
|
||||
guard let reducer = (reducers.compactMap { reducer in reducer as? any Reducer<Context, TriggerOutcome> }).first else {
|
||||
return nil
|
||||
}
|
||||
return reducer.function(context, outcome)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public func testReducing() {
|
||||
let erasedReducers: [any ErasedReducer<ExampleContext>] = [
|
||||
ExampleReducer<ExampleContext, ExampleOutcome, ExampleResult>(name: "Example", function: { (_, _) in ExampleResult() })
|
||||
]
|
||||
let context = ExampleContext()
|
||||
let trigger = ExampleOutcome()
|
||||
|
||||
let service = ExampleService<ExampleContext>(reducers: erasedReducers)
|
||||
|
||||
_ = service.reduce(outcome: trigger, context: context)
|
||||
}
|
||||
Reference in New Issue
Block a user