Skip to content

Commit 01b5a9d

Browse files
committed
[DI] TypeWrappers: Support conformance requirements on Wrapper/Storage parameters
1 parent 4a0f9ca commit 01b5a9d

File tree

3 files changed

+64
-9
lines changed

3 files changed

+64
-9
lines changed

lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,15 +1315,24 @@ void LifetimeChecker::injectTypeWrapperStorageInitalization() {
13151315
wrapperInitArgs.push_back(storageObj);
13161316
wrapperInitArgs.push_back(typeWrapperType);
13171317

1318-
// <wrapper-var> = <TypeWrapper>.init(storage: tmpStorage)
1319-
auto wrapperInitResult = b.createApply(
1320-
loc, typeWrapperInitRef,
1321-
SubstitutionMap::get(typeWrapperInit->getGenericSignature(),
1322-
/*substitutions=*/
1323-
{wrappedType->getMetatypeInstanceType(),
1324-
storageType.getASTType()},
1325-
/*conformances=*/{}),
1326-
wrapperInitArgs);
1318+
TypeSubstitutionMap wrapperInitSubs;
1319+
{
1320+
auto sig =
1321+
typeWrapperInit->getGenericSignature().getCanonicalSignature();
1322+
wrapperInitSubs[sig.getGenericParams()[0]] =
1323+
wrappedType->getMetatypeInstanceType();
1324+
wrapperInitSubs[sig.getGenericParams()[1]] = storageType.getASTType();
1325+
}
1326+
1327+
// <wrapper-var> = <TypeWrapper>.init(for: <Type>, storage: tmpStorage)
1328+
auto wrapperInitResult =
1329+
b.createApply(loc, typeWrapperInitRef,
1330+
SubstitutionMap::get(
1331+
typeWrapperInit->getGenericSignature(),
1332+
QueryTypeSubstitutionMap{wrapperInitSubs},
1333+
LookUpConformanceInModule(
1334+
ctor->getDeclContext()->getParentModule())),
1335+
wrapperInitArgs);
13271336

13281337
// self.$storage is a property access so it has to has to be wrapped
13291338
// in begin/end access instructions.

test/Interpreter/Inputs/type_wrapper_defs.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,3 +419,35 @@ public struct PropWrapperWithDefaultInit<T> {
419419
self.value = wrappedValue
420420
}
421421
}
422+
423+
@typeWrapper
424+
public struct WrapperWithConformance<W : WrappedTypesOnly, S> {
425+
var underlying: S
426+
427+
public init(for wrappedType: W.Type, storage: S) {
428+
print("WrapperWithConformance.init(for: \(wrappedType), storage: \(storage))")
429+
self.underlying = storage
430+
}
431+
432+
public subscript<V>(propertyKeyPath propertyPath: KeyPath<W, V>,
433+
storageKeyPath storagePath: KeyPath<S, V>) -> V {
434+
get {
435+
print("in read-only getter storage: \(storagePath)")
436+
return underlying[keyPath: storagePath]
437+
}
438+
}
439+
440+
public subscript<V>(propertyKeyPath propertyPath: KeyPath<W, V>,
441+
storageKeyPath storagePath: WritableKeyPath<S, V>) -> V {
442+
get {
443+
print("in getter storage: \(storagePath)")
444+
return underlying[keyPath: storagePath]
445+
}
446+
set {
447+
print("in setter => \(newValue)")
448+
underlying[keyPath: storagePath] = newValue
449+
}
450+
}
451+
}
452+
453+
public protocol WrappedTypesOnly {}

test/Interpreter/type_wrappers.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,3 +710,17 @@ do {
710710
// CHECK-NEXT: in (reference type) getter storage: \$Storage._x
711711
// CHECK-NEXT: 42
712712
}
713+
714+
do {
715+
@WrapperWithConformance
716+
struct Test : WrappedTypesOnly {
717+
var a: Int = 42
718+
var b: String = ""
719+
@PropWrapperWithDefaultInit var c: [Int]
720+
721+
init() {}
722+
}
723+
724+
let test = Test()
725+
// CHECK: WrapperWithConformance.init(for: Test, storage: $Storage(a: 42, b: "", _c: type_wrapper_defs.PropWrapperWithDefaultInit<Swift.Array<Swift.Int>>(value: nil)))
726+
}

0 commit comments

Comments
 (0)