Skip to content
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
3 changes: 3 additions & 0 deletions include/swift/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,9 @@ EXPERIMENTAL_FEATURE(WarnUnsafe, true)
/// Import unsafe C and C++ constructs as @unsafe.
EXPERIMENTAL_FEATURE(SafeInterop, true)

/// Ignore resilience errors due to C++ types.
EXPERIMENTAL_FEATURE(AssumeResilientCxxTypes, true)
Copy link
Contributor

@ravikandhadai ravikandhadai Oct 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is better not to use experimental feature since this is a flag to opt out of the error and not really a feature. Think it would better to have a flag that reads like allow-cxx-types-in-swift-interface

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I prefer the experimental feature approach because they are easier to add and remove. If you add flags, you have to update the drivers and frontend, and possibly leave them in forever. Experimental features are more self-contained.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me.


// Isolated deinit
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(IsolatedDeinit, true)

Expand Down
1 change: 1 addition & 0 deletions lib/AST/FeatureSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ static bool usesFeatureAllowUnsafeAttribute(Decl *decl) {

UNINTERESTING_FEATURE(WarnUnsafe)
UNINTERESTING_FEATURE(SafeInterop)
UNINTERESTING_FEATURE(AssumeResilientCxxTypes)

bool swift::usesFeatureIsolatedDeinit(const Decl *decl) {
if (auto cd = dyn_cast<ClassDecl>(decl)) {
Expand Down
4 changes: 3 additions & 1 deletion lib/Sema/TypeCheckAccess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1997,7 +1997,9 @@ swift::getDisallowedOriginKind(const Decl *decl,
where.getDeclContext()->getAsDecl() &&
where.getDeclContext()->getAsDecl()->getModuleContext()->isResilient() &&
decl->hasClangNode() && !decl->getModuleContext()->isSwiftShimsModule() &&
isFragileClangNode(decl->getClangNode()))
isFragileClangNode(decl->getClangNode()) &&
!SF->getASTContext().LangOpts.hasFeature(
Feature::AssumeResilientCxxTypes))
return DisallowedOriginKind::FragileCxxAPI;

// Report non-public import last as it can be ignored by the caller.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// RUN: %empty-directory(%t)
// RUN: split-file %s %t
// RUN: %target-swift-frontend %t/test.swift -I %t/Inputs -typecheck -enable-library-evolution -enable-experimental-cxx-interop -disable-availability-checking -disable-implicit-cxx-module-import -enable-experimental-feature AssumeResilientCxxTypes -verify

//--- Inputs/module.modulemap
module CxxModule {
header "header.h"
requires cplusplus
}

//--- Inputs/header.h

class CxxStruct {
public:
int x; int y;

void method() const;
};

enum class CxxEnum {
A, B
};

template<class T>
class CxxTemplate {
T v;
};

using CxxTemplateInt = CxxTemplate<int>;

class
__attribute__((swift_attr("import_reference")))
__attribute__((swift_attr("retain:immortal")))
__attribute__((swift_attr("release:immortal")))
SingletonReference {
public:
SingletonReference(const SingletonReference &) = delete;

static SingletonReference * _Nonnull create();

void method();
};

CxxStruct createStruct();

void freeCxxFunction();

using BuiltinIntTypealis = int;

//--- test.swift

import CxxModule

public func usesBuiltinIntTypealis() -> BuiltinIntTypealis {
return 21
}

public func usesCxxSingletonReference() -> SingletonReference {
return SingletonReference.create()
}

public func usesCxxStruct(_ x: CxxStruct) {
}

public typealias EnumT = CxxEnum

extension CxxTemplateInt {
func testInternal() {

}
}

extension CxxTemplateInt {
public func testPublicExt() {
}
}

public func publicFuncInternalBody() {
let s = createStruct()
s.method()
}

@inlinable
public func publicFuncPublicBody() {
let value = SingletonReference.create()
value.method()
}