Skip to content

Commit dc51950

Browse files
committed
Add '@_alwaysEmitConformanceMetadata' protocol attribute
This attribute will, in the near future, be used to inform IRGen that a nominal type that conforms to such protocol must have its type metadata always emitted into the binary, regardless of whether it is used/public.
1 parent 78f5e0b commit dc51950

File tree

7 files changed

+25
-2
lines changed

7 files changed

+25
-2
lines changed

docs/ReferenceGuides/UnderscoredAttributes.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,3 +852,8 @@ the distributed actor isolation checks. This is used for things like `whenLocal`
852852
where the actor passed to the closure is known-to-be-local, and similarly a
853853
`self` of obtained from an _isolated_ function inside a distributed actor is
854854
also guaranteed to be local by construction.
855+
856+
857+
## `@_alwaysEmitConformanceMetadata`
858+
859+
Forces conformances of the attributed protocol to always have their Type Metadata get emitted into the binary and prevents it from being optimized away or stripped by the linker.

include/swift/AST/Attr.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,10 @@ SIMPLE_DECL_ATTR(_moveOnly, MoveOnly,
740740
UserInaccessible |
741741
ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove,
742742
131)
743+
744+
SIMPLE_DECL_ATTR(_alwaysEmitConformanceMetadata, AlwaysEmitConformanceMetadata,
745+
OnProtocol | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
746+
132)
743747

744748
// If you're adding a new underscored attribute here, please document it in
745749
// docs/ReferenceGuides/UnderscoredAttributes.md.

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,6 +1415,9 @@ ERROR(transparent_in_protocols_not_supported,none,
14151415
ERROR(transparent_in_classes_not_supported,none,
14161416
"'@_transparent' attribute is not supported on declarations within classes", ())
14171417

1418+
ERROR(always_emit_conformance_attr_protocols_only,none,
1419+
"'@_alwaysEmitConformanceMetadata' attribute is only valid on protocol declarations", ())
1420+
14181421
ERROR(iboutlet_nonobjc_class,none,
14191422
"@IBOutlet property cannot %select{have|be an array of}0 "
14201423
"non-'@objc' class type %1", (bool, Type))

lib/AST/Attr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1269,7 +1269,7 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
12691269
Printer << ")";
12701270
break;
12711271
}
1272-
1272+
// ACTODO
12731273
case DAK_Count:
12741274
llvm_unreachable("exceed declaration attribute kinds");
12751275

lib/Sema/TypeCheckAttr.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,8 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
311311
void visitNonisolatedAttr(NonisolatedAttr *attr);
312312

313313
void visitNoImplicitCopyAttr(NoImplicitCopyAttr *attr);
314+
315+
void visitAlwaysEmitConformanceMetadataAttr(AlwaysEmitConformanceMetadataAttr *attr);
314316

315317
void visitUnavailableFromAsyncAttr(UnavailableFromAsyncAttr *attr);
316318

@@ -381,6 +383,14 @@ void AttributeChecker::visitNoImplicitCopyAttr(NoImplicitCopyAttr *attr) {
381383
}
382384
}
383385

386+
void AttributeChecker::visitAlwaysEmitConformanceMetadataAttr(AlwaysEmitConformanceMetadataAttr *attr) {
387+
DeclContext *dc = D->getDeclContext();
388+
// Only protocol declarations can be annotated `_alwaysEmitConformanceMetadata`
389+
if (!isa<ProtocolDecl>(dc))
390+
diagnoseAndRemoveAttr(attr, diag::always_emit_conformance_attr_protocols_only);
391+
return;
392+
}
393+
384394
void AttributeChecker::visitTransparentAttr(TransparentAttr *attr) {
385395
DeclContext *dc = D->getDeclContext();
386396
// Protocol declarations cannot be transparent.

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1612,6 +1612,7 @@ namespace {
16121612

16131613
UNINTERESTING_ATTR(UnsafeInheritExecutor)
16141614
UNINTERESTING_ATTR(CompilerInitialized)
1615+
UNINTERESTING_ATTR(AlwaysEmitConformanceMetadata)
16151616
#undef UNINTERESTING_ATTR
16161617

16171618
void visitAvailableAttr(AvailableAttr *attr) {

lib/Serialization/ModuleFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5858
/// describe what change you made. The content of this comment isn't important;
5959
/// it just ensures a conflict if two people change the module format.
6060
/// Don't worry about adhering to the 80-column limit for this line.
61-
const uint16_t SWIFTMODULE_VERSION_MINOR = 698; // opaque decl with unavailability conditions
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 699; // @_alwaysEmitConformanceMetadata
6262

6363
/// A standard hash seed used for all string hashes in a serialized module.
6464
///

0 commit comments

Comments
 (0)