Skip to content

AST/Frontend/stdlib: Fix condfails for NoncopyableGenerics and IsolatedAny #72608

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 28, 2024
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/AST/PrintOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,9 @@ struct PrintOptions {
/// Suppress Noncopyable generics.
bool SuppressNoncopyableGenerics = false;

/// Suppress printing of `borrowing` and `consuming`.
bool SuppressNoncopyableOwnershipModifiers = false;

/// List of attribute kinds that should not be printed.
std::vector<AnyAttrKind> ExcludeAttrList = {
DeclAttrKind::Transparent, DeclAttrKind::Effects,
Expand Down
6 changes: 6 additions & 0 deletions include/swift/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,9 @@ EXPERIMENTAL_FEATURE(Embedded, true)
/// Enables noncopyable generics
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(NoncopyableGenerics, true)

// Alias for NoncopyableGenerics
EXPERIMENTAL_FEATURE(NoncopyableGenerics2, true)

/// Allow destructuring stored `let` bindings in structs.
EXPERIMENTAL_FEATURE(StructLetDestructuring, true)

Expand Down Expand Up @@ -358,6 +361,9 @@ EXPERIMENTAL_FEATURE(ClosureIsolation, true)
// Enable isolated(any) attribute on function types.
CONDITIONALLY_SUPPRESSIBLE_EXPERIMENTAL_FEATURE(IsolatedAny, true)

// Alias for IsolatedAny
EXPERIMENTAL_FEATURE(IsolatedAny2, true)

// Enable usability improvements for global-actor-isolated types.
EXPERIMENTAL_FEATURE(GlobalActorIsolatedTypesUsability, false)

Expand Down
22 changes: 19 additions & 3 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1138,7 +1138,16 @@ class PrintAST : public ASTVisitor<PrintAST> {
Printer.callPrintDeclPre(D, Options.BracketOptions);

if (Options.PrintCompatibilityFeatureChecks) {
printWithCompatibilityFeatureChecks(Printer, Options, D, [&]{
printWithCompatibilityFeatureChecks(Printer, Options, D, [&] {
// If we are in a scope where non-copyable generics are being suppressed
// and we are also printing a decl that has @_preInverseGenerics, make
// sure we also suppress printing ownership modifiers that were added
// to satisfy the requirements of non-copyability.
llvm::SaveAndRestore<bool> scope(
Options.SuppressNoncopyableOwnershipModifiers,
Options.SuppressNoncopyableGenerics &&
D->getAttrs().hasAttribute<PreInverseGenericsAttr>());

ASTVisitor::visit(D);
});
} else {
Expand Down Expand Up @@ -3123,9 +3132,12 @@ static void suppressingFeatureAssociatedTypeImplements(PrintOptions &options,
static void suppressingFeatureNoncopyableGenerics(
PrintOptions &options,
llvm::function_ref<void()> action) {
unsigned originalExcludeAttrCount = options.ExcludeAttrList.size();
options.ExcludeAttrList.push_back(DeclAttrKind::PreInverseGenerics);
llvm::SaveAndRestore<bool> scope(
options.SuppressNoncopyableGenerics, true);
action();
options.ExcludeAttrList.resize(originalExcludeAttrCount);
}

/// Suppress the printing of a particular feature.
Expand Down Expand Up @@ -3680,10 +3692,14 @@ static void printParameterFlags(ASTPrinter &printer,
printer.printKeyword("inout", options, " ");
break;
case ParamSpecifier::Borrowing:
printer.printKeyword("borrowing", options, " ");
if (!options.SuppressNoncopyableOwnershipModifiers) {
printer.printKeyword("borrowing", options, " ");
}
break;
case ParamSpecifier::Consuming:
printer.printKeyword("consuming", options, " ");
if (!options.SuppressNoncopyableOwnershipModifiers) {
printer.printKeyword("consuming", options, " ");
}
break;
case ParamSpecifier::LegacyShared:
printer.printKeyword("__shared", options, " ");
Expand Down
7 changes: 7 additions & 0 deletions lib/AST/FeatureSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,9 @@ static bool usesFeatureRawLayout(Decl *decl) {
UNINTERESTING_FEATURE(Embedded)

static bool usesFeatureNoncopyableGenerics(Decl *decl) {
if (decl->getAttrs().hasAttribute<PreInverseGenericsAttr>())
return true;

if (auto *valueDecl = dyn_cast<ValueDecl>(decl)) {
if (isa<StructDecl, EnumDecl, ClassDecl>(decl)) {
auto *nominalDecl = cast<NominalTypeDecl>(valueDecl);
Expand Down Expand Up @@ -568,6 +571,8 @@ static bool usesFeatureNoncopyableGenerics(Decl *decl) {
return !inverseReqs.empty();
}

UNINTERESTING_FEATURE(NoncopyableGenerics2)

static bool usesFeatureStructLetDestructuring(Decl *decl) {
auto sd = dyn_cast<StructDecl>(decl);
if (!sd)
Expand Down Expand Up @@ -676,6 +681,8 @@ static bool usesFeatureIsolatedAny(Decl *decl) {
});
}

UNINTERESTING_FEATURE(IsolatedAny2)

static bool usesFeatureGlobalActorIsolatedTypesUsability(Decl *decl) {
return false;
}
Expand Down
6 changes: 6 additions & 0 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,12 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
#else
Opts.enableFeature(*feature);
#endif

if (*feature == Feature::NoncopyableGenerics2)
Opts.enableFeature(Feature::NoncopyableGenerics);

if (*feature == Feature::IsolatedAny2)
Opts.enableFeature(Feature::IsolatedAny);
}

// Hack: In order to support using availability macros in SPM packages, we
Expand Down
2 changes: 1 addition & 1 deletion stdlib/cmake/modules/SwiftSource.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ function(_compile_swift_files
list(APPEND swift_flags "-experimental-hermetic-seal-at-link")
endif()

list(APPEND swift_flags "-enable-experimental-feature" "NoncopyableGenerics")
list(APPEND swift_flags "-enable-experimental-feature" "NoncopyableGenerics2")

if(SWIFT_ENABLE_EXPERIMENTAL_NONESCAPABLE_TYPES)
list(APPEND swift_flags "-enable-experimental-feature" "NonescapableTypes")
Expand Down
2 changes: 1 addition & 1 deletion stdlib/public/Concurrency/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ endif()

list(APPEND SWIFT_RUNTIME_CONCURRENCY_SWIFT_FLAGS
"-enable-experimental-feature"
"IsolatedAny"
"IsolatedAny2"
)

list(APPEND SWIFT_RUNTIME_CONCURRENCY_C_FLAGS
Expand Down
2 changes: 2 additions & 0 deletions stdlib/public/Concurrency/TaskGroup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,7 @@ public struct ThrowingTaskGroup<ChildTaskResult: Sendable, Failure: Error> {
/// to set the child task's priority to the priority of the group.
/// - operation: The operation to execute as part of the task group.
@_alwaysEmitIntoClient
@_allowFeatureSuppression(IsolatedAny)
public mutating func addTask(
priority: TaskPriority? = nil,
operation: __owned @Sendable @escaping @isolated(any) () async throws -> ChildTaskResult
Expand Down Expand Up @@ -823,6 +824,7 @@ public struct ThrowingTaskGroup<ChildTaskResult: Sendable, Failure: Error> {
/// - Returns: `true` if the child task was added to the group;
/// otherwise `false`.
@_alwaysEmitIntoClient
@_allowFeatureSuppression(IsolatedAny)
public mutating func addTaskUnlessCancelled(
priority: TaskPriority? = nil,
operation: __owned @Sendable @escaping @isolated(any) () async throws -> ChildTaskResult
Expand Down
13 changes: 5 additions & 8 deletions stdlib/public/core/Optional.swift
Original file line number Diff line number Diff line change
Expand Up @@ -213,20 +213,22 @@ extension Optional where Wrapped: ~Copyable {
}
}

#if hasFeature(BorrowingSwitch)
// FIXME(NCG): Make this public.
@_alwaysEmitIntoClient
public borrowing func _borrowingMap<U: ~Copyable, E: Error>(
_ transform: (borrowing Wrapped) throws(E) -> U
) throws(E) -> U? {
#if $NoncopyableGenerics
switch self {
case .some(_borrowing y):
return .some(try transform(y))
case .none:
return .none
}
#else
fatalError("unsupported compiler")
#endif
}
#endif
}

extension Optional {
Expand Down Expand Up @@ -263,6 +265,7 @@ extension Optional {
}
}

@_disallowFeatureSuppression(NoncopyableGenerics)
extension Optional where Wrapped: ~Copyable {
// FIXME(NCG): Make this public.
@_alwaysEmitIntoClient
Expand All @@ -277,7 +280,6 @@ extension Optional where Wrapped: ~Copyable {
}
}

#if hasFeature(BorrowingSwitch)
// FIXME(NCG): Make this public.
@_alwaysEmitIntoClient
public func _borrowingFlatMap<U: ~Copyable, E: Error>(
Expand All @@ -290,7 +292,6 @@ extension Optional where Wrapped: ~Copyable {
return .none
}
}
#endif
}

extension Optional {
Expand Down Expand Up @@ -546,7 +547,6 @@ public struct _OptionalNilComparisonType: ExpressibleByNilLiteral {
}
}

#if hasFeature(BorrowingSwitch)
extension Optional where Wrapped: ~Copyable {
/// Returns a Boolean value indicating whether an argument matches `nil`.
///
Expand Down Expand Up @@ -735,9 +735,6 @@ extension Optional where Wrapped: ~Copyable {
}
}
}
#else
#error("FIXME(NCG): Fill this out.")
#endif

/// Performs a nil-coalescing operation, returning the wrapped value of an
/// `Optional` instance or a default value.
Expand Down
7 changes: 3 additions & 4 deletions stdlib/public/core/Result.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ extension Result {
}
}

@_disallowFeatureSuppression(NoncopyableGenerics)
extension Result where Success: ~Copyable {
// FIXME(NCG): Make this public.
@_alwaysEmitIntoClient
Expand All @@ -75,7 +76,6 @@ extension Result where Success: ~Copyable {
}
}

#if $BorrowingSwitch
// FIXME(NCG): Make this public.
@_alwaysEmitIntoClient
public borrowing func _borrowingMap<NewSuccess: ~Copyable>(
Expand All @@ -88,7 +88,6 @@ extension Result where Success: ~Copyable {
return .failure(failure)
}
}
#endif
}

extension Result where Success: ~Copyable {
Expand Down Expand Up @@ -131,6 +130,7 @@ extension Result where Success: ~Copyable {
}
}

@_disallowFeatureSuppression(NoncopyableGenerics)
extension Result {
@_spi(SwiftStdlibLegacyABI) @available(swift, obsoleted: 1)
@usableFromInline
Expand Down Expand Up @@ -186,6 +186,7 @@ extension Result {
}
}

@_disallowFeatureSuppression(NoncopyableGenerics)
extension Result where Success: ~Copyable {
// FIXME(NCG): Make this public.
@_alwaysEmitIntoClient
Expand All @@ -200,7 +201,6 @@ extension Result where Success: ~Copyable {
}
}

#if $BorrowingSwitch
// FIXME(NCG): Make this public.
@_alwaysEmitIntoClient
public borrowing func _borrowingFlatMap<NewSuccess: ~Copyable>(
Expand All @@ -213,7 +213,6 @@ extension Result where Success: ~Copyable {
return .failure(failure)
}
}
#endif
}

extension Result {
Expand Down
1 change: 1 addition & 0 deletions stdlib/public/core/UnsafeBufferPointer.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,7 @@ extension Unsafe${Mutable}BufferPointer where Element: ~Copyable {

}

@_disallowFeatureSuppression(NoncopyableGenerics)
extension Unsafe${Mutable}BufferPointer {
/// Accesses the element at the specified position.
///
Expand Down
4 changes: 4 additions & 0 deletions stdlib/public/core/UnsafePointer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ extension UnsafePointer where Pointee: ~Copyable {
}
}

@_disallowFeatureSuppression(NoncopyableGenerics)
extension UnsafePointer {
// This preserves the ABI of the original (pre-6.0) `pointee` property that
// used to export a getter. The current one above would export a read
Expand Down Expand Up @@ -315,6 +316,7 @@ extension UnsafePointer where Pointee: ~Copyable {
}
}

@_disallowFeatureSuppression(NoncopyableGenerics)
extension UnsafePointer {
// This preserves the ABI of the original (pre-6.0) subscript that used to
// export a getter. The current one above would export a read accessor, if it
Expand Down Expand Up @@ -843,6 +845,7 @@ extension UnsafeMutablePointer where Pointee: ~Copyable {
}
}

@_disallowFeatureSuppression(NoncopyableGenerics)
extension UnsafeMutablePointer {
// This preserves the ABI of the original (pre-6.0) `pointee` property that
// used to export a getter. The current one above would export a read
Expand Down Expand Up @@ -1300,6 +1303,7 @@ extension UnsafeMutablePointer where Pointee: ~Copyable {
}
}

@_disallowFeatureSuppression(NoncopyableGenerics)
extension UnsafeMutablePointer {
// This preserves the ABI of the original (pre-6.0) subscript that used to
// export a getter. The current one above would export a read accessor, if it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@

// REQUIRES: executable_test

// FIXME(NCG): This test requires NoncopyableGenerics to be a "suppressible" compiler feature.
// XFAIL: !noncopyable_generics

//--- header.h

#include <stdio.h>
Expand Down
3 changes: 0 additions & 3 deletions test/Interop/SwiftToCxx/stdlib/swift-stdlib-in-cxx.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
// RUN: %check-interop-cxx-header-in-clang(%t/Swift.h -DSWIFT_CXX_INTEROP_HIDE_STL_OVERLAY -Wno-unused-private-field -Wno-unused-function -Wc++98-compat-extra-semi)
// RUN: %check-interop-cxx-header-in-clang(%t/Swift.h -DSWIFT_CXX_INTEROP_HIDE_STL_OVERLAY -Wno-unused-private-field -Wno-unused-function -Wc++98-compat-extra-semi -DDEBUG=1)

// FIXME(NCG): This test requires NoncopyableGenerics to be a "suppressible" compiler feature.
// XFAIL: !noncopyable_generics

// CHECK: namespace swift SWIFT_PRIVATE_ATTR SWIFT_SYMBOL_MODULE("swift") {

// CHECK: template<class T_0_0>
Expand Down
6 changes: 6 additions & 0 deletions test/ModuleInterface/Inputs/NoncopyableGenerics_Misc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,9 @@ extension Outer.InnerStruct {

@_preInverseGenerics
public func old_swap<T: ~Copyable>(_ a: inout T, _ b: inout T) {}

@_preInverseGenerics
public func borrowsNoncopyable<T: ~Copyable>(_ t: borrowing T) {}

@_disallowFeatureSuppression(NoncopyableGenerics)
public func suppressesNoncopyableGenerics<T: ~Copyable>(_ t: borrowing T) {}
1 change: 1 addition & 0 deletions test/ModuleInterface/isolated_any_suppression.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// RUN: %empty-directory(%t)

// RUN: %target-swift-frontend -swift-version 5 -enable-library-evolution -module-name isolated_any -emit-module -o %t/isolated_any.swiftmodule -emit-module-interface-path - -enable-experimental-feature IsolatedAny %s | %FileCheck %s
// RUN: %target-swift-frontend -swift-version 5 -enable-library-evolution -module-name isolated_any -emit-module -o %t/isolated_any.swiftmodule -emit-module-interface-path - -enable-experimental-feature IsolatedAny2 %s | %FileCheck %s

// CHECK: #if compiler(>=5.3) && $IsolatedAny
// CHECK-NEXT: {{^}}public func test1(fn: @isolated(any) @Sendable () -> ())
Expand Down
15 changes: 15 additions & 0 deletions test/ModuleInterface/noncopyable_generics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,23 @@ import NoncopyableGenerics_Misc

// CHECK-MISC: #if compiler(>=5.3) && $NoncopyableGenerics
// CHECK-MISC-NEXT: @_preInverseGenerics public func old_swap<T>(_ a: inout T, _ b: inout T) where T : ~Copyable
// CHECK-MISC-NEXT: #else
// CHECK-MISC-NOT: @_preInverseGenerics
// CHECK-MISC-NEXT: public func old_swap<T>(_ a: inout T, _ b: inout T)
// CHECK-MISC: #endif

// CHECK-MISC: #if compiler(>=5.3) && $NoncopyableGenerics
// CHECK-MISC-NEXT: @_preInverseGenerics public func borrowsNoncopyable<T>(_ t: borrowing T) where T : ~Copyable
// CHECK-MISC-NEXT: #else
// CHECK-MISC-NOT: @_preInverseGenerics
// CHECK-MISC-NEXT: public func borrowsNoncopyable<T>(_ t: T)
// CHECK-MISC-NEXT: #endif

// CHECK-MISC: #if compiler(>=5.3) && $NoncopyableGenerics
// CHECK-MISC-NEXT: public func suppressesNoncopyableGenerics<T>(_ t: borrowing T) where T : ~Copyable
// CHECK-MISC-NEXT: #endif


import Swiftskell

// CHECK: #if compiler(>=5.3) && $NoncopyableGenerics
Expand Down