Fix SILGenFunction::emitValueConstructor for library evolution.

Always call createMarkUnresolvedNonCopyableValueInst for a constructor
with move-only 'self'. Handle 'self' that is either returned by value
or as an indirect result

Fixes rdar://142690658 (In ~Copyable public struct,
an init with COW type param causes compiler error)
This commit is contained in:
Andrew Trick
2025-01-10 16:21:04 -08:00
parent eb07814abd
commit fe075dcb29
2 changed files with 19 additions and 7 deletions

View File

@@ -773,15 +773,14 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) {
auto cleanupLoc = CleanupLocation(ctor);
if (selfLV.getType().isMoveOnly()) {
selfLV = B.createMarkUnresolvedNonCopyableValueInst(
cleanupLoc, selfLV,
MarkUnresolvedNonCopyableValueInst::CheckKind::
AssignableButNotConsumable);
}
if (!F.getConventions().hasIndirectSILResults()) {
// Otherwise, load and return the final 'self' value.
if (selfLV.getType().isMoveOnly()) {
selfLV = B.createMarkUnresolvedNonCopyableValueInst(
cleanupLoc, selfLV,
MarkUnresolvedNonCopyableValueInst::CheckKind::
AssignableButNotConsumable);
}
selfValue = lowering.emitLoad(B, cleanupLoc, selfLV.getValue(),
LoadOwnershipQualifier::Copy);

View File

@@ -106,3 +106,16 @@ func useUsableFromInlineTestKlass() {
let k = UsableFromInlineTestKlass()
k.e = E()
}
// rdar://142690658 (In ~Copyable public struct, an init with COW type param causes compiler error)
//
// CHECK-LABEL: sil hidden [ossa] @$s26moveonly_library_evolution19NonCopyableWithInitV1sACSS_tcfC :
// CHECK-SAME: $@convention(method) (@owned String, @thin NonCopyableWithInit.Type) -> @out NonCopyableWithInit {
// CHECK: bb0(%0 : $*NonCopyableWithInit, %1 : @owned $String, %2 : $@thin NonCopyableWithInit.Type):
// CHECK: [[BOX:%.*]] = project_box %{{.*}}, 0
// CHECK: store %{{.*}} to [init] [[BOX]]
// CHECK: [[MD:%.*]] = mark_unresolved_non_copyable_value [assignable_but_not_consumable] [[BOX]]
// CHECK: copy_addr [[MD]] to [init] %0
public struct NonCopyableWithInit: ~Copyable {
init(s: String) {}
}