Skip to content

Commit 8569b6e

Browse files
Merge pull request #72108 from nate-chandler/bitwise-copyable/20240305/1
[BitwiseCopyable] Imported type improvements.
2 parents 48fd54d + cf77b9f commit 8569b6e

File tree

4 files changed

+123
-0
lines changed

4 files changed

+123
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7650,6 +7650,10 @@ ERROR(non_bitwise_copyable_type_nonescapable,none,
76507650
"nonescapable type cannot conform to 'BitwiseCopyable'", ())
76517651
ERROR(non_bitwise_copyable_type_cxx_nontrivial,none,
76527652
"non-trivial C++ type cannot conform to 'BitwiseCopyable'", ())
7653+
ERROR(non_bitwise_copyable_c_type_nontrivial,none,
7654+
"type with unrepresentable fields cannot derive conformance to 'BitwiseCopyable'", ())
7655+
NOTE(note_non_bitwise_copyable_c_type_add_attr,none,
7656+
"annotate the type __attribute__((__swift_attr__(\"_BitwiseCopyable\")))",())
76537657
ERROR(non_bitwise_copyable_type_member,none,
76547658
"%select{stored property %2|associated value %2}1 of "
76557659
"'BitwiseCopyable'-conforming %kind3 has non-bitwise-copyable type %0",

lib/ClangImporter/ImportDecl.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8039,6 +8039,30 @@ ClangImporter::Implementation::importSwiftAttrAttributes(Decl *MappedDecl) {
80398039
continue;
80408040
}
80418041

8042+
if (swiftAttr->getAttribute() == "_BitwiseCopyable") {
8043+
if (!SwiftContext.LangOpts.hasFeature(Feature::BitwiseCopyable))
8044+
continue;
8045+
auto *protocol =
8046+
SwiftContext.getProtocol(KnownProtocolKind::BitwiseCopyable);
8047+
auto *nominal = dyn_cast<NominalTypeDecl>(MappedDecl);
8048+
if (!nominal)
8049+
continue;
8050+
auto *module = nominal->getModuleContext();
8051+
// Don't synthesize a conformance if one already exists.
8052+
auto ty = nominal->getDeclaredInterfaceType();
8053+
if (module->lookupConformance(ty, protocol))
8054+
continue;
8055+
auto conformance = SwiftContext.getNormalConformance(
8056+
ty, protocol, nominal->getLoc(), nominal->getDeclContextForModule(),
8057+
ProtocolConformanceState::Complete,
8058+
/*isUnchecked=*/false,
8059+
/*isPreconcurrency=*/false);
8060+
conformance->setSourceKindAndImplyingConformance(
8061+
ConformanceEntryKind::Synthesized, nullptr);
8062+
8063+
nominal->registerProtocolConformance(conformance, /*synthesized=*/true);
8064+
}
8065+
80428066
// Dig out a buffer with the attribute text.
80438067
unsigned bufferID = getClangSwiftAttrSourceBuffer(
80448068
swiftAttr->getAttribute());

lib/Sema/TypeCheckBitwise.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,14 @@ static bool checkBitwiseCopyableInstanceStorage(NominalTypeDecl *nominal,
269269
return true;
270270
}
271271

272+
if (sd && sd->hasUnreferenceableStorage()) {
273+
if (!isImplicit(check)) {
274+
sd->diagnose(diag::non_bitwise_copyable_c_type_nontrivial);
275+
sd->diagnose(diag::note_non_bitwise_copyable_c_type_add_attr);
276+
}
277+
return true;
278+
}
279+
272280
BitwiseCopyableStorageVisitor visitor(nominal, dc, check);
273281

274282
return visitor.visit(nominal, dc) || visitor.invalid;
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend \
5+
// RUN: %t/Downstream.swift \
6+
// RUN: -typecheck -verify \
7+
// RUN: -enable-experimental-feature NonescapableTypes \
8+
// RUN: -enable-experimental-feature BitwiseCopyable \
9+
// RUN: -enable-builtin-module \
10+
// RUN: -debug-diagnostic-names \
11+
// RUN: -import-objc-header %t/Library.h
12+
13+
//--- Library.h
14+
15+
struct Tenple {
16+
int i0;
17+
int i1;
18+
int i2;
19+
int i3;
20+
int i4;
21+
int i5;
22+
int i6;
23+
int i7;
24+
int i8;
25+
int i9;
26+
};
27+
28+
struct Ints128 {
29+
int is[128];
30+
};
31+
32+
struct VoidPointers {
33+
void *p1;
34+
void *p2;
35+
void *p3;
36+
void *p4;
37+
void *p5;
38+
void *p6;
39+
void *p7;
40+
void *p8;
41+
void *p9;
42+
void *p10;
43+
};
44+
45+
struct IntsTrailing {
46+
double d;
47+
float f;
48+
int is[];
49+
};
50+
51+
struct IntsTrailing2 {
52+
double d;
53+
float f;
54+
int is[];
55+
};
56+
57+
struct IntsTrailing3 {
58+
double d;
59+
float f;
60+
int is[];
61+
} __attribute__((__swift_attr__("_BitwiseCopyable")));
62+
63+
//--- Downstream.swift
64+
65+
func take<T : _BitwiseCopyable>(_ t: T) {}
66+
67+
func passTenple(_ t: Tenple) { take(t) }
68+
func passInts128(_ t: Ints128) {
69+
take(t)
70+
take(t.is.0)
71+
take(t.is.17)
72+
}
73+
func passVoidPointers(_ t: VoidPointers) {
74+
take(t)
75+
take(t.p10)
76+
}
77+
func passIntsTrailing(_ t: IntsTrailing) {
78+
take(t) // expected-error{{type_does_not_conform_decl_owner}}
79+
// expected-note@-14{{where_requirement_failure_one_subst}}
80+
}
81+
extension IntsTrailing2 : _BitwiseCopyable {} //expected-error{{bitwise_copyable_outside_module}}
82+
func passIntsTrailing2(_ t: IntsTrailing2) {
83+
take(t)
84+
}
85+
func passIntsTrailing3(_ t: IntsTrailing3) {
86+
take(t)
87+
}

0 commit comments

Comments
 (0)