diff --git a/Sources/_StringProcessing/Engine/InstPayload.swift b/Sources/_StringProcessing/Engine/InstPayload.swift index 550fa4915..0a4df998c 100644 --- a/Sources/_StringProcessing/Engine/InstPayload.swift +++ b/Sources/_StringProcessing/Engine/InstPayload.swift @@ -552,7 +552,7 @@ struct QuantifyPayload: RawRepresentable { } var builtinCC: _CharacterClassModel.Representation { - _CharacterClassModel.Representation(rawValue: self.rawValue & 0xFF)! + _uncheckedRawEnum(self.rawValue & 0xFF) } var builtinIsInverted: Bool { (self.rawValue >> 9) & 1 == 1 @@ -596,8 +596,7 @@ struct CharacterClassPayload: RawRepresentable { self.rawValue & CharacterClassPayload.scalarBit != 0 } var cc: _CharacterClassModel.Representation { - _CharacterClassModel.Representation.init( - rawValue: self.rawValue & CharacterClassPayload.ccMask).unsafelyUnwrapped + _uncheckedRawEnum(self.rawValue & CharacterClassPayload.ccMask) } } @@ -636,8 +635,7 @@ struct AssertionPayload: RawRepresentable { } var kind: DSLTree.Atom.Assertion { - return .init( - rawValue: self.rawValue & AssertionPayload.assertionKindMask).unsafelyUnwrapped + _uncheckedRawEnum(self.rawValue & AssertionPayload.assertionKindMask) } var anchorsMatchNewlines: Bool { self.rawValue & AssertionPayload.anchorBit != 0 } var usesSimpleUnicodeBoundaries: Bool { diff --git a/Sources/_StringProcessing/Engine/Instruction.swift b/Sources/_StringProcessing/Engine/Instruction.swift index 80bfd9b05..66416106d 100644 --- a/Sources/_StringProcessing/Engine/Instruction.swift +++ b/Sources/_StringProcessing/Engine/Instruction.swift @@ -279,9 +279,9 @@ extension Instruction { var opcode: OpCode { get { - OpCode( - rawValue: (rawValue & _opcodeMask) &>> 56 - ).unsafelyUnwrapped + // Every instruction is built from a real case, with the payload inside 56 bits, + // so the opcode byte is always a valid case index. + _uncheckedRawEnum(rawValue &>> 56) } set { assert(newValue != .invalid, "consider hoisting this") diff --git a/Sources/_StringProcessing/Utility/Misc.swift b/Sources/_StringProcessing/Utility/Misc.swift index d63370b55..749288672 100644 --- a/Sources/_StringProcessing/Utility/Misc.swift +++ b/Sources/_StringProcessing/Utility/Misc.swift @@ -76,4 +76,18 @@ extension String { } } - +/// Converts a raw value into a single-byte enum without going through +/// its checked initializer. +/// +/// - Precondition: `rawValue` is the raw value of a case of `T`, and `T` is +/// a no-payload enum laid out as a single byte. +@inline(__always) +//@unsafe +internal func _uncheckedRawEnum( + _ rawValue: UInt64, as _: T.Type = T.self +) -> T where T.RawValue == UInt64 { + let result = unsafeBitCast(UInt8(truncatingIfNeeded: rawValue), to: T.self) + assert(result.rawValue == rawValue, + "\(T.self) is no longer laid out as its contiguous case index") + return result +}