1818
1919#include " swift/AST/ConcreteDeclRef.h"
2020#include " swift/AST/Decl.h"
21+ #include " swift/AST/ProtocolConformanceOptions.h"
2122#include " swift/AST/Type.h"
2223#include " swift/AST/Types.h"
2324#include " swift/AST/TypeAlignments.h"
@@ -146,20 +147,21 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance
146147 SWIFT_INLINE_BITFIELD_EMPTY (RootProtocolConformance, ProtocolConformance);
147148
148149 SWIFT_INLINE_BITFIELD_FULL (NormalProtocolConformance, RootProtocolConformance,
149- 1 +1 +1 +1 +bitmax (NumProtocolConformanceStateBits,8 )+
150+ 1 +1 +
151+ bitmax (NumProtocolConformanceOptions,8 )+
152+ bitmax (NumProtocolConformanceStateBits,8 )+
150153 bitmax (NumConformanceEntryKindBits,8 ),
151154 // / Indicates whether the conformance is invalid.
152155 IsInvalid : 1 ,
153- // / The conformance was labeled with @unchecked.
154- IsUnchecked : 1 ,
155- // / The conformance was labeled with @preconcurrency.
156- IsPreconcurrency : 1 ,
157156 // / We have allocated the AssociatedConformances array (but not necessarily
158157 // / populated any of its elements).
159158 HasComputedAssociatedConformances : 1 ,
160159
161160 : NumPadBits,
162161
162+ // / Options.
163+ Options : bitmax (NumProtocolConformanceOptions, 8 ),
164+
163165 // / The current state of the conformance.
164166 State : bitmax (NumProtocolConformanceStateBits, 8 ),
165167 // / The reason that this conformance exists.
@@ -567,8 +569,8 @@ class NormalProtocolConformance : public RootProtocolConformance,
567569public:
568570 NormalProtocolConformance (Type conformingType, ProtocolDecl *protocol,
569571 SourceLoc loc, DeclContext *dc,
570- ProtocolConformanceState state, bool isUnchecked,
571- bool isPreconcurrency ,
572+ ProtocolConformanceState state,
573+ ProtocolConformanceOptions options ,
572574 SourceLoc preconcurrencyLoc)
573575 : RootProtocolConformance(ProtocolConformanceKind::Normal,
574576 conformingType),
@@ -577,12 +579,12 @@ class NormalProtocolConformance : public RootProtocolConformance,
577579 Context(dc) {
578580 assert (!conformingType->hasArchetype () &&
579581 " ProtocolConformances should store interface types" );
580- assert ((preconcurrencyLoc.isInvalid () || isPreconcurrency) &&
582+ assert ((preconcurrencyLoc.isInvalid () ||
583+ options.contains (ProtocolConformanceFlags::Preconcurrency)) &&
581584 " Cannot have a @preconcurrency location without isPreconcurrency" );
582585 setState (state);
583586 Bits.NormalProtocolConformance .IsInvalid = false ;
584- Bits.NormalProtocolConformance .IsUnchecked = isUnchecked;
585- Bits.NormalProtocolConformance .IsPreconcurrency = isPreconcurrency;
587+ Bits.NormalProtocolConformance .Options = options.toRaw ();
586588 Bits.NormalProtocolConformance .HasComputedAssociatedConformances = false ;
587589 Bits.NormalProtocolConformance .SourceKind =
588590 unsigned (ConformanceEntryKind::Explicit);
@@ -626,27 +628,42 @@ class NormalProtocolConformance : public RootProtocolConformance,
626628 // / Mark this conformance as invalid.
627629 void setInvalid () { Bits.NormalProtocolConformance .IsInvalid = true ; }
628630
631+ ProtocolConformanceOptions getOptions () const {
632+ return ProtocolConformanceOptions (Bits.NormalProtocolConformance .Options );
633+ }
634+
629635 // / Whether this is an "unchecked" conformance.
630636 bool isUnchecked () const {
631- return Bits. NormalProtocolConformance . IsUnchecked ;
637+ return getOptions (). contains (ProtocolConformanceFlags::Unchecked) ;
632638 }
633639
634640 // / Mark the conformance as unchecked (equivalent to the @unchecked
635641 // / conformance attribute).
636642 void setUnchecked () {
637643 // OK to mutate because the flags are not part of the folding set node ID.
638- Bits.NormalProtocolConformance .IsUnchecked = true ;
644+ Bits.NormalProtocolConformance .Options =
645+ (getOptions () | ProtocolConformanceFlags::Unchecked).toRaw ();
639646 }
640647
641648 // / Whether this is an preconcurrency conformance.
642649 bool isPreconcurrency () const {
643- return Bits. NormalProtocolConformance . IsPreconcurrency ;
650+ return getOptions (). contains (ProtocolConformanceFlags::Preconcurrency) ;
644651 }
645652
646653 // / Retrieve the location of `@preconcurrency`, if there is one and it is
647654 // / known.
648655 SourceLoc getPreconcurrencyLoc () const { return PreconcurrencyLoc; }
649656
657+ // / Whether this is an "unsafe" conformance.
658+ bool isUnsafe () const {
659+ return getOptions ().contains (ProtocolConformanceFlags::Unsafe);
660+ }
661+
662+ // / Whether this is an "safe(unchecked)" conformance.
663+ bool isSafe () const {
664+ return getOptions ().contains (ProtocolConformanceFlags::Safe);
665+ }
666+
650667 // / Determine whether we've lazily computed the associated conformance array
651668 // / already.
652669 bool hasComputedAssociatedConformances () const {
@@ -684,8 +701,8 @@ class NormalProtocolConformance : public RootProtocolConformance,
684701 if (auto implying = implyingConformance) {
685702 ImplyingConformance = implying;
686703 PreconcurrencyLoc = implying->getPreconcurrencyLoc ();
687- Bits.NormalProtocolConformance .IsPreconcurrency =
688- implying-> isPreconcurrency ();
704+ Bits.NormalProtocolConformance .Options =
705+ implyingConformance-> getOptions (). toRaw ();
689706 }
690707 }
691708
0 commit comments