Skip to content

Commit

Permalink
Merge pull request #73594 from kavon/6.0-ncgeneric-coverage-rdar12770…
Browse files Browse the repository at this point in the history
…1059
  • Loading branch information
kavon authored May 14, 2024
2 parents d887827 + 99d417b commit c9e109e
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 49 deletions.
3 changes: 3 additions & 0 deletions lib/Basic/LangOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ LangOptions::LangOptions() {
#endif

// Note: Introduce default-on language options here.
Features.insert(Feature::NoncopyableGenerics);
Features.insert(Feature::BorrowingSwitch);
Features.insert(Feature::MoveOnlyPartialConsumption);

// Enable any playground options that are enabled by default.
#define PLAYGROUND_OPTION(OptionName, Description, DefaultOn, HighPerfOn) \
Expand Down
10 changes: 5 additions & 5 deletions lib/ClangImporter/ClangImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5778,16 +5778,16 @@ cloneBaseMemberDecl(ValueDecl *decl, DeclContext *newContext) {
if (auto var = dyn_cast<VarDecl>(decl)) {
auto oldContext = var->getDeclContext();
auto oldTypeDecl = oldContext->getSelfNominalTypeDecl();
// If the base type is non-copyable, and non-copyable generics are disabled,
// we cannot synthesize the accessor, because its implementation would use
// `UnsafePointer<BaseTy>`.
// If the base type is non-copyable, we cannot synthesize the accessor,
// because its implementation would use `UnsafePointer<BaseTy>`, and that
// triggers a bug when building SwiftCompilerSources. (rdar://128013193)
//
// We cannot use `ty->isNoncopyable()` here because that would create a
// cyclic dependency between ModuleQualifiedLookupRequest and
// LookupConformanceInModuleRequest, so we check for the presence of
// move-only attribute that is implicitly added to non-copyable C++ types by
// ClangImporter.
if (oldTypeDecl->getAttrs().hasAttribute<MoveOnlyAttr>() &&
!context.LangOpts.hasFeature(Feature::NoncopyableGenerics))
if (oldTypeDecl->getAttrs().hasAttribute<MoveOnlyAttr>())
return nullptr;

auto rawMemory = allocateMemoryForDecl<VarDecl>(var->getASTContext(),
Expand Down
10 changes: 5 additions & 5 deletions lib/ClangImporter/ImportType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,8 +509,10 @@ namespace {
return importFunctionPointerLikeType(*type, pointeeType);
}

// If non-copyable generics are disabled, we cannot specify
// UnsafePointer<T> with a non-copyable type T.
// We cannot specify UnsafePointer<T> with a non-copyable type T just yet,
// because it triggers a bug when building SwiftCompilerSources.
// (rdar://128013193)
//
// We cannot use `ty->isNoncopyable()` here because that would create a
// cyclic dependency between ModuleQualifiedLookupRequest and
// LookupConformanceInModuleRequest, so we check for the presence of
Expand All @@ -519,9 +521,7 @@ namespace {
if (pointeeType && pointeeType->getAnyNominal() &&
pointeeType->getAnyNominal()
->getAttrs()
.hasAttribute<MoveOnlyAttr>() &&
!Impl.SwiftContext.LangOpts.hasFeature(
Feature::NoncopyableGenerics)) {
.hasAttribute<MoveOnlyAttr>()) {
auto opaquePointerDecl = Impl.SwiftContext.getOpaquePointerDecl();
if (!opaquePointerDecl)
return Type();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// RUN: %target-swift-emit-irgen -I %S/Inputs -cxx-interoperability-mode=swift-6 -enable-experimental-feature NoncopyableGenerics %s -validate-tbd-against-ir=none -Xcc -fignore-exceptions | %FileCheck %s
// RUN: %target-swift-emit-irgen -I %S/Inputs -cxx-interoperability-mode=upcoming-swift -enable-experimental-feature NoncopyableGenerics %s -validate-tbd-against-ir=none -Xcc -fignore-exceptions | %FileCheck %s

// REQUIRES: rdar128013193

import MoveOnlyCxxValueType

func testGetX() -> CInt {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// RUN: %target-swift-emit-sil -I %S/Inputs -cxx-interoperability-mode=swift-6 -enable-experimental-feature NoncopyableGenerics %s -validate-tbd-against-ir=none | %FileCheck %s
// RUN: %target-swift-emit-sil -I %S/Inputs -cxx-interoperability-mode=upcoming-swift -enable-experimental-feature NoncopyableGenerics %s -validate-tbd-against-ir=none | %FileCheck %s

// REQUIRES: rdar128013193

import MoveOnlyCxxValueType

func testGetX() -> CInt {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift -enable-experimental-feature NoncopyableGenerics)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift -enable-experimental-feature NoncopyableGenerics -O -Xfrontend -sil-verify-none)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift -O -Xfrontend -sil-verify-none)
//
// REQUIRES: executable_test
// REQUIRES: GH_ISSUE_70246
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// 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-NO-NCG
// RUN: %target-swift-ide-test -print-module -module-to-print=MoveOnlyCxxValueType -I %S/Inputs -cxx-interoperability-mode=upcoming-swift -source-filename=x -enable-experimental-feature NoncopyableGenerics | %FileCheck %s --check-prefix=CHECK-NCG
// 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

// CHECK-NO-NCG: func getNonCopyablePtr() -> OpaquePointer
// CHECK-NO-NCG: func getNonCopyableDerivedPtr() -> OpaquePointer
// CHECK: func getNonCopyablePtr() -> OpaquePointer
// CHECK: func getNonCopyableDerivedPtr() -> OpaquePointer

// CHECK-NCG: func getNonCopyablePtr() -> UnsafeMutablePointer<NonCopyable>
// CHECK-NCG: func getNonCopyableDerivedPtr() -> UnsafeMutablePointer<NonCopyableDerived>
// FIXME: would prefer to have this (rdar://128013193)
// func getNonCopyablePtr() -> UnsafeMutablePointer<NonCopyable>
// func getNonCopyableDerivedPtr() -> UnsafeMutablePointer<NonCopyableDerived>
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift -enable-experimental-feature NoncopyableGenerics -D HAS_NONCOPYABLE_GENERICS)
// -- FIXME: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift -D HAS_RDAR_128013193)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-5.9 -O)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-6 -O)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-6 -O -enable-experimental-feature NoncopyableGenerics -D HAS_NONCOPYABLE_GENERICS)

// REQUIRES: executable_test

Expand All @@ -29,7 +28,7 @@ MoveOnlyCxxValueType.test("Test derived move only type member access") {
var k = c.method(-3)
expectEqual(k, -6)
expectEqual(c.method(1), 2)
#if HAS_NONCOPYABLE_GENERICS
#if HAS_RDAR_128013193
k = c.x
expectEqual(k, 2)
c.x = 11
Expand Down Expand Up @@ -60,7 +59,7 @@ MoveOnlyCxxValueType.test("Test move only field access in holder") {
expectEqual(c.x.x, 5)
}

#if HAS_NONCOPYABLE_GENERICS
#if HAS_RDAR_128013193
MoveOnlyCxxValueType.test("Test move only field access in derived holder") {
var c = NonCopyableHolderDerivedDerived(-11)
var k = borrowNC(c.x)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-5.9)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-6)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift -enable-experimental-feature NoncopyableGenerics -D HAS_NONCOPYABLE_GENERICS)
// -- FIXME: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift -D HAS_RDAR_128013193)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-5.9 -O)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=swift-6 -O)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift -O)
// RUN: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift -O -enable-experimental-feature NoncopyableGenerics -D HAS_NONCOPYABLE_GENERICS)
// -- FIXME: %target-run-simple-swift(-I %S/Inputs/ -cxx-interoperability-mode=upcoming-swift -O -D HAS_RDAR_128013193)
//
// REQUIRES: executable_test

Expand Down Expand Up @@ -92,7 +92,7 @@ MoveOnlyCxxOperators.test("testNonCopyableHolderValueMutDeref pointee value") {
expectEqual(k.x, k2.x)
}

#if HAS_NONCOPYABLE_GENERICS
#if HAS_RDAR_128013193
MoveOnlyCxxOperators.test("NonCopyableHolderConstDerefDerivedDerived pointee borrow") {
let holder = NonCopyableHolderConstDerefDerivedDerived(11)
var k = borrowNC(holder.pointee)
Expand Down
20 changes: 20 additions & 0 deletions test/ModuleInterface/noncopyable_generics_feature_flag.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: %empty-directory(%t)
// RUN: split-file %s %t

// RUN: %target-swift-emit-module-interface(%t/Library.swiftinterface) %t/Library.swift -module-name Library
// RUN: rm -f %t/Library.swiftmodule
// RUN: %target-swift-frontend -I %t -typecheck -verify %t/test.swift


//--- Library.swift

public struct Hello<T: ~Copyable> {
public init() {}
}

//--- test.swift
import Library

struct NC: ~Copyable {}

let x: Hello<NC> = .init()
48 changes: 24 additions & 24 deletions test/Sema/moveonly_enum.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ enum Foo3 {
}

func test_switch(x: consuming Foo3) {
switch x { // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{12-12=consume }}
switch x {
default:
break
}
Expand All @@ -32,7 +32,7 @@ func test_switch(x: consuming Foo3) {
break
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

func test_switch_b(x: __owned Foo3) {
switch x { // expected-error{{noncopyable binding being pattern-matched must have the 'consume' operator applied}} {{12-12=consume }}
switch x {
default:
break
}
Expand All @@ -140,7 +140,7 @@ func test_switch_b(x: __owned Foo3) {
break
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Expand Down

0 comments on commit c9e109e

Please sign in to comment.