Skip to content

Emit reflection metadata for noncopyable fields more often #72163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion lib/IRGen/GenReflection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,10 +411,28 @@ getTypeRefImpl(IRGenModule &IGM,
// signal from future runtimes whether they support noncopyable types before
// exposing their metadata to them.
Type contextualTy = type;
if (sig)
if (sig) {
contextualTy = sig.getGenericEnvironment()->mapTypeIntoContext(type);
}

bool isAlwaysNoncopyable = false;
if (contextualTy->isNoncopyable()) {
// If the contextual type has any archetypes in it, it's plausible that
// we could end up with a copyable type in some instances. Look for those.
if (contextualTy->hasArchetype()) {
// If this is a nominal type, check whether it can ever be copyable.
if (auto nominal = contextualTy->getAnyNominal()) {
if (!nominal->canBeCopyable())
isAlwaysNoncopyable = true;
} else {
// Assume that we could end up with a copyable type somehow.
}
} else {
isAlwaysNoncopyable = true;
}
}

if (isAlwaysNoncopyable) {
IGM.IRGen.noteUseOfTypeMetadata(type);
return getTypeRefByFunction(IGM, sig, type);
}
Expand Down
38 changes: 38 additions & 0 deletions test/IRGen/noncopyable_field_descriptors.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -emit-ir -o - %s -module-name test \
// RUN: -enable-experimental-feature NoncopyableGenerics \
// RUN: -enable-experimental-feature NonescapableTypes \
// RUN: -parse-as-library \
// RUN: -enable-library-evolution \
// RUN: > %t/test.irgen

// RUN: %FileCheck %s < %t/test.irgen

@frozen
public enum ConditionallyCopyable<Wrapped: ~Copyable>: ~Copyable {
case none
case some(Wrapped)
}

extension ConditionallyCopyable: Copyable where Wrapped: Copyable { }

@frozen
public enum NeverCopyable<Wrapped: ~Copyable>: ~Copyable {
case none
case some(Wrapped)
}

@frozen
public struct NonCopyable: ~Copyable { }

// CHECK: @"$s4test1CCMF" =
// CHECK-SAME: @"symbolic _____yxG 4test21ConditionallyCopyableOAARiczrlE"
// CHECK-SAME: @"get_type_metadata Riczl4test21ConditionallyCopyableOyAA03NonC0VG.3"
// CHECK-SAME: @"symbolic _____yxG 4test21ConditionallyCopyableOAARiczrlE"
// CHECK-SAME: @"get_type_metadata Riczl4test21ConditionallyCopyableOyAA03NonC0VG.3"
public class C<T: ~Copyable> {
var ccT: ConditionallyCopyable<T> = .none
var ccNC: ConditionallyCopyable<NonCopyable> = .none
var ncT: ConditionallyCopyable<T> = .none
var ncNC: ConditionallyCopyable<NonCopyable> = .none
}