Skip to content

Commit bcd08c0

Browse files
Merge pull request swiftlang#73235 from nate-chandler/bitwise-copyable/enable
[BitwiseCopyable] Promote to feature.
2 parents da9922d + b12def9 commit bcd08c0

File tree

55 files changed

+285
-284
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+285
-284
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7740,12 +7740,14 @@ NOTE(note_non_bitwise_copyable_type_indirect_enum_element,none,
77407740
"indirect case is here", ())
77417741
ERROR(non_bitwise_copyable_type_suppressed,none,
77427742
"cannot both conform to and suppress conformance to 'BitwiseCopyable'", ())
7743+
ERROR(non_bitwise_copyable_type_sensitive,none,
7744+
"a @sensitive type cannot conform to 'BitwiseCopyable'", ())
77437745
ERROR(non_bitwise_copyable_type_cxx_nontrivial,none,
77447746
"non-trivial C++ type cannot conform to 'BitwiseCopyable'", ())
77457747
ERROR(non_bitwise_copyable_c_type_nontrivial,none,
77467748
"type with unrepresentable fields cannot derive conformance to 'BitwiseCopyable'", ())
77477749
NOTE(note_non_bitwise_copyable_c_type_add_attr,none,
7748-
"annotate the type __attribute__((__swift_attr__(\"_BitwiseCopyable\")))",())
7750+
"annotate the type __attribute__((__swift_attr__(\"BitwiseCopyable\")))",())
77497751
ERROR(non_bitwise_copyable_type_member,none,
77507752
"%select{stored property %2|associated value %2}1 of "
77517753
"'BitwiseCopyable'-conforming %kind3 has non-bitwise-copyable type %0",

include/swift/AST/KnownProtocols.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ PROTOCOL(FloatingPoint)
150150
INVERTIBLE_PROTOCOL_WITH_NAME(Name, #Name)
151151
#include "swift/ABI/InvertibleProtocols.def"
152152

153-
REPRESSIBLE_PROTOCOL_(BitwiseCopyable)
153+
REPRESSIBLE_PROTOCOL(BitwiseCopyable)
154154

155155
EXPRESSIBLE_BY_LITERAL_PROTOCOL(ExpressibleByArrayLiteral, "Array", false)
156156
EXPRESSIBLE_BY_LITERAL_PROTOCOL(ExpressibleByBooleanLiteral, "BooleanLiteralType", true)

include/swift/Basic/Features.def

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,9 @@ LANGUAGE_FEATURE(BuiltinCreateTask, 0, "Builtin.createTask and Builtin.createDis
177177
SUPPRESSIBLE_LANGUAGE_FEATURE(AssociatedTypeImplements, 0, "@_implements on associated types")
178178
LANGUAGE_FEATURE(BuiltinAddressOfRawLayout, 0, "Builtin.addressOfRawLayout")
179179
LANGUAGE_FEATURE(MoveOnlyPartialConsumption, 429, "Partial consumption of noncopyable values")
180+
/// Enable bitwise-copyable feature.
181+
LANGUAGE_FEATURE(BitwiseCopyable, 426, "BitwiseCopyable protocol")
182+
SUPPRESSIBLE_LANGUAGE_FEATURE(ConformanceSuppression, 426, "Suppressible inferred conformances")
180183

181184
// Swift 6
182185
UPCOMING_FEATURE(ConciseMagicFile, 274, 6)
@@ -343,12 +346,6 @@ EXPERIMENTAL_FEATURE(StaticExclusiveOnly, true)
343346
/// Enable the @extractConstantsFromMembers attribute.
344347
EXPERIMENTAL_FEATURE(ExtractConstantsFromMembers, false)
345348

346-
/// Enable bitwise-copyable feature.
347-
EXPERIMENTAL_FEATURE(BitwiseCopyable, true)
348-
349-
/// Enable the suppression of inferred, non-invertible, protocols via ~.
350-
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(ConformanceSuppression, true)
351-
352349
/// Enables the FixedArray data type.
353350
EXPERIMENTAL_FEATURE(FixedArrays, true)
354351

lib/AST/LifetimeDependence.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,6 @@ static LifetimeDependenceKind getLifetimeDependenceKindFromDecl(
173173
}
174174

175175
static bool isBitwiseCopyable(Type type, ModuleDecl *mod, ASTContext &ctx) {
176-
if (!ctx.LangOpts.hasFeature(Feature::BitwiseCopyable)) {
177-
return false;
178-
}
179176
auto *bitwiseCopyableProtocol =
180177
ctx.getProtocol(KnownProtocolKind::BitwiseCopyable);
181178
if (!bitwiseCopyableProtocol) {

lib/AST/ProtocolConformance.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,10 +1284,7 @@ static SmallVector<ProtocolConformance *, 2> findSynthesizedConformances(
12841284
for (auto ip : InvertibleProtocolSet::allKnown())
12851285
trySynthesize(getKnownProtocolKind(ip));
12861286

1287-
if (nominal->getASTContext().LangOpts.hasFeature(
1288-
Feature::BitwiseCopyable)) {
1289-
trySynthesize(KnownProtocolKind::BitwiseCopyable);
1290-
}
1287+
trySynthesize(KnownProtocolKind::BitwiseCopyable);
12911288
}
12921289

12931290
/// Distributed actors can synthesize Encodable/Decodable, so look for those

lib/ClangImporter/ImportDecl.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8028,9 +8028,7 @@ ClangImporter::Implementation::importSwiftAttrAttributes(Decl *MappedDecl) {
80288028
continue;
80298029
}
80308030

8031-
if (swiftAttr->getAttribute() == "_BitwiseCopyable") {
8032-
if (!SwiftContext.LangOpts.hasFeature(Feature::BitwiseCopyable))
8033-
continue;
8031+
if (swiftAttr->getAttribute() == "BitwiseCopyable") {
80348032
auto *protocol =
80358033
SwiftContext.getProtocol(KnownProtocolKind::BitwiseCopyable);
80368034
auto *nominal = dyn_cast<NominalTypeDecl>(MappedDecl);

lib/SIL/IR/TypeLowering.cpp

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "swift/AST/DiagnosticEngine.h"
2121
#include "swift/AST/DiagnosticsSIL.h"
2222
#include "swift/AST/Expr.h"
23+
#include "swift/AST/FileUnit.h"
2324
#include "swift/AST/GenericEnvironment.h"
2425
#include "swift/AST/LocalArchetypeRequirementCollector.h"
2526
#include "swift/AST/Module.h"
@@ -28,6 +29,7 @@
2829
#include "swift/AST/Pattern.h"
2930
#include "swift/AST/PrettyStackTrace.h"
3031
#include "swift/AST/PropertyWrappers.h"
32+
#include "swift/AST/SourceFile.h"
3133
#include "swift/AST/TypeDifferenceVisitor.h"
3234
#include "swift/AST/Types.h"
3335
#include "swift/ClangImporter/ClangModule.h"
@@ -3041,8 +3043,6 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
30413043
AbstractionPattern origType,
30423044
CanType substType,
30433045
TypeExpansionContext forExpansion) {
3044-
if (!Context.LangOpts.hasFeature(Feature::BitwiseCopyable))
3045-
return;
30463046
auto *bitwiseCopyableProtocol =
30473047
Context.getProtocol(KnownProtocolKind::BitwiseCopyable);
30483048
if (!bitwiseCopyableProtocol)
@@ -3057,10 +3057,20 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
30573057

30583058
if (auto *nominal = substType.getAnyNominal()) {
30593059
auto *module = nominal->getModuleContext();
3060-
if (module && module->isBuiltFromInterface()) {
3061-
// Don't verify for types in modules built from interfaces; the feature
3062-
// may not have been enabled in them.
3063-
return;
3060+
if (module) {
3061+
if (module->isBuiltFromInterface()) {
3062+
// Don't verify for types in modules built from interfaces; the feature
3063+
// may not have been enabled in them.
3064+
return;
3065+
}
3066+
auto *file = dyn_cast_or_null<FileUnit>(module->getModuleScopeContext());
3067+
if (file && file->getKind() == FileUnitKind::Source) {
3068+
auto sourceFile = nominal->getParentSourceFile();
3069+
if (sourceFile && sourceFile->Kind == SourceFileKind::SIL) {
3070+
// Don't verify for types in SIL files.
3071+
return;
3072+
}
3073+
}
30643074
}
30653075
}
30663076

@@ -3086,6 +3096,7 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
30863096
// unconditionally but does in this case
30873097
// (8) being or containing the error type
30883098
// (9) explicitly suppressing conformance
3099+
// (10) a layout constrained archetype
30893100
bool hasNoNonconformingNode = visitAggregateLeaves(
30903101
origType, substType, forExpansion,
30913102
/*isLeafAggregate=*/
@@ -3155,7 +3166,7 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
31553166

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

3188+
// Case (10): a layout-constrained archetype.
3189+
if (auto archetype = dyn_cast<ArchetypeType>(ty)) {
3190+
auto constraint = archetype->getLayoutConstraint();
3191+
if (constraint && constraint->isTrivial()) {
3192+
return false;
3193+
}
3194+
}
3195+
31773196
auto *nominal = ty.getAnyNominal();
31783197

31793198
// Non-nominal types (besides case (3) handled above) are trivial iff
31803199
// conforming.
31813200
if (!nominal) {
31823201
llvm::errs()
3183-
<< "Non-nominal type without conformance to _BitwiseCopyable:\n"
3202+
<< "Non-nominal type without conformance to BitwiseCopyable:\n"
31843203
<< ty << "\n"
31853204
<< "within " << substType << "\n"
31863205
<< "of " << origType << "\n";
@@ -3291,7 +3310,7 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
32913310
return true;
32923311
});
32933312
if (hasNoConformingArchetypeNode) {
3294-
llvm::errs() << "Non-trivial type with _BitwiseCopyable conformance!?:\n"
3313+
llvm::errs() << "Non-trivial type with BitwiseCopyable conformance!?:\n"
32953314
<< substType << "\n";
32963315
conformance.print(llvm::errs());
32973316
llvm::errs() << "\n"

lib/Sema/TypeCheckBitwise.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,14 @@ static bool checkBitwiseCopyableInstanceStorage(NominalTypeDecl *nominal,
237237
return true;
238238
}
239239

240+
auto &attrs = nominal->getAttrs();
241+
if (attrs.hasAttribute<SensitiveAttr>()) {
242+
if (!isImplicit(check)) {
243+
conformanceDecl->diagnose(diag::non_bitwise_copyable_type_sensitive);
244+
}
245+
return true;
246+
}
247+
240248
if (dc->mapTypeIntoContext(nominal->getDeclaredInterfaceType())
241249
->isNoncopyable()) {
242250
// Already separately diagnosed when explicit.

lib/Sema/TypeCheckDecl.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -682,9 +682,9 @@ ExistentialConformsToSelfRequest::evaluate(Evaluator &evaluator,
682682
ProtocolDecl *decl) const {
683683
// Marker protocols always self-conform.
684684
if (decl->isMarkerProtocol()) {
685-
// Except for BitwiseCopyable an existential of which is non-trivial.
686-
if (decl->getASTContext().LangOpts.hasFeature(Feature::BitwiseCopyable) &&
687-
decl->getKnownProtocolKind() == KnownProtocolKind::BitwiseCopyable) {
685+
// Except for BitwiseCopyable an existential of which is not bitwise
686+
// copyable.
687+
if (decl->getKnownProtocolKind() == KnownProtocolKind::BitwiseCopyable) {
688688
return false;
689689
}
690690
return true;

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6117,11 +6117,9 @@ void TypeChecker::checkConformancesInContext(IterableDeclContext *idc) {
61176117
break;
61186118
}
61196119
case KnownProtocolKind::BitwiseCopyable: {
6120-
if (Context.LangOpts.hasFeature(Feature::BitwiseCopyable)) {
6121-
checkBitwiseCopyableConformance(
6122-
conformance, /*isImplicit=*/conformance->getSourceKind() ==
6123-
ConformanceEntryKind::Synthesized);
6124-
}
6120+
checkBitwiseCopyableConformance(
6121+
conformance, /*isImplicit=*/conformance->getSourceKind() ==
6122+
ConformanceEntryKind::Synthesized);
61256123
break;
61266124
}
61276125
default:

0 commit comments

Comments
 (0)