Skip to content
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

6.0: [BitwiseCopyable] Promote to feature. #73282

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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -7694,7 +7694,7 @@ ERROR(non_bitwise_copyable_type_cxx_nontrivial,none,
ERROR(non_bitwise_copyable_c_type_nontrivial,none,
"type with unrepresentable fields cannot derive conformance to 'BitwiseCopyable'", ())
NOTE(note_non_bitwise_copyable_c_type_add_attr,none,
"annotate the type __attribute__((__swift_attr__(\"_BitwiseCopyable\")))",())
"annotate the type __attribute__((__swift_attr__(\"BitwiseCopyable\")))",())
ERROR(non_bitwise_copyable_type_member,none,
"%select{stored property %2|associated value %2}1 of "
"'BitwiseCopyable'-conforming %kind3 has non-bitwise-copyable type %0",
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/KnownProtocols.def
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ PROTOCOL(FloatingPoint)
INVERTIBLE_PROTOCOL_WITH_NAME(Name, #Name)
#include "swift/ABI/InvertibleProtocols.def"

REPRESSIBLE_PROTOCOL_(BitwiseCopyable)
REPRESSIBLE_PROTOCOL(BitwiseCopyable)

EXPRESSIBLE_BY_LITERAL_PROTOCOL(ExpressibleByArrayLiteral, "Array", false)
EXPRESSIBLE_BY_LITERAL_PROTOCOL(ExpressibleByBooleanLiteral, "BooleanLiteralType", true)
Expand Down
9 changes: 3 additions & 6 deletions include/swift/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ LANGUAGE_FEATURE(BuiltinStoreRaw, 0, "Builtin.storeRaw")
LANGUAGE_FEATURE(BuiltinCreateTask, 0, "Builtin.createTask and Builtin.createDiscardingTask")
SUPPRESSIBLE_LANGUAGE_FEATURE(AssociatedTypeImplements, 0, "@_implements on associated types")
LANGUAGE_FEATURE(MoveOnlyPartialConsumption, 429, "Partial consumption of noncopyable values")
/// Enable bitwise-copyable feature.
LANGUAGE_FEATURE(BitwiseCopyable, 426, "BitwiseCopyable protocol")
SUPPRESSIBLE_LANGUAGE_FEATURE(ConformanceSuppression, 426, "Suppressible inferred conformances")

// Swift 6
UPCOMING_FEATURE(ConciseMagicFile, 274, 6)
Expand Down Expand Up @@ -339,12 +342,6 @@ EXPERIMENTAL_FEATURE(StaticExclusiveOnly, true)
/// Enable the @extractConstantsFromMembers attribute.
EXPERIMENTAL_FEATURE(ExtractConstantsFromMembers, false)

/// Enable bitwise-copyable feature.
EXPERIMENTAL_FEATURE(BitwiseCopyable, true)

/// Enable the suppression of inferred, non-invertible, protocols via ~.
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(ConformanceSuppression, true)

/// Enables the FixedArray data type.
EXPERIMENTAL_FEATURE(FixedArrays, true)

Expand Down
5 changes: 1 addition & 4 deletions lib/AST/ProtocolConformance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1284,10 +1284,7 @@ static SmallVector<ProtocolConformance *, 2> findSynthesizedConformances(
for (auto ip : InvertibleProtocolSet::allKnown())
trySynthesize(getKnownProtocolKind(ip));

if (nominal->getASTContext().LangOpts.hasFeature(
Feature::BitwiseCopyable)) {
trySynthesize(KnownProtocolKind::BitwiseCopyable);
}
trySynthesize(KnownProtocolKind::BitwiseCopyable);
}

/// Distributed actors can synthesize Encodable/Decodable, so look for those
Expand Down
4 changes: 1 addition & 3 deletions lib/ClangImporter/ImportDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8020,9 +8020,7 @@ ClangImporter::Implementation::importSwiftAttrAttributes(Decl *MappedDecl) {
continue;
}

if (swiftAttr->getAttribute() == "_BitwiseCopyable") {
if (!SwiftContext.LangOpts.hasFeature(Feature::BitwiseCopyable))
continue;
if (swiftAttr->getAttribute() == "BitwiseCopyable") {
auto *protocol =
SwiftContext.getProtocol(KnownProtocolKind::BitwiseCopyable);
auto *nominal = dyn_cast<NominalTypeDecl>(MappedDecl);
Expand Down
37 changes: 28 additions & 9 deletions lib/SIL/IR/TypeLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "swift/AST/DiagnosticEngine.h"
#include "swift/AST/DiagnosticsSIL.h"
#include "swift/AST/Expr.h"
#include "swift/AST/FileUnit.h"
#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/LazyResolver.h"
#include "swift/AST/Module.h"
Expand All @@ -28,6 +29,7 @@
#include "swift/AST/Pattern.h"
#include "swift/AST/PrettyStackTrace.h"
#include "swift/AST/PropertyWrappers.h"
#include "swift/AST/SourceFile.h"
#include "swift/AST/TypeDifferenceVisitor.h"
#include "swift/AST/Types.h"
#include "swift/ClangImporter/ClangModule.h"
Expand Down Expand Up @@ -3034,8 +3036,6 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
AbstractionPattern origType,
CanType substType,
TypeExpansionContext forExpansion) {
if (!Context.LangOpts.hasFeature(Feature::BitwiseCopyable))
return;
auto *bitwiseCopyableProtocol =
Context.getProtocol(KnownProtocolKind::BitwiseCopyable);
if (!bitwiseCopyableProtocol)
Expand All @@ -3050,10 +3050,20 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,

if (auto *nominal = substType.getAnyNominal()) {
auto *module = nominal->getModuleContext();
if (module && module->isBuiltFromInterface()) {
// Don't verify for types in modules built from interfaces; the feature
// may not have been enabled in them.
return;
if (module) {
if (module->isBuiltFromInterface()) {
// Don't verify for types in modules built from interfaces; the feature
// may not have been enabled in them.
return;
}
auto *file = dyn_cast_or_null<FileUnit>(module->getModuleScopeContext());
if (file && file->getKind() == FileUnitKind::Source) {
auto sourceFile = nominal->getParentSourceFile();
if (sourceFile && sourceFile->Kind == SourceFileKind::SIL) {
// Don't verify for types in SIL files.
return;
}
}
}
}

Expand All @@ -3079,6 +3089,7 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
// unconditionally but does in this case
// (8) being or containing the error type
// (9) explicitly suppressing conformance
// (10) a layout constrained archetype
bool hasNoNonconformingNode = visitAggregateLeaves(
origType, substType, forExpansion,
/*isLeafAggregate=*/
Expand Down Expand Up @@ -3148,7 +3159,7 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,

// ModuleTypes are trivial but don't warrant being given a
// conformance to BitwiseCopyable (case (3)).
if (isa<ModuleType, SILTokenType>(ty)) {
if (isa<ModuleType>(ty) || isa<SILTokenType>(ty)) {
// These types should never appear within aggregates.
assert(isTopLevel && "aggregate containing marker type!?");
// If they did, though, they would not justify the aggregate's
Expand All @@ -3167,13 +3178,21 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
return !isTopLevel;
}

// Case (10): a layout-constrained archetype.
if (auto archetype = dyn_cast<ArchetypeType>(ty)) {
auto constraint = archetype->getLayoutConstraint();
if (constraint && constraint->isTrivial()) {
return false;
}
}

auto *nominal = ty.getAnyNominal();

// Non-nominal types (besides case (3) handled above) are trivial iff
// conforming.
if (!nominal) {
llvm::errs()
<< "Non-nominal type without conformance to _BitwiseCopyable:\n"
<< "Non-nominal type without conformance to BitwiseCopyable:\n"
<< ty << "\n"
<< "within " << substType << "\n"
<< "of " << origType << "\n";
Expand Down Expand Up @@ -3284,7 +3303,7 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
return true;
});
if (hasNoConformingArchetypeNode) {
llvm::errs() << "Non-trivial type with _BitwiseCopyable conformance!?:\n"
llvm::errs() << "Non-trivial type with BitwiseCopyable conformance!?:\n"
<< substType << "\n";
conformance.print(llvm::errs());
llvm::errs() << "\n"
Expand Down
32 changes: 14 additions & 18 deletions lib/Sema/LifetimeDependence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,14 +205,12 @@ LifetimeDependenceInfo::fromTypeRepr(AbstractFunctionDecl *afd) {
// error.
// TODO: Diagnose ~Escapable types are always non-trivial in SIL.
if (paramType->isEscapable()) {
if (ctx.LangOpts.hasFeature(Feature::BitwiseCopyable)) {
auto *bitwiseCopyableProtocol =
ctx.getProtocol(KnownProtocolKind::BitwiseCopyable);
if (bitwiseCopyableProtocol &&
mod->checkConformance(paramType, bitwiseCopyableProtocol)) {
diags.diagnose(loc, diag::lifetime_dependence_on_bitwise_copyable);
return true;
}
auto *bitwiseCopyableProtocol =
ctx.getProtocol(KnownProtocolKind::BitwiseCopyable);
if (bitwiseCopyableProtocol &&
mod->checkConformance(paramType, bitwiseCopyableProtocol)) {
diags.diagnose(loc, diag::lifetime_dependence_on_bitwise_copyable);
return true;
}
}

Expand Down Expand Up @@ -425,16 +423,14 @@ LifetimeDependenceInfo::infer(AbstractFunctionDecl *afd) {
if (!cd && afd->hasImplicitSelfDecl()) {
Type selfTypeInContext = dc->getSelfTypeInContext();
if (selfTypeInContext->isEscapable()) {
if (ctx.LangOpts.hasFeature(Feature::BitwiseCopyable)) {
auto *bitwiseCopyableProtocol =
ctx.getProtocol(KnownProtocolKind::BitwiseCopyable);
if (bitwiseCopyableProtocol &&
mod->checkConformance(selfTypeInContext, bitwiseCopyableProtocol)) {
diags.diagnose(
returnLoc,
diag::lifetime_dependence_method_escapable_bitwisecopyable_self);
return std::nullopt;
}
auto *bitwiseCopyableProtocol =
ctx.getProtocol(KnownProtocolKind::BitwiseCopyable);
if (bitwiseCopyableProtocol &&
mod->checkConformance(selfTypeInContext, bitwiseCopyableProtocol)) {
diags.diagnose(
returnLoc,
diag::lifetime_dependence_method_escapable_bitwisecopyable_self);
return std::nullopt;
}
}
auto kind = getLifetimeDependenceKindFromType(selfTypeInContext);
Expand Down
6 changes: 3 additions & 3 deletions lib/Sema/TypeCheckDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -682,9 +682,9 @@ ExistentialConformsToSelfRequest::evaluate(Evaluator &evaluator,
ProtocolDecl *decl) const {
// Marker protocols always self-conform.
if (decl->isMarkerProtocol()) {
// Except for BitwiseCopyable an existential of which is non-trivial.
if (decl->getASTContext().LangOpts.hasFeature(Feature::BitwiseCopyable) &&
decl->getKnownProtocolKind() == KnownProtocolKind::BitwiseCopyable) {
// Except for BitwiseCopyable an existential of which is not bitwise
// copyable.
if (decl->getKnownProtocolKind() == KnownProtocolKind::BitwiseCopyable) {
return false;
}
return true;
Expand Down
8 changes: 3 additions & 5 deletions lib/Sema/TypeCheckProtocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6117,11 +6117,9 @@ void TypeChecker::checkConformancesInContext(IterableDeclContext *idc) {
break;
}
case KnownProtocolKind::BitwiseCopyable: {
if (Context.LangOpts.hasFeature(Feature::BitwiseCopyable)) {
checkBitwiseCopyableConformance(
conformance, /*isImplicit=*/conformance->getSourceKind() ==
ConformanceEntryKind::Synthesized);
}
checkBitwiseCopyableConformance(
conformance, /*isImplicit=*/conformance->getSourceKind() ==
ConformanceEntryKind::Synthesized);
break;
}
default:
Expand Down
2 changes: 0 additions & 2 deletions stdlib/public/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -315,9 +315,7 @@ list(APPEND swift_stdlib_compile_flags "-Xfrontend" "-enable-experimental-concis
list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "Macros")
list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "FreestandingMacros")
list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "Extern")
list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "BitwiseCopyable")
list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "BorrowingSwitch")
list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "ConformanceSuppression")

if("${SWIFT_NATIVE_SWIFT_TOOLS_PATH}" STREQUAL "")
set(swift_bin_dir "${CMAKE_BINARY_DIR}/bin")
Expand Down
10 changes: 1 addition & 9 deletions stdlib/public/core/CommandLine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,9 @@ internal func _swift_stdlib_getUnsafeArgvArgc(_: UnsafeMutablePointer<Int32>)
-> UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>

/// Command-line arguments for the current process.
#if $BitwiseCopyable && $ConformanceSuppression
@frozen // namespace
public enum CommandLine : ~_BitwiseCopyable {
public enum CommandLine : ~BitwiseCopyable {
}
#else
@frozen // namespace
public enum CommandLine {
}
@available(*, unavailable)
extension CommandLine : _BitwiseCopyable {}
#endif

extension CommandLine {
/// The backing static variable for argument count may come either from the
Expand Down
6 changes: 3 additions & 3 deletions stdlib/public/core/KeyPath.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1845,12 +1845,12 @@ internal struct RawKeyPathComponent {
}
}

internal func _pop<T : _BitwiseCopyable>(from: inout UnsafeRawBufferPointer,
internal func _pop<T : BitwiseCopyable>(from: inout UnsafeRawBufferPointer,
as type: T.Type) -> T {
let buffer = _pop(from: &from, as: type, count: 1)
return buffer.baseAddress.unsafelyUnwrapped.pointee
}
internal func _pop<T : _BitwiseCopyable>(from: inout UnsafeRawBufferPointer,
internal func _pop<T : BitwiseCopyable>(from: inout UnsafeRawBufferPointer,
as: T.Type,
count: Int) -> UnsafeBufferPointer<T> {
from = MemoryLayout<T>._roundingUpBaseToAlignment(from)
Expand Down Expand Up @@ -3470,7 +3470,7 @@ internal struct InstantiateKeyPathBuffer: KeyPathPatternVisitor {
}
return (baseAddress, misalign)
}
mutating func pushDest<T : _BitwiseCopyable>(_ value: T) {
mutating func pushDest<T : BitwiseCopyable>(_ value: T) {
let size = MemoryLayout<T>.size
let (baseAddress, misalign) = adjustDestForAlignment(of: T.self)
_withUnprotectedUnsafeBytes(of: value) {
Expand Down
9 changes: 1 addition & 8 deletions stdlib/public/core/MemoryLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,8 @@
/// let pointPointer = UnsafeMutableRawPointer.allocate(
/// byteCount: count * MemoryLayout<Point>.stride,
/// alignment: MemoryLayout<Point>.alignment)
#if $BitwiseCopyable && $ConformanceSuppression
@frozen // namespace
public enum MemoryLayout<T: ~Copyable>: ~_BitwiseCopyable, Copyable {}
#else
@frozen // namespace
public enum MemoryLayout<T: ~Copyable>: Copyable {}
@available(*, unavailable)
extension MemoryLayout: _BitwiseCopyable {}
#endif
public enum MemoryLayout<T: ~Copyable>: ~BitwiseCopyable, Copyable {}

extension MemoryLayout where T: ~Copyable {
/// The contiguous memory footprint of `T`, in bytes.
Expand Down
7 changes: 5 additions & 2 deletions stdlib/public/core/Misc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,10 @@ func _rethrowsViaClosure(_ fn: () throws -> ()) rethrows {
@_marker public protocol Escapable {}

#if $NoncopyableGenerics && $NonescapableTypes
@_marker public protocol _BitwiseCopyable: ~Escapable { }
@_marker public protocol BitwiseCopyable: ~Escapable { }
#else
@_marker public protocol _BitwiseCopyable { }
@_marker public protocol BitwiseCopyable { }
#endif

@available(*, unavailable)
@_marker public protocol _BitwiseCopyable {}
2 changes: 1 addition & 1 deletion stdlib/public/core/Optional.swift
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ extension Optional: Copyable /* where Wrapped: Copyable */ {}

extension Optional: Sendable where Wrapped: ~Copyable & Sendable { }

extension Optional: _BitwiseCopyable where Wrapped: _BitwiseCopyable { }
extension Optional: BitwiseCopyable where Wrapped: BitwiseCopyable { }

@_preInverseGenerics
extension Optional: ExpressibleByNilLiteral where Wrapped: ~Copyable {
Expand Down
2 changes: 1 addition & 1 deletion stdlib/public/core/Pointer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public protocol _Pointer:
Strideable,
_CustomDebugStringConvertibleOrNone,
_CustomReflectableOrNone,
_BitwiseCopyable
BitwiseCopyable
{
/// A type that represents the distance between two pointers.
typealias Distance = Int
Expand Down
8 changes: 4 additions & 4 deletions stdlib/public/core/SIMDVector.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ prefix operator .!
/// elementwise accesses. Computational operations are defined on the `SIMD`
/// protocol, which refines this protocol, and on the concrete types that
/// conform to `SIMD`.
public protocol SIMDStorage : _BitwiseCopyable {
public protocol SIMDStorage : BitwiseCopyable {
/// The type of scalars in the vector space.
#if $Embedded
associatedtype Scalar: Hashable
Expand Down Expand Up @@ -64,7 +64,7 @@ extension SIMDStorage {
}

/// A type that can be used as an element in a SIMD vector.
public protocol SIMDScalar : _BitwiseCopyable {
public protocol SIMDScalar : BitwiseCopyable {
associatedtype SIMDMaskScalar: SIMDScalar & FixedWidthInteger & SignedInteger
where SIMDMaskScalar.SIMDMaskScalar == SIMDMaskScalar
associatedtype SIMD2Storage: SIMDStorage where SIMD2Storage.Scalar == Self
Expand All @@ -81,7 +81,7 @@ public protocol SIMD<Scalar>:
SIMDStorage,
Hashable,
ExpressibleByArrayLiteral,
_BitwiseCopyable
BitwiseCopyable
{
/// The mask type resulting from pointwise comparisons of this vector type.
associatedtype MaskStorage: SIMD
Expand All @@ -97,7 +97,7 @@ public protocol SIMD<Scalar>:
Hashable,
CustomStringConvertible,
ExpressibleByArrayLiteral,
_BitwiseCopyable
BitwiseCopyable
{
/// The mask type resulting from pointwise comparisons of this vector type.
associatedtype MaskStorage: SIMD
Expand Down
8 changes: 1 addition & 7 deletions stdlib/public/core/Unicode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -671,11 +671,5 @@ public func transcode<Input, InputEncoding, OutputEncoding>(
}

/// A namespace for Unicode utilities.
#if $BitwiseCopyable && $ConformanceSuppression
@frozen
public enum Unicode : ~_BitwiseCopyable {}
#else
@frozen
public enum Unicode {}
#endif

public enum Unicode : ~BitwiseCopyable {}