Skip to content

Commit 0ef978a

Browse files
authored
Merge pull request #72163 from DougGregor/noncopyable-field-reflection-heuristic
2 parents ed58b9a + 73552d0 commit 0ef978a

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

lib/IRGen/GenReflection.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,10 +411,28 @@ getTypeRefImpl(IRGenModule &IGM,
411411
// signal from future runtimes whether they support noncopyable types before
412412
// exposing their metadata to them.
413413
Type contextualTy = type;
414-
if (sig)
414+
if (sig) {
415415
contextualTy = sig.getGenericEnvironment()->mapTypeIntoContext(type);
416+
}
416417

418+
bool isAlwaysNoncopyable = false;
417419
if (contextualTy->isNoncopyable()) {
420+
// If the contextual type has any archetypes in it, it's plausible that
421+
// we could end up with a copyable type in some instances. Look for those.
422+
if (contextualTy->hasArchetype()) {
423+
// If this is a nominal type, check whether it can ever be copyable.
424+
if (auto nominal = contextualTy->getAnyNominal()) {
425+
if (!nominal->canBeCopyable())
426+
isAlwaysNoncopyable = true;
427+
} else {
428+
// Assume that we could end up with a copyable type somehow.
429+
}
430+
} else {
431+
isAlwaysNoncopyable = true;
432+
}
433+
}
434+
435+
if (isAlwaysNoncopyable) {
418436
IGM.IRGen.noteUseOfTypeMetadata(type);
419437
return getTypeRefByFunction(IGM, sig, type);
420438
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-ir -o - %s -module-name test \
3+
// RUN: -enable-experimental-feature NoncopyableGenerics \
4+
// RUN: -enable-experimental-feature NonescapableTypes \
5+
// RUN: -parse-as-library \
6+
// RUN: -enable-library-evolution \
7+
// RUN: > %t/test.irgen
8+
9+
// RUN: %FileCheck %s < %t/test.irgen
10+
11+
@frozen
12+
public enum ConditionallyCopyable<Wrapped: ~Copyable>: ~Copyable {
13+
case none
14+
case some(Wrapped)
15+
}
16+
17+
extension ConditionallyCopyable: Copyable where Wrapped: Copyable { }
18+
19+
@frozen
20+
public enum NeverCopyable<Wrapped: ~Copyable>: ~Copyable {
21+
case none
22+
case some(Wrapped)
23+
}
24+
25+
@frozen
26+
public struct NonCopyable: ~Copyable { }
27+
28+
// CHECK: @"$s4test1CCMF" =
29+
// CHECK-SAME: @"symbolic _____yxG 4test21ConditionallyCopyableOAARiczrlE"
30+
// CHECK-SAME: @"get_type_metadata Riczl4test21ConditionallyCopyableOyAA03NonC0VG.3"
31+
// CHECK-SAME: @"symbolic _____yxG 4test21ConditionallyCopyableOAARiczrlE"
32+
// CHECK-SAME: @"get_type_metadata Riczl4test21ConditionallyCopyableOyAA03NonC0VG.3"
33+
public class C<T: ~Copyable> {
34+
var ccT: ConditionallyCopyable<T> = .none
35+
var ccNC: ConditionallyCopyable<NonCopyable> = .none
36+
var ncT: ConditionallyCopyable<T> = .none
37+
var ncNC: ConditionallyCopyable<NonCopyable> = .none
38+
}

0 commit comments

Comments
 (0)