Skip to content

Commit 3dffcc6

Browse files
authored
Merge pull request #73522 from kavon/ncgeneric-coverage-rdar127701059
NCGenerics: add test for feature flag
2 parents dae1e84 + 89ff3fe commit 3dffcc6

10 files changed

+101
-27
lines changed

lib/Basic/LangOptions.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ LangOptions::LangOptions() {
4747
#endif
4848

4949
// Note: Introduce default-on language options here.
50+
Features.insert(Feature::NoncopyableGenerics);
51+
Features.insert(Feature::BorrowingSwitch);
52+
Features.insert(Feature::MoveOnlyPartialConsumption);
5053

5154
// Enable any playground options that are enabled by default.
5255
#define PLAYGROUND_OPTION(OptionName, Description, DefaultOn, HighPerfOn) \

lib/ClangImporter/ClangImporter.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5795,6 +5795,20 @@ cloneBaseMemberDecl(ValueDecl *decl, DeclContext *newContext) {
57955795
}
57965796

57975797
if (auto var = dyn_cast<VarDecl>(decl)) {
5798+
auto oldContext = var->getDeclContext();
5799+
auto oldTypeDecl = oldContext->getSelfNominalTypeDecl();
5800+
// If the base type is non-copyable, we cannot synthesize the accessor,
5801+
// because its implementation would use `UnsafePointer<BaseTy>`, and that
5802+
// triggers a bug when building SwiftCompilerSources. (rdar://128013193)
5803+
//
5804+
// We cannot use `ty->isNoncopyable()` here because that would create a
5805+
// cyclic dependency between ModuleQualifiedLookupRequest and
5806+
// LookupConformanceInModuleRequest, so we check for the presence of
5807+
// move-only attribute that is implicitly added to non-copyable C++ types by
5808+
// ClangImporter.
5809+
if (oldTypeDecl->getAttrs().hasAttribute<MoveOnlyAttr>())
5810+
return nullptr;
5811+
57985812
auto rawMemory = allocateMemoryForDecl<VarDecl>(var->getASTContext(),
57995813
sizeof(VarDecl), false);
58005814
auto out =

lib/ClangImporter/ImportType.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,26 @@ namespace {
509509
return importFunctionPointerLikeType(*type, pointeeType);
510510
}
511511

512+
// We cannot specify UnsafePointer<T> with a non-copyable type T just yet,
513+
// because it triggers a bug when building SwiftCompilerSources.
514+
// (rdar://128013193)
515+
//
516+
// We cannot use `ty->isNoncopyable()` here because that would create a
517+
// cyclic dependency between ModuleQualifiedLookupRequest and
518+
// LookupConformanceInModuleRequest, so we check for the presence of
519+
// move-only attribute that is implicitly added to non-copyable C++ types
520+
// by ClangImporter.
521+
if (pointeeType && pointeeType->getAnyNominal() &&
522+
pointeeType->getAnyNominal()
523+
->getAttrs()
524+
.hasAttribute<MoveOnlyAttr>()) {
525+
auto opaquePointerDecl = Impl.SwiftContext.getOpaquePointerDecl();
526+
if (!opaquePointerDecl)
527+
return Type();
528+
return {opaquePointerDecl->getDeclaredInterfaceType(),
529+
ImportHint::OtherPointer};
530+
}
531+
512532
PointerTypeKind pointerKind;
513533
if (quals.hasConst()) {
514534
pointerKind = PTK_UnsafePointer;

test/Interop/Cxx/class/move-only/inherited-field-access-irgen.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// RUN: %target-swift-emit-irgen -I %S/Inputs -cxx-interoperability-mode=swift-6 %s -validate-tbd-against-ir=none -Xcc -fignore-exceptions | %FileCheck %s
22
// RUN: %target-swift-emit-irgen -I %S/Inputs -cxx-interoperability-mode=upcoming-swift %s -validate-tbd-against-ir=none -Xcc -fignore-exceptions | %FileCheck %s
33

4+
// REQUIRES: rdar128013193
5+
46
import MoveOnlyCxxValueType
57

68
func testGetX() -> CInt {

test/Interop/Cxx/class/move-only/inherited-field-access-silgen.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// RUN: %target-swift-emit-sil -I %S/Inputs -cxx-interoperability-mode=swift-6 %s -validate-tbd-against-ir=none | %FileCheck %s
22
// RUN: %target-swift-emit-sil -I %S/Inputs -cxx-interoperability-mode=upcoming-swift %s -validate-tbd-against-ir=none | %FileCheck %s
33

4+
// REQUIRES: rdar128013193
5+
46
import MoveOnlyCxxValueType
57

68
func testGetX() -> CInt {
Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
// RUN: %target-swift-ide-test -print-module -module-to-print=MoveOnlyCxxValueType -I %S/Inputs -cxx-interoperability-mode=upcoming-swift -source-filename=x | %FileCheck %s --check-prefix=CHECK-NCG
1+
// RUN: %target-swift-ide-test -print-module -module-to-print=MoveOnlyCxxValueType -I %S/Inputs -cxx-interoperability-mode=upcoming-swift -source-filename=x | %FileCheck %s --check-prefix=CHECK
22

3-
// CHECK-NCG: func getNonCopyablePtr() -> UnsafeMutablePointer<NonCopyable>
4-
// CHECK-NCG: func getNonCopyableDerivedPtr() -> UnsafeMutablePointer<NonCopyableDerived>
3+
// CHECK: func getNonCopyablePtr() -> OpaquePointer
4+
// CHECK: func getNonCopyableDerivedPtr() -> OpaquePointer
5+
6+
// FIXME: would prefer to have this (rdar://128013193)
7+
// func getNonCopyablePtr() -> UnsafeMutablePointer<NonCopyable>
8+
// func getNonCopyableDerivedPtr() -> UnsafeMutablePointer<NonCopyableDerived>

test/Interop/Cxx/class/move-only/move-only-cxx-value-type.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift)
2+
// -- FIXME: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift -D HAS_RDAR_128013193)
23
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-5.9 -O)
34
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-6 -O)
45

@@ -27,10 +28,12 @@ MoveOnlyCxxValueType.test("Test derived move only type member access") {
2728
var k = c.method(-3)
2829
expectEqual(k, -6)
2930
expectEqual(c.method(1), 2)
31+
#if HAS_RDAR_128013193
3032
k = c.x
3133
expectEqual(k, 2)
3234
c.x = 11
3335
expectEqual(c.x, 11)
36+
#endif
3437
k = c.mutMethod(-13)
3538
expectEqual(k, -13)
3639
}
@@ -56,6 +59,7 @@ MoveOnlyCxxValueType.test("Test move only field access in holder") {
5659
expectEqual(c.x.x, 5)
5760
}
5861

62+
#if HAS_RDAR_128013193
5963
MoveOnlyCxxValueType.test("Test move only field access in derived holder") {
6064
var c = NonCopyableHolderDerivedDerived(-11)
6165
var k = borrowNC(c.x)
@@ -69,5 +73,6 @@ MoveOnlyCxxValueType.test("Test move only field access in derived holder") {
6973
c.x.mutMethod(5)
7074
expectEqual(c.x.x, 5)
7175
}
76+
#endif
7277

7378
runAllTests()

test/Interop/Cxx/operators/move-only/move-only-synthesized-properties.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-5.9)
22
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-6)
33
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift)
4+
// -- FIXME: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift -D HAS_RDAR_128013193)
45
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-5.9 -O)
56
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-6 -O)
67
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift -O)
8+
// -- FIXME: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift -O -D HAS_RDAR_128013193)
79
//
810
// REQUIRES: executable_test
911

@@ -90,6 +92,7 @@ MoveOnlyCxxOperators.test("testNonCopyableHolderValueMutDeref pointee value") {
9092
expectEqual(k.x, k2.x)
9193
}
9294

95+
#if HAS_RDAR_128013193
9396
MoveOnlyCxxOperators.test("NonCopyableHolderConstDerefDerivedDerived pointee borrow") {
9497
let holder = NonCopyableHolderConstDerefDerivedDerived(11)
9598
var k = borrowNC(holder.pointee)
@@ -157,5 +160,6 @@ MoveOnlyCxxOperators.test("testNonCopyableHolderValueMutDerefDerivedDerived poin
157160
var k2 = holder.pointee
158161
expectEqual(k.x, k2.x)
159162
}
163+
#endif
160164

161165
runAllTests()
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-emit-module-interface(%t/Library.swiftinterface) %t/Library.swift -module-name Library
5+
// RUN: rm -f %t/Library.swiftmodule
6+
// RUN: %target-swift-frontend -I %t -typecheck -verify %t/test.swift
7+
8+
9+
//--- Library.swift
10+
11+
public struct Hello<T: ~Copyable> {
12+
public init() {}
13+
}
14+
15+
//--- test.swift
16+
import Library
17+
18+
struct NC: ~Copyable {}
19+
20+
let x: Hello<NC> = .init()

test/Sema/moveonly_enum.swift

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ enum Foo3 {
2222
}
2323

2424
func test_switch(x: consuming Foo3) {
25-
switch x { // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{12-12=consume }}
25+
switch x {
2626
default:
2727
break
2828
}
@@ -32,7 +32,7 @@ func test_switch(x: consuming Foo3) {
3232
break
3333
}
3434

35-
switch (x) { // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{13-13=consume }}
35+
switch (x) {
3636
default:
3737
break
3838
}
@@ -43,7 +43,7 @@ func test_switch(x: consuming Foo3) {
4343
}
4444

4545
let _: () -> () = {
46-
switch x { // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{16-16=consume }}
46+
switch x {
4747
default:
4848
break
4949
}
@@ -57,7 +57,7 @@ func test_switch(x: consuming Foo3) {
5757
}
5858

5959
let _: () -> () = {
60-
switch (x) { // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{17-17=consume }}
60+
switch (x) {
6161
default:
6262
break
6363
}
@@ -72,19 +72,19 @@ func test_switch(x: consuming Foo3) {
7272
}
7373

7474
func test_if_case(x: consuming Foo3) {
75-
if case .bar(let y) = x { _ = y } // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{27-27=consume }}
75+
if case .bar(let y) = x { _ = y }
7676

77-
guard case .bar(let y) = x else { return } // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{30-30=consume }}
77+
guard case .bar(let y) = x else { return }
7878
_ = y
7979

8080
if case .bar(let z) = consume x { _ = z }
8181

8282
guard case .bar(let z) = consume x else { return }
8383
_ = z
8484

85-
if case .bar(let a) = (x) { _ = a } // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{28-28=consume }}
85+
if case .bar(let a) = (x) { _ = a }
8686

87-
guard case .bar(let a) = (x) else { return } // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{31-31=consume }}
87+
guard case .bar(let a) = (x) else { return }
8888
_ = a
8989

9090
if case .bar(let b) = (consume x) { _ = b }
@@ -93,11 +93,11 @@ func test_if_case(x: consuming Foo3) {
9393
_ = b
9494

9595
let _: () -> () = {
96-
if case .bar(let y) = x { _ = y } // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{31-31=consume }}
96+
if case .bar(let y) = x { _ = y }
9797
}
9898

9999
let _: () -> () = {
100-
guard case .bar(let y) = x else { return } // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{34-34=consume }}
100+
guard case .bar(let y) = x else { return }
101101
_ = y
102102
}
103103

@@ -111,11 +111,11 @@ func test_if_case(x: consuming Foo3) {
111111
}
112112

113113
let _: () -> () = {
114-
if case .bar(let a) = (x) { _ = a } // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{32-32=consume }}
114+
if case .bar(let a) = (x) { _ = a }
115115
}
116116

117117
let _: () -> () = {
118-
guard case .bar(let a) = (x) else { return } // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{35-35=consume }}
118+
guard case .bar(let a) = (x) else { return }
119119
_ = a
120120
}
121121

@@ -130,7 +130,7 @@ func test_if_case(x: consuming Foo3) {
130130
}
131131

132132
func test_switch_b(x: __owned Foo3) {
133-
switch x { // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{12-12=consume }}
133+
switch x {
134134
default:
135135
break
136136
}
@@ -140,7 +140,7 @@ func test_switch_b(x: __owned Foo3) {
140140
break
141141
}
142142

143-
switch (x) { // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{13-13=consume }}
143+
switch (x) {
144144
default:
145145
break
146146
}
@@ -151,7 +151,7 @@ func test_switch_b(x: __owned Foo3) {
151151
}
152152

153153
let _: () -> () = {
154-
switch x { // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{16-16=consume }}
154+
switch x {
155155
default:
156156
break
157157
}
@@ -165,7 +165,7 @@ func test_switch_b(x: __owned Foo3) {
165165
}
166166

167167
let _: () -> () = {
168-
switch (x) { // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{17-17=consume }}
168+
switch (x) {
169169
default:
170170
break
171171
}
@@ -180,19 +180,19 @@ func test_switch_b(x: __owned Foo3) {
180180
}
181181

182182
func test_if_case_b(x: __owned Foo3) {
183-
if case .bar(let y) = x { _ = y } // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{27-27=consume }}
183+
if case .bar(let y) = x { _ = y }
184184

185-
guard case .bar(let y) = x else { return } // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{30-30=consume }}
185+
guard case .bar(let y) = x else { return }
186186
_ = y
187187

188188
if case .bar(let z) = consume x { _ = z }
189189

190190
guard case .bar(let z) = consume x else { return }
191191
_ = z
192192

193-
if case .bar(let a) = (x) { _ = a } // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{28-28=consume }}
193+
if case .bar(let a) = (x) { _ = a }
194194

195-
guard case .bar(let a) = (x) else { return } // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{31-31=consume }}
195+
guard case .bar(let a) = (x) else { return }
196196
_ = a
197197

198198
if case .bar(let b) = (consume x) { _ = b }
@@ -201,11 +201,11 @@ func test_if_case_b(x: __owned Foo3) {
201201
_ = b
202202

203203
let _: () -> () = {
204-
if case .bar(let y) = x { _ = y } // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{31-31=consume }}
204+
if case .bar(let y) = x { _ = y }
205205
}
206206

207207
let _: () -> () = {
208-
guard case .bar(let y) = x else { return } // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{34-34=consume }}
208+
guard case .bar(let y) = x else { return }
209209
_ = y
210210
}
211211

@@ -219,11 +219,11 @@ func test_if_case_b(x: __owned Foo3) {
219219
}
220220

221221
let _: () -> () = {
222-
if case .bar(let a) = (x) { _ = a } // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{32-32=consume }}
222+
if case .bar(let a) = (x) { _ = a }
223223
}
224224

225225
let _: () -> () = {
226-
guard case .bar(let a) = (x) else { return } // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{35-35=consume }}
226+
guard case .bar(let a) = (x) else { return }
227227
_ = a
228228
}
229229

0 commit comments

Comments
 (0)