And yet, it's part of the standard library as the OptionSet
protocol, and baked into the C interoperability story. The proposed macro makes it easier to define new types that fit in with the standard library's notion of an OptionSet
, something that is currently error-prone and tedious. The alternative you are proposing doesn't exist, and (without further extension) delegates control over layout to the Swift compiler.
Sometimes you do want low-level control over bit placements. I think of how extensively we use the C++ FlagSet
in the runtime to provide an abstraction over a specific layout of flags in a fixed-sized integer, and I want to be able to do that in Swift (with less boilerplate). A FlagSet
-style macro could follow the same general pattern of the OptionSet
macro (especially with the revised formulation that ditches the nested enum
), but with annotations on properties to provide bit positions and widths:
@FlagSet<UInt16>
struct TypeContextDescriptorFlags {
@Bitfield(width: 2)
var metadataInitialization: MetadataInitialization
var hasImportInfo: Bool
var hasCanonicalMetadataPrespecializations: Bool
var hasLayoutString: Bool
@Bitfield(bit: 7)
var isActor: Bool
var isDefaultActor: Bool
@Bitfield(width: 3)
var resilientSuperclassReferenceKind: TypeReferenceKind
var ImmediateMembersNegative: Bool
var hasResilientSuperclass: Bool
var hasOverrideTable: Bool
var hasVTable: Bool
}
The corresponding C++ definition of this ABI type is here. We can provide better checking within the macro to ensure that bitfields aren't overlapping, don't run over the end of the raw type, etc.
How many language extensions would we need to be able to express the TypeContextDescriptorFlags
above as a simple struct? I can write that today with macros (might be fun), and I feel like that's the whole point of macros---that we don't need to wait for a future language feature to make things automatic, because we can build it now out of existing pieces.
Doug