Files
swift-mirror/test/SILGen/keypaths_resilient_generic.swift
Slava Pestov 10c37c6565 SILGen: Work around for stored property keypath components not supporting generic resilient classes
A keypath component for a stored property can take one of several forms:

- The property offset is known to be constant at compile-time.

  This is used in the simplest cases for classes and structs.

- The property offset is not constant, but can be loaded from a global.

  This is used for classes that require runtime resilient layout, but where
  the offsets do not depend on the generic context.

- The property offset is not constant, and must be loaded from metadata.

  This is the case where the offset depends on the generic context. Here,
  we were only set up to load it from a fixed offset in the metadata.
  This works for generic structs, or generic classes where the superclass
  chain does not cross a resilience boundary.

  However, if a resilience boundary is crossed, the offset of the field
  offset in the metadata must itself be obtained at runtime by adding a
  constant to a value loaded from a global. This case is not supported by
  the current keypath ABI due to an oversight.

I filed <rdar://problem/59777983> to track extending the ABI to handle
this more elegantly in the future.

Fixes <rdar://problem/59617119>.
2020-02-25 16:39:50 -05:00

31 lines
1.8 KiB
Swift

// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -emit-module -enable-library-evolution -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift
// RUN: %target-swift-frontend -emit-module -enable-library-evolution -emit-module-path=%t/resilient_class.swiftmodule -module-name=resilient_class -I %t %S/../Inputs/resilient_class.swift
// RUN: %target-swift-emit-silgen %s -I %t -enable-library-evolution | %FileCheck %s
import resilient_class
open class MySubclass<T> : ResilientOutsideParent {
public final var storedProperty: T? = nil
}
open class ConcreteSubclass : MySubclass<Int> {
public final var anotherStoredProperty: Int? = nil
}
// CHECK-LABEL: sil shared [thunk] [ossa] @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTK : $@convention(thin) <T> (@in_guaranteed MySubclass<T>) -> @out Optional<T> {
// CHECK-LABEL: sil shared [thunk] [ossa] @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTk : $@convention(thin) <T> (@in_guaranteed Optional<T>, @in_guaranteed MySubclass<T>) -> () {
// CHECK: sil_property #MySubclass.storedProperty<τ_0_0> (
// CHECK-SAME: settable_property $Optional<τ_0_0>,
// CHECK-SAME: id ##MySubclass.storedProperty,
// CHECK-SAME: getter @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTK : $@convention(thin) <τ_0_0> (@in_guaranteed MySubclass<τ_0_0>) -> @out Optional<τ_0_0>,
// CHECK-SAME: setter @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTk : $@convention(thin) <τ_0_0> (@in_guaranteed Optional<τ_0_0>, @in_guaranteed MySubclass<τ_0_0>) -> ()
// CHECK-SAME: )
// CHECK: sil_property #ConcreteSubclass.anotherStoredProperty (
// CHECK-SAME: stored_property #ConcreteSubclass.anotherStoredProperty : $Optional<Int>
// CHECK-SAME: )