diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp index 187df508fa854..e6e56bfc75715 100644 --- a/lib/IRGen/GenMeta.cpp +++ b/lib/IRGen/GenMeta.cpp @@ -3391,15 +3391,18 @@ static void emitInitializeValueMetadata(IRGenFunction &IGF, MetadataDependencyCollector *collector) { auto &IGM = IGF.IGM; auto loweredTy = IGM.getLoweredType(nominalDecl->getDeclaredTypeInContext()); + auto &concreteTI = IGM.getTypeInfo(loweredTy); + bool useLayoutStrings = layoutStringsEnabled(IGM) && IGM.Context.LangOpts.hasFeature( Feature::LayoutStringValueWitnessesInstantiation) && - IGM.getOptions().EnableLayoutStringValueWitnessesInstantiation; + IGM.getOptions().EnableLayoutStringValueWitnessesInstantiation && + concreteTI.isCopyable(ResilienceExpansion::Maximal); if (auto sd = dyn_cast(nominalDecl)) { - auto &fixedTI = IGM.getTypeInfo(loweredTy); - if (isa(fixedTI)) return; + if (isa(concreteTI)) + return; // Use a different runtime function to initialize the value witness table // if the struct has a raw layout. The existing swift_initStructMetadata diff --git a/lib/IRGen/GenValueWitness.cpp b/lib/IRGen/GenValueWitness.cpp index 82e8a62edfbe2..ef71f2cfb7588 100644 --- a/lib/IRGen/GenValueWitness.cpp +++ b/lib/IRGen/GenValueWitness.cpp @@ -1059,7 +1059,8 @@ static void addValueWitness(IRGenModule &IGM, ConstantStructBuilder &B, return addFunction(getNoOpVoidFunction(IGM)); } else if (concreteTI.isSingleSwiftRetainablePointer(ResilienceExpansion::Maximal)) { return addFunction(getDestroyStrongFunction(IGM)); - } else if (layoutStringsEnabled(IGM)) { + } else if (layoutStringsEnabled(IGM) && + concreteTI.isCopyable(ResilienceExpansion::Maximal)) { auto ty = boundGenericCharacteristics ? boundGenericCharacteristics->concreteType : concreteType; auto &typeInfo = boundGenericCharacteristics ? *boundGenericCharacteristics->TI : concreteTI; if (auto *typeLayoutEntry = @@ -1083,7 +1084,8 @@ static void addValueWitness(IRGenModule &IGM, ConstantStructBuilder &B, } } - if (layoutStringsEnabled(IGM)) { + if (layoutStringsEnabled(IGM) && + concreteTI.isCopyable(ResilienceExpansion::Maximal)) { auto ty = boundGenericCharacteristics ? boundGenericCharacteristics->concreteType : concreteType; @@ -1106,7 +1108,8 @@ static void addValueWitness(IRGenModule &IGM, ConstantStructBuilder &B, case ValueWitness::InitializeWithTake: if (concreteTI.isBitwiseTakable(ResilienceExpansion::Maximal)) { return addFunction(getMemCpyFunction(IGM, concreteTI)); - } else if (layoutStringsEnabled(IGM)) { + } else if (layoutStringsEnabled(IGM) && + concreteTI.isCopyable(ResilienceExpansion::Maximal)) { auto ty = boundGenericCharacteristics ? boundGenericCharacteristics->concreteType : concreteType; auto &typeInfo = boundGenericCharacteristics ? *boundGenericCharacteristics->TI : concreteTI; if (auto *typeLayoutEntry = @@ -1126,7 +1129,8 @@ static void addValueWitness(IRGenModule &IGM, ConstantStructBuilder &B, return addFunction(getMemCpyFunction(IGM, concreteTI)); } else if (concreteTI.isSingleSwiftRetainablePointer(ResilienceExpansion::Maximal)) { return addFunction(getAssignWithCopyStrongFunction(IGM)); - } else if (layoutStringsEnabled(IGM)) { + } else if (layoutStringsEnabled(IGM) && + concreteTI.isCopyable(ResilienceExpansion::Maximal)) { auto ty = boundGenericCharacteristics ? boundGenericCharacteristics->concreteType : concreteType; auto &typeInfo = boundGenericCharacteristics ? *boundGenericCharacteristics->TI : concreteTI; if (auto *typeLayoutEntry = @@ -1146,7 +1150,8 @@ static void addValueWitness(IRGenModule &IGM, ConstantStructBuilder &B, return addFunction(getMemCpyFunction(IGM, concreteTI)); } else if (concreteTI.isSingleSwiftRetainablePointer(ResilienceExpansion::Maximal)) { return addFunction(getAssignWithTakeStrongFunction(IGM)); - } else if (layoutStringsEnabled(IGM)) { + } else if (layoutStringsEnabled(IGM) && + concreteTI.isCopyable(ResilienceExpansion::Maximal)) { auto ty = boundGenericCharacteristics ? boundGenericCharacteristics->concreteType : concreteType; auto &typeInfo = boundGenericCharacteristics ? *boundGenericCharacteristics->TI : concreteTI; if (auto *typeLayoutEntry = @@ -1166,7 +1171,8 @@ static void addValueWitness(IRGenModule &IGM, ConstantStructBuilder &B, return addFunction(getMemCpyFunction(IGM, concreteTI)); } else if (concreteTI.isSingleSwiftRetainablePointer(ResilienceExpansion::Maximal)) { return addFunction(getInitWithCopyStrongFunction(IGM)); - } else if (layoutStringsEnabled(IGM)) { + } else if (layoutStringsEnabled(IGM) && + concreteTI.isCopyable(ResilienceExpansion::Maximal)) { auto ty = boundGenericCharacteristics ? boundGenericCharacteristics->concreteType : concreteType; auto &typeInfo = boundGenericCharacteristics ? *boundGenericCharacteristics->TI : concreteTI; if (auto *typeLayoutEntry = @@ -1233,7 +1239,8 @@ static void addValueWitness(IRGenModule &IGM, ConstantStructBuilder &B, case ValueWitness::GetEnumTag: { assert(concreteType.getEnumOrBoundGenericEnum()); - if (layoutStringsEnabled(IGM)) { + if (layoutStringsEnabled(IGM) && + concreteTI.isCopyable(ResilienceExpansion::Maximal)) { auto ty = boundGenericCharacteristics ? boundGenericCharacteristics->concreteType : concreteType; @@ -1255,7 +1262,8 @@ static void addValueWitness(IRGenModule &IGM, ConstantStructBuilder &B, } case ValueWitness::DestructiveInjectEnumTag: { assert(concreteType.getEnumOrBoundGenericEnum()); - if (layoutStringsEnabled(IGM)) { + if (layoutStringsEnabled(IGM) && + concreteTI.isCopyable(ResilienceExpansion::Maximal)) { auto ty = boundGenericCharacteristics ? boundGenericCharacteristics->concreteType : concreteType; diff --git a/test/IRGen/layout_string_witnesses_noncopyable.swift b/test/IRGen/layout_string_witnesses_noncopyable.swift new file mode 100644 index 0000000000000..8e9b30364d90a --- /dev/null +++ b/test/IRGen/layout_string_witnesses_noncopyable.swift @@ -0,0 +1,31 @@ +// RUN: %target-swift-frontend -enable-experimental-feature LayoutStringValueWitnesses -enable-experimental-feature LayoutStringValueWitnessesInstantiation -enable-layout-string-value-witnesses -enable-layout-string-value-witnesses-instantiation -emit-ir -module-name Foo %s | %FileCheck %s + +// CHECK-NOT: @"$s3Foo7GenericVWV" = {{.*}}ptr @swift_generic{{.*$}} +struct Generic: ~Copyable { + let x: T + let y: Int +} + +// CHECK-NOT: @"$s3Foo13SinglePayloadOWV" = {{.*}}ptr @swift_generic{{.*$}} +enum SinglePayload: ~Copyable { + case x(AnyObject) + case y +} + +// CHECK-NOT: @"$s3Foo12MultiPayloadOWV" = {{.*}}ptr @swift_generic{{.*$}} +enum MultiPayload: ~Copyable { + case x(AnyObject) + case y(AnyObject) +} + +// CHECK-NOT: @"$s3Foo20SinglePayloadGenericOWV" = {{.*}}ptr @swift_generic{{.*$}} +enum SinglePayloadGeneric: ~Copyable { + case x(T) + case y +} + +// CHECK-NOT: @"$s3Foo19MultiPayloadGenericOWV" = {{.*}}ptr @swift_generic{{.*$}} +enum MultiPayloadGeneric: ~Copyable { + case x(T) + case y(T) +}