diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index 27e455458eb1a..3e0160aca3733 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -318,6 +318,11 @@ class RecursiveTypeProperties { Bits &= ~HasDependentMember; } + /// Remove the IsUnsafe property from this set. + void removeIsUnsafe() { + Bits &= ~IsUnsafe; + } + /// Test for a particular property in this set. bool operator&(Property prop) const { return Bits & prop; diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 0abb432390de1..892209281dfe6 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -3543,6 +3543,12 @@ TypeAliasType *TypeAliasType::get(TypeAliasDecl *typealias, Type parent, auto &ctx = underlying->getASTContext(); auto arena = getArena(properties); + // Typealiases can't meaningfully be unsafe; it's the underlying type that + // matters. + properties.removeIsUnsafe(); + if (underlying->isUnsafe()) + properties |= RecursiveTypeProperties::IsUnsafe; + // Profile the type. llvm::FoldingSetNodeID id; TypeAliasType::Profile(id, typealias, parent, genericArgs, underlying); @@ -4190,6 +4196,54 @@ void UnboundGenericType::Profile(llvm::FoldingSetNodeID &ID, ID.AddPointer(Parent.getPointer()); } +/// The safety of a parent type does not have an impact on a nested type within +/// it. This produces the recursive properties of a given type that should +/// be propagated to a nested type, which won't include any "IsUnsafe" bit +/// determined based on the declaration itself. +static RecursiveTypeProperties getRecursivePropertiesAsParent(Type type) { + if (!type) + return RecursiveTypeProperties(); + + // We only need to do anything interesting at all for unsafe types. + auto properties = type->getRecursiveProperties(); + if (!properties.isUnsafe()) + return properties; + + if (auto nominal = type->getAnyNominal()) { + // If the nominal wasn't itself unsafe, then we got the unsafety from + // something else (e.g., a generic argument), so it won't change. + if (nominal->getExplicitSafety() != ExplicitSafety::Unsafe) + return properties; + } + + // Drop the "unsafe" bit. We have to recompute it without considering the + // enclosing nominal type. + properties.removeIsUnsafe(); + + // Check generic arguments of parent types. + while (type) { + // Merge from the generic arguments. + if (auto boundGeneric = type->getAs()) { + for (auto genericArg : boundGeneric->getGenericArgs()) + properties |= genericArg->getRecursiveProperties(); + } + + if (auto nominalOrBound = type->getAs()) { + type = nominalOrBound->getParent(); + continue; + } + + if (auto unbound = type->getAs()) { + type = unbound->getParent(); + continue; + } + + break; + }; + + return properties; +} + UnboundGenericType *UnboundGenericType:: get(GenericTypeDecl *TheDecl, Type Parent, const ASTContext &C) { llvm::FoldingSetNodeID ID; @@ -4198,7 +4252,7 @@ get(GenericTypeDecl *TheDecl, Type Parent, const ASTContext &C) { RecursiveTypeProperties properties; if (TheDecl->getExplicitSafety() == ExplicitSafety::Unsafe) properties |= RecursiveTypeProperties::IsUnsafe; - if (Parent) properties |= Parent->getRecursiveProperties(); + properties |= getRecursivePropertiesAsParent(Parent); auto arena = getArena(properties); @@ -4252,7 +4306,7 @@ BoundGenericType *BoundGenericType::get(NominalTypeDecl *TheDecl, RecursiveTypeProperties properties; if (TheDecl->getExplicitSafety() == ExplicitSafety::Unsafe) properties |= RecursiveTypeProperties::IsUnsafe; - if (Parent) properties |= Parent->getRecursiveProperties(); + properties |= getRecursivePropertiesAsParent(Parent); for (Type Arg : GenericArgs) { properties |= Arg->getRecursiveProperties(); } @@ -4335,7 +4389,7 @@ EnumType *EnumType::get(EnumDecl *D, Type Parent, const ASTContext &C) { RecursiveTypeProperties properties; if (D->getExplicitSafety() == ExplicitSafety::Unsafe) properties |= RecursiveTypeProperties::IsUnsafe; - if (Parent) properties |= Parent->getRecursiveProperties(); + properties |= getRecursivePropertiesAsParent(Parent); auto arena = getArena(properties); auto *&known = C.getImpl().getArena(arena).EnumTypes[{D, Parent}]; @@ -4353,7 +4407,7 @@ StructType *StructType::get(StructDecl *D, Type Parent, const ASTContext &C) { RecursiveTypeProperties properties; if (D->getExplicitSafety() == ExplicitSafety::Unsafe) properties |= RecursiveTypeProperties::IsUnsafe; - if (Parent) properties |= Parent->getRecursiveProperties(); + properties |= getRecursivePropertiesAsParent(Parent); auto arena = getArena(properties); auto *&known = C.getImpl().getArena(arena).StructTypes[{D, Parent}]; @@ -4371,7 +4425,7 @@ ClassType *ClassType::get(ClassDecl *D, Type Parent, const ASTContext &C) { RecursiveTypeProperties properties; if (D->getExplicitSafety() == ExplicitSafety::Unsafe) properties |= RecursiveTypeProperties::IsUnsafe; - if (Parent) properties |= Parent->getRecursiveProperties(); + properties |= getRecursivePropertiesAsParent(Parent); auto arena = getArena(properties); auto *&known = C.getImpl().getArena(arena).ClassTypes[{D, Parent}]; @@ -5538,7 +5592,7 @@ ProtocolType *ProtocolType::get(ProtocolDecl *D, Type Parent, RecursiveTypeProperties properties; if (D->getExplicitSafety() == ExplicitSafety::Unsafe) properties |= RecursiveTypeProperties::IsUnsafe; - if (Parent) properties |= Parent->getRecursiveProperties(); + properties |= getRecursivePropertiesAsParent(Parent); auto arena = getArena(properties); auto *&known = C.getImpl().getArena(arena).ProtocolTypes[{D, Parent}]; diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index c968958623f97..04046f8482ab7 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -1212,12 +1212,14 @@ ExplicitSafety Decl::getExplicitSafety() const { ExplicitSafety::Unspecified); } - // Inference: Check the enclosing context. - if (auto enclosingDC = getDeclContext()) { - // Is this an extension with @safe or @unsafe on it? - if (auto ext = dyn_cast(enclosingDC)) { - if (auto extSafety = getExplicitSafetyFromAttrs(ext)) - return *extSafety; + // Inference: Check the enclosing context, unless this is a type. + if (!isa(this)) { + if (auto enclosingDC = getDeclContext()) { + // Is this an extension with @safe or @unsafe on it? + if (auto ext = dyn_cast(enclosingDC)) { + if (auto extSafety = getExplicitSafetyFromAttrs(ext)) + return *extSafety; + } } } diff --git a/lib/Sema/TypeCheckEffects.cpp b/lib/Sema/TypeCheckEffects.cpp index 9a23b3b8a66ec..1c823f41f83b4 100644 --- a/lib/Sema/TypeCheckEffects.cpp +++ b/lib/Sema/TypeCheckEffects.cpp @@ -670,6 +670,8 @@ class EffectsHandlingWalker : public ASTWalker { recurse = asImpl().checkForEach(forEach); } else if (auto labeled = dyn_cast(S)) { asImpl().noteLabeledConditionalStmt(labeled); + } else if (auto defer = dyn_cast(S)) { + recurse = asImpl().checkDefer(defer); } if (!recurse) @@ -2110,6 +2112,10 @@ class ApplyClassifier { return ShouldRecurse; } + ShouldRecurse_t checkDefer(DeferStmt *S) { + return ShouldNotRecurse; + } + ShouldRecurse_t checkSingleValueStmtExpr(SingleValueStmtExpr *SVE) { return ShouldRecurse; } @@ -2255,6 +2261,10 @@ class ApplyClassifier { return ShouldRecurse; } + ShouldRecurse_t checkDefer(DeferStmt *S) { + return ShouldNotRecurse; + } + ShouldRecurse_t checkSingleValueStmtExpr(SingleValueStmtExpr *SVE) { return ShouldRecurse; } @@ -2354,6 +2364,10 @@ class ApplyClassifier { return ShouldNotRecurse; } + ShouldRecurse_t checkDefer(DeferStmt *S) { + return ShouldNotRecurse; + } + ShouldRecurse_t checkSingleValueStmtExpr(SingleValueStmtExpr *SVE) { return ShouldRecurse; } @@ -4398,6 +4412,17 @@ class CheckEffectsCoverage : public EffectsHandlingWalker return ShouldRecurse; } + ShouldRecurse_t checkDefer(DeferStmt *S) { + // Pretend we're in an 'unsafe'. + ContextScope scope(*this, std::nullopt); + scope.enterUnsafe(S->getDeferLoc()); + + // Walk the call expression. We don't care about the rest. + S->getCallExpr()->walk(*this); + + return ShouldNotRecurse; + } + void diagnoseRedundantTry(AnyTryExpr *E) const { if (auto *SVE = SingleValueStmtExpr::tryDigOutSingleValueStmtExpr(E)) { // For an if/switch expression, produce a tailored warning. diff --git a/lib/Sema/TypeCheckUnsafe.cpp b/lib/Sema/TypeCheckUnsafe.cpp index c9ef7d913f175..4273123e91e65 100644 --- a/lib/Sema/TypeCheckUnsafe.cpp +++ b/lib/Sema/TypeCheckUnsafe.cpp @@ -330,7 +330,12 @@ bool swift::enumerateUnsafeUses(ArrayRef conformances, bool swift::enumerateUnsafeUses(SubstitutionMap subs, SourceLoc loc, llvm::function_ref fn) { - // FIXME: Check replacement types? + // Replacement types. + for (auto replacementType : subs.getReplacementTypes()) { + if (replacementType->isUnsafe() && + fn(UnsafeUse::forReferenceToUnsafe(nullptr, false, replacementType, loc))) + return true; + } // Check conformances. if (enumerateUnsafeUses(subs.getConformances(), loc, fn)) @@ -375,21 +380,73 @@ void swift::diagnoseUnsafeType(ASTContext &ctx, SourceLoc loc, Type type, if (!ctx.LangOpts.hasFeature(Feature::StrictMemorySafety)) return; - if (!type->isUnsafe() && !type->getCanonicalType()->isUnsafe()) + if (!type->isUnsafe()) return; - // Look for a specific @unsafe nominal type. - Type specificType; - type.findIf([&specificType](Type type) { - if (auto typeDecl = type->getAnyNominal()) { - if (typeDecl->getExplicitSafety() == ExplicitSafety::Unsafe) { - specificType = type; - return false; + // Look for a specific @unsafe nominal type along the way. + class Walker : public TypeWalker { + public: + Type specificType; + + Action walkToTypePre(Type type) override { + if (specificType) + return Action::Stop; + + // If this refers to a nominal type that is @unsafe, store that. + if (auto typeDecl = type->getAnyNominal()) { + if (typeDecl->getExplicitSafety() == ExplicitSafety::Unsafe) { + specificType = type; + return Action::Stop; + } + } + + // Do not recurse into nominal types, because we do not want to visit + // their "parent" types. + if (isa(type.getPointer()) || + isa(type.getPointer())) { + // Recurse into the generic arguments. This operation is recursive, + // because we also need to see the generic arguments of parent types. + walkGenericArguments(type); + + return Action::SkipNode; + } + + return Action::Continue; + } + + private: + /// Recursively walk the generic arguments of this type and its parent + /// types. + void walkGenericArguments(Type type) { + if (!type) + return; + + // Walk the generic arguments. + if (auto boundGeneric = type->getAs()) { + for (auto genericArg : boundGeneric->getGenericArgs()) + genericArg.walk(*this); } + + if (auto nominalOrBound = type->getAs()) + return walkGenericArguments(nominalOrBound->getParent()); + + if (auto unbound = type->getAs()) + return walkGenericArguments(unbound->getParent()); } + }; - return false; - }); + // Look for a canonical unsafe type. + Walker walker; + type->getCanonicalType().walk(walker); + Type specificType = walker.specificType; + + // Look for an unsafe type in the non-canonical type, which is a better answer + // if we can find it. + walker.specificType = Type(); + type.walk(walker); + if (specificType && walker.specificType && + specificType->isEqual(walker.specificType)) + specificType = walker.specificType; diagnose(specificType ? specificType : type); } diff --git a/stdlib/public/Concurrency/Deque/Deque+UnsafeHandle.swift b/stdlib/public/Concurrency/Deque/Deque+UnsafeHandle.swift index 683b5a2b264fc..8fe4b07e467f6 100644 --- a/stdlib/public/Concurrency/Deque/Deque+UnsafeHandle.swift +++ b/stdlib/public/Concurrency/Deque/Deque+UnsafeHandle.swift @@ -63,7 +63,7 @@ extension _Deque._UnsafeHandle { var startSlot: Slot { get { unsafe _header.pointee.startSlot } - nonmutating set { unsafe _header.pointee.startSlot = unsafe newValue } + nonmutating set { unsafe _header.pointee.startSlot = newValue } } func ptr(at slot: Slot) -> UnsafeMutablePointer { @@ -99,28 +99,28 @@ extension _Deque._UnsafeHandle { internal func slot(after slot: Slot) -> Slot { unsafe assert(slot.position < capacity) - let position = unsafe slot.position + 1 + let position = slot.position + 1 if unsafe position >= capacity { - return unsafe Slot(at: 0) + return Slot(at: 0) } - return unsafe Slot(at: position) + return Slot(at: position) } internal func slot(before slot: Slot) -> Slot { unsafe assert(slot.position < capacity) - if unsafe slot.position == 0 { return unsafe Slot(at: capacity - 1) } - return unsafe Slot(at: slot.position - 1) + if slot.position == 0 { return unsafe Slot(at: capacity - 1) } + return Slot(at: slot.position - 1) } internal func slot(_ slot: Slot, offsetBy delta: Int) -> Slot { unsafe assert(slot.position <= capacity) - let position = unsafe slot.position + delta + let position = slot.position + delta if delta >= 0 { if unsafe position >= capacity { return unsafe Slot(at: position - capacity) } } else { if position < 0 { return unsafe Slot(at: position + capacity) } } - return unsafe Slot(at: position) + return Slot(at: position) } internal var endSlot: Slot { @@ -139,7 +139,7 @@ extension _Deque._UnsafeHandle { // random-access subscript operations. (Up to 2x on some microbenchmarks.) let position = unsafe startSlot.position &+ offset guard unsafe position < capacity else { return unsafe Slot(at: position &- capacity) } - return unsafe Slot(at: position) + return Slot(at: position) } } @@ -199,9 +199,9 @@ extension _Deque._UnsafeHandle { from source: UnsafeBufferPointer ) -> Slot { unsafe assert(start.position + source.count <= capacity) - guard source.count > 0 else { return unsafe start } + guard source.count > 0 else { return start } unsafe ptr(at: start).initialize(from: source.baseAddress!, count: source.count) - return unsafe Slot(at: start.position + source.count) + return Slot(at: start.position + source.count) } @discardableResult @@ -210,9 +210,9 @@ extension _Deque._UnsafeHandle { from source: UnsafeMutableBufferPointer ) -> Slot { unsafe assert(start.position + source.count <= capacity) - guard source.count > 0 else { return unsafe start } + guard source.count > 0 else { return start } unsafe ptr(at: start).moveInitialize(from: source.baseAddress!, count: source.count) - return unsafe Slot(at: start.position + source.count) + return Slot(at: start.position + source.count) } @discardableResult @@ -224,7 +224,7 @@ extension _Deque._UnsafeHandle { assert(count >= 0) unsafe assert(source.position + count <= self.capacity) unsafe assert(target.position + count <= self.capacity) - guard count > 0 else { return unsafe (source, target) } + guard count > 0 else { return (source, target) } unsafe ptr(at: target).moveInitialize(from: ptr(at: source), count: count) return unsafe (slot(source, offsetBy: count), slot(target, offsetBy: count)) } @@ -451,7 +451,7 @@ extension _Deque._UnsafeHandle { ) -> _UnsafeMutableWrappedBuffer { unsafe assert(start.position <= capacity) unsafe assert(end.position <= capacity) - if unsafe start < end { + if start < end { return unsafe .init(start: ptr(at: start), count: end.position - start.position) } return unsafe .init( diff --git a/stdlib/public/Concurrency/Task.swift b/stdlib/public/Concurrency/Task.swift index 044571a82a702..bd1ed5e1650a1 100644 --- a/stdlib/public/Concurrency/Task.swift +++ b/stdlib/public/Concurrency/Task.swift @@ -261,7 +261,7 @@ extension Task where Failure == Never { @available(SwiftStdlib 5.1, *) extension Task: Hashable { public func hash(into hasher: inout Hasher) { - unsafe UnsafeRawPointer(Builtin.bridgeToRawPointer(_task)).hash(into: &hasher) + UnsafeRawPointer(Builtin.bridgeToRawPointer(_task)).hash(into: &hasher) } } diff --git a/stdlib/public/Synchronization/Atomics/AtomicPointers.swift b/stdlib/public/Synchronization/Atomics/AtomicPointers.swift index 2c5e4b06e9ac2..286c1ba9afa95 100644 --- a/stdlib/public/Synchronization/Atomics/AtomicPointers.swift +++ b/stdlib/public/Synchronization/Atomics/AtomicPointers.swift @@ -822,7 +822,7 @@ extension UnsafeBufferPointer: @unsafe AtomicRepresentable where Element: ~Copya public static func decodeAtomicRepresentation( _ representation: consuming AtomicRepresentation ) -> UnsafeBufferPointer { - let wp = unsafe WordPair.decodeAtomicRepresentation(representation) + let wp = WordPair.decodeAtomicRepresentation(representation) return unsafe UnsafeBufferPointer( start: UnsafePointer(bitPattern: wp.first), @@ -890,7 +890,7 @@ where Element: ~Copyable public static func decodeAtomicRepresentation( _ representation: consuming AtomicRepresentation ) -> UnsafeMutableBufferPointer { - let wp = unsafe WordPair.decodeAtomicRepresentation(representation) + let wp = WordPair.decodeAtomicRepresentation(representation) return unsafe UnsafeMutableBufferPointer( start: UnsafeMutablePointer(bitPattern: wp.first), @@ -956,7 +956,7 @@ extension UnsafeRawBufferPointer: @unsafe AtomicRepresentable { public static func decodeAtomicRepresentation( _ representation: consuming AtomicRepresentation ) -> UnsafeRawBufferPointer { - let wp = unsafe WordPair.decodeAtomicRepresentation(representation) + let wp = WordPair.decodeAtomicRepresentation(representation) return unsafe UnsafeRawBufferPointer( start: UnsafeRawPointer(bitPattern: wp.first), @@ -1022,7 +1022,7 @@ extension UnsafeMutableRawBufferPointer: @unsafe AtomicRepresentable { public static func decodeAtomicRepresentation( _ representation: consuming AtomicRepresentation ) -> UnsafeMutableRawBufferPointer { - let wp = unsafe WordPair.decodeAtomicRepresentation(representation) + let wp = WordPair.decodeAtomicRepresentation(representation) return unsafe UnsafeMutableRawBufferPointer( start: UnsafeMutableRawPointer(bitPattern: wp.first), diff --git a/stdlib/public/core/ArrayBuffer.swift b/stdlib/public/core/ArrayBuffer.swift index 777d868016eeb..e0b49bcb2c261 100644 --- a/stdlib/public/core/ArrayBuffer.swift +++ b/stdlib/public/core/ArrayBuffer.swift @@ -330,7 +330,7 @@ extension _ArrayBuffer { .assumingMemoryBound(to: AnyObject.self) let (_, c) = unsafe _nonNative._copyContents( initializing: UnsafeMutableBufferPointer(start: ptr, count: buffer.count)) - return unsafe (IndexingIterator(_elements: self, _position: c), c) + return (IndexingIterator(_elements: self, _position: c), c) } /// Returns a `_SliceBuffer` containing the given sub-range of elements in diff --git a/stdlib/public/core/Bitset.swift b/stdlib/public/core/Bitset.swift index 1d38caf2a5a43..300e05e9dcffb 100644 --- a/stdlib/public/core/Bitset.swift +++ b/stdlib/public/core/Bitset.swift @@ -45,7 +45,7 @@ extension _UnsafeBitset { _internalInvariant(element >= 0) // Note: We perform on UInts to get faster unsigned math (shifts). let element = UInt(bitPattern: element) - let capacity = unsafe UInt(bitPattern: Word.capacity) + let capacity = UInt(bitPattern: Word.capacity) return Int(bitPattern: element / capacity) } @@ -55,7 +55,7 @@ extension _UnsafeBitset { _internalInvariant(element >= 0) // Note: We perform on UInts to get faster unsigned math (masking). let element = UInt(bitPattern: element) - let capacity = unsafe UInt(bitPattern: Word.capacity) + let capacity = UInt(bitPattern: Word.capacity) return Int(bitPattern: element % capacity) } @@ -68,8 +68,8 @@ extension _UnsafeBitset { @inlinable @inline(__always) internal static func join(word: Int, bit: Int) -> Int { - unsafe _internalInvariant(bit >= 0 && bit < Word.capacity) - return unsafe word &* Word.capacity &+ bit + _internalInvariant(bit >= 0 && bit < Word.capacity) + return word &* Word.capacity &+ bit } } @@ -84,7 +84,7 @@ extension _UnsafeBitset { internal var capacity: Int { @inline(__always) get { - return unsafe wordCount &* Word.capacity + return wordCount &* Word.capacity } } @@ -199,7 +199,7 @@ extension _UnsafeBitset { @inlinable internal init(_ value: UInt) { - unsafe self.value = value + self.value = value } } } @@ -217,7 +217,7 @@ extension _UnsafeBitset.Word { @inline(__always) internal func uncheckedContains(_ bit: Int) -> Bool { _internalInvariant(bit >= 0 && bit < UInt.bitWidth) - return unsafe value & (1 &<< bit) != 0 + return value & (1 &<< bit) != 0 } @inlinable @@ -226,8 +226,8 @@ extension _UnsafeBitset.Word { internal mutating func uncheckedInsert(_ bit: Int) -> Bool { _internalInvariant(bit >= 0 && bit < UInt.bitWidth) let mask: UInt = 1 &<< bit - let inserted = unsafe value & mask == 0 - unsafe value |= mask + let inserted = value & mask == 0 + value |= mask return inserted } @@ -237,8 +237,8 @@ extension _UnsafeBitset.Word { internal mutating func uncheckedRemove(_ bit: Int) -> Bool { _internalInvariant(bit >= 0 && bit < UInt.bitWidth) let mask: UInt = 1 &<< bit - let removed = unsafe value & mask != 0 - unsafe value &= ~mask + let removed = value & mask != 0 + value &= ~mask return removed } } @@ -248,8 +248,8 @@ extension _UnsafeBitset.Word { var minimum: Int? { @inline(__always) get { - guard unsafe value != 0 else { return nil } - return unsafe value.trailingZeroBitCount + guard value != 0 else { return nil } + return value.trailingZeroBitCount } } @@ -257,8 +257,8 @@ extension _UnsafeBitset.Word { var maximum: Int? { @inline(__always) get { - guard unsafe value != 0 else { return nil } - return unsafe _UnsafeBitset.Word.capacity &- 1 &- value.leadingZeroBitCount + guard value != 0 else { return nil } + return _UnsafeBitset.Word.capacity &- 1 &- value.leadingZeroBitCount } } @@ -266,32 +266,32 @@ extension _UnsafeBitset.Word { var complement: _UnsafeBitset.Word { @inline(__always) get { - return unsafe _UnsafeBitset.Word(~value) + return _UnsafeBitset.Word(~value) } } @inlinable @inline(__always) internal func subtracting(elementsBelow bit: Int) -> _UnsafeBitset.Word { - unsafe _internalInvariant(bit >= 0 && bit < _UnsafeBitset.Word.capacity) + _internalInvariant(bit >= 0 && bit < _UnsafeBitset.Word.capacity) let mask = UInt.max &<< bit - return unsafe _UnsafeBitset.Word(value & mask) + return _UnsafeBitset.Word(value & mask) } @inlinable @inline(__always) internal func intersecting(elementsBelow bit: Int) -> _UnsafeBitset.Word { - unsafe _internalInvariant(bit >= 0 && bit < _UnsafeBitset.Word.capacity) + _internalInvariant(bit >= 0 && bit < _UnsafeBitset.Word.capacity) let mask: UInt = (1 as UInt &<< bit) &- 1 - return unsafe _UnsafeBitset.Word(value & mask) + return _UnsafeBitset.Word(value & mask) } @inlinable @inline(__always) internal func intersecting(elementsAbove bit: Int) -> _UnsafeBitset.Word { - unsafe _internalInvariant(bit >= 0 && bit < _UnsafeBitset.Word.capacity) + _internalInvariant(bit >= 0 && bit < _UnsafeBitset.Word.capacity) let mask = (UInt.max &<< bit) &<< 1 - return unsafe _UnsafeBitset.Word(value & mask) + return _UnsafeBitset.Word(value & mask) } } @@ -300,7 +300,7 @@ extension _UnsafeBitset.Word { internal static var empty: _UnsafeBitset.Word { @inline(__always) get { - return unsafe _UnsafeBitset.Word(0) + return _UnsafeBitset.Word(0) } } @@ -308,7 +308,7 @@ extension _UnsafeBitset.Word { internal static var allBits: _UnsafeBitset.Word { @inline(__always) get { - return unsafe _UnsafeBitset.Word(UInt.max) + return _UnsafeBitset.Word(UInt.max) } } } @@ -324,19 +324,19 @@ extension _UnsafeBitset.Word: @unsafe Sequence, @unsafe IteratorProtocol { @inlinable internal var count: Int { - return unsafe value.nonzeroBitCount + return value.nonzeroBitCount } @inlinable internal var underestimatedCount: Int { - return unsafe count + return count } @inlinable internal var isEmpty: Bool { @inline(__always) get { - return unsafe value == 0 + return value == 0 } } @@ -344,9 +344,9 @@ extension _UnsafeBitset.Word: @unsafe Sequence, @unsafe IteratorProtocol { /// and also destructively clear it. @inlinable internal mutating func next() -> Int? { - guard unsafe value != 0 else { return nil } - let bit = unsafe value.trailingZeroBitCount - unsafe value &= value &- 1 // Clear lowest nonzero bit. + guard value != 0 else { return nil } + let bit = value.trailingZeroBitCount + value &= value &- 1 // Clear lowest nonzero bit. return bit } } diff --git a/stdlib/public/core/CollectionAlgorithms.swift b/stdlib/public/core/CollectionAlgorithms.swift index ce14eb793a798..3dab3d5ee89d4 100644 --- a/stdlib/public/core/CollectionAlgorithms.swift +++ b/stdlib/public/core/CollectionAlgorithms.swift @@ -402,7 +402,7 @@ extension MutableCollection where Self: BidirectionalCollection { (bufferPointer) -> Int in let unsafeBufferPivot = try unsafe bufferPointer._partitionImpl( by: belongsInSecondPartition) - return unsafe unsafeBufferPivot - bufferPointer.startIndex + return unsafeBufferPivot - bufferPointer.startIndex } if let offset = maybeOffset { return index(startIndex, offsetBy: offset) diff --git a/stdlib/public/core/ContiguouslyStored.swift b/stdlib/public/core/ContiguouslyStored.swift index 340ebd3313624..5f303f258f5a5 100644 --- a/stdlib/public/core/ContiguouslyStored.swift +++ b/stdlib/public/core/ContiguouslyStored.swift @@ -42,7 +42,7 @@ extension Array: _HasContiguousBytes { } } extension ContiguousArray: _HasContiguousBytes {} -extension UnsafeBufferPointer: _HasContiguousBytes { +extension UnsafeBufferPointer: @unsafe _HasContiguousBytes { @inlinable @inline(__always) @safe func withUnsafeBytes( @@ -53,7 +53,7 @@ extension UnsafeBufferPointer: _HasContiguousBytes { return try unsafe body(UnsafeRawBufferPointer(start: ptr, count: len)) } } -extension UnsafeMutableBufferPointer: _HasContiguousBytes { +extension UnsafeMutableBufferPointer: @unsafe _HasContiguousBytes { @inlinable @inline(__always) @safe func withUnsafeBytes( @@ -64,7 +64,7 @@ extension UnsafeMutableBufferPointer: _HasContiguousBytes { return try unsafe body(UnsafeRawBufferPointer(start: ptr, count: len)) } } -extension UnsafeRawBufferPointer: _HasContiguousBytes { +extension UnsafeRawBufferPointer: @unsafe _HasContiguousBytes { @inlinable @inline(__always) @safe func withUnsafeBytes( @@ -73,7 +73,7 @@ extension UnsafeRawBufferPointer: _HasContiguousBytes { return try unsafe body(self) } } -extension UnsafeMutableRawBufferPointer: _HasContiguousBytes { +extension UnsafeMutableRawBufferPointer: @unsafe _HasContiguousBytes { @inlinable @inline(__always) @safe func withUnsafeBytes( diff --git a/stdlib/public/core/Dictionary.swift b/stdlib/public/core/Dictionary.swift index 6661feb56bb6e..6e867aedec522 100644 --- a/stdlib/public/core/Dictionary.swift +++ b/stdlib/public/core/Dictionary.swift @@ -838,7 +838,7 @@ extension Dictionary: ExpressibleByDictionaryLiteral { for (key, value) in elements { let (bucket, found) = native.find(key) _precondition(!found, "Dictionary literal contains duplicate keys") - unsafe native._insert(at: bucket, key: key, value: value) + native._insert(at: bucket, key: key, value: value) } self.init(_native: native) } @@ -904,11 +904,11 @@ extension Dictionary { } @inline(__always) _modify { - let (bucket, found) = unsafe _variant.mutatingFind(key) + let (bucket, found) = _variant.mutatingFind(key) let native = _variant.asNative if !found { let value = defaultValue() - unsafe native._insert(at: bucket, key: key, value: value) + native._insert(at: bucket, key: key, value: value) } let address = unsafe native._values + bucket.offset defer { _fixLifetime(self) } @@ -1458,7 +1458,7 @@ extension Dictionary { } _modify { let native = _variant.ensureUniqueNative() - let bucket = unsafe native.validatedBucket(for: position) + let bucket = native.validatedBucket(for: position) let address = unsafe native._values + bucket.offset defer { _fixLifetime(self) } yield unsafe &address.pointee @@ -1491,9 +1491,9 @@ extension Dictionary { #endif let isUnique = _variant.isUniquelyReferenced() let native = _variant.asNative - let a = unsafe native.validatedBucket(for: i) - let b = unsafe native.validatedBucket(for: j) - unsafe _variant.asNative.swapValuesAt(a, b, isUnique: isUnique) + let a = native.validatedBucket(for: i) + let b = native.validatedBucket(for: j) + _variant.asNative.swapValuesAt(a, b, isUnique: isUnique) } } } diff --git a/stdlib/public/core/DictionaryBridging.swift b/stdlib/public/core/DictionaryBridging.swift index 3077635c47674..e4db83fe124fb 100644 --- a/stdlib/public/core/DictionaryBridging.swift +++ b/stdlib/public/core/DictionaryBridging.swift @@ -98,12 +98,12 @@ final internal class _SwiftDictionaryNSEnumerator @objc internal func nextObject() -> AnyObject? { - if unsafe nextBucket == endBucket { + if nextBucket == endBucket { return nil } - let bucket = unsafe nextBucket + let bucket = nextBucket unsafe nextBucket = base.hashTable.occupiedBucket(after: nextBucket) - return unsafe self.bridgedKey(at: bucket) + return self.bridgedKey(at: bucket) } @objc(countByEnumeratingWithState:objects:count:) @@ -119,7 +119,7 @@ final internal class _SwiftDictionaryNSEnumerator unsafe theState.mutationsPtr = _fastEnumerationStorageMutationsPtr } - if unsafe nextBucket == endBucket { + if nextBucket == endBucket { unsafe state.pointee = theState return 0 } @@ -411,7 +411,7 @@ final internal class _SwiftDeferredNSDictionary // Only need to bridge once, so we can hoist it out of the loop. let bridgedKeys = unsafe bridgeKeys() for i in 0..= 0 { + var bucket = _HashTable.Bucket(offset: initializedCount - 1) + while bucket.offset >= 0 { if unsafe hashTable._isOccupied(bucket) { // We've moved an element here in a previous iteration. - unsafe bucket.offset -= 1 + bucket.offset -= 1 continue } // Find the target bucket for this entry and mark it as in use. @@ -148,35 +148,35 @@ extension _NativeDictionary { if _isDebugAssertConfiguration() || allowingDuplicates { let (b, found) = unsafe find(_keys[bucket.offset]) if found { - unsafe _internalInvariant(b != bucket) + _internalInvariant(b != bucket) _precondition(allowingDuplicates, "Duplicate keys found") // Discard duplicate entry. unsafe uncheckedDestroy(at: bucket) unsafe _storage._count -= 1 - unsafe bucket.offset -= 1 + bucket.offset -= 1 continue } unsafe hashTable.insert(b) - unsafe target = unsafe b + target = b } else { let hashValue = unsafe self.hashValue(for: _keys[bucket.offset]) unsafe target = unsafe hashTable.insertNew(hashValue: hashValue) } - if unsafe target > bucket { + if target > bucket { // The target is outside the unprocessed region. We can simply move the // entry, leaving behind an uninitialized bucket. - unsafe moveEntry(from: bucket, to: target) + moveEntry(from: bucket, to: target) // Restore invariants by lowering the region boundary. - unsafe bucket.offset -= 1 - } else if unsafe target == bucket { + bucket.offset -= 1 + } else if target == bucket { // Already in place. - unsafe bucket.offset -= 1 + bucket.offset -= 1 } else { // The target bucket is also in the unprocessed region. Swap the current // item into place, then try again with the swapped-in value, so that we // don't lose it. - unsafe swapEntry(target, with: bucket) + swapEntry(target, with: bucket) } } // When there are no more unprocessed entries, we're left with a valid diff --git a/stdlib/public/core/DictionaryStorage.swift b/stdlib/public/core/DictionaryStorage.swift index 2de249834a415..650813234f1e9 100644 --- a/stdlib/public/core/DictionaryStorage.swift +++ b/stdlib/public/core/DictionaryStorage.swift @@ -247,11 +247,11 @@ extension __RawDictionaryStorage { var bucket = unsafe hashTable.idealBucket(forHashValue: hashValue) while unsafe hashTable._isOccupied(bucket) { if unsafe uncheckedKey(at: bucket) == key { - return unsafe (bucket, true) + return (bucket, true) } unsafe bucket = unsafe hashTable.bucket(wrappedAfter: bucket) } - return unsafe (bucket, false) + return (bucket, false) } } @@ -358,7 +358,7 @@ final internal class _DictionaryStorage "Invalid fast enumeration state") var stored = 0 for i in 0.. Bool { - return unsafe lhs.offset == rhs.offset + return lhs.offset == rhs.offset } } @@ -181,7 +181,7 @@ extension _HashTable.Bucket: Comparable { @inline(__always) internal static func < (lhs: _HashTable.Bucket, rhs: _HashTable.Bucket) -> Bool { - return unsafe lhs.offset < rhs.offset + return lhs.offset < rhs.offset } } @@ -199,7 +199,7 @@ extension _HashTable { @inlinable @inline(__always) internal init(bucket: Bucket, age: Int32) { - unsafe self.bucket = unsafe bucket + unsafe self.bucket = bucket unsafe self.age = age } } @@ -316,7 +316,7 @@ extension _HashTable { var word = word while unsafe word < wordCount { if let bit = unsafe words[word].minimum { - return unsafe Bucket(word: word, bit: bit) + return Bucket(word: word, bit: bit) } word += 1 } @@ -326,9 +326,9 @@ extension _HashTable { @inlinable internal func occupiedBucket(after bucket: Bucket) -> Bucket { _internalInvariant(isValid(bucket)) - let word = unsafe bucket.word + let word = bucket.word if let bit = unsafe words[word].intersecting(elementsAbove: bucket.bit).minimum { - return unsafe Bucket(word: word, bit: bit) + return Bucket(word: word, bit: bit) } return unsafe _firstOccupiedBucket(fromWord: word + 1) } @@ -370,13 +370,13 @@ extension _HashTable { _internalInvariant(isValid(bucket)) // Note that if we have only a single partial word, its out-of-bounds bits // are guaranteed to be all set, so the formula below gives correct results. - var word = unsafe bucket.word + var word = bucket.word if let bit = unsafe words[word] .complement .intersecting(elementsBelow: bucket.bit) .maximum { - return unsafe Bucket(word: word, bit: bit) + return Bucket(word: word, bit: bit) } var wrap = false while true { @@ -387,7 +387,7 @@ extension _HashTable { word = unsafe wordCount - 1 } if let bit = unsafe words[word].complement.maximum { - return unsafe Bucket(word: word, bit: bit) + return Bucket(word: word, bit: bit) } } fatalError() @@ -398,13 +398,13 @@ extension _HashTable { _internalInvariant(isValid(bucket)) // Note that if we have only a single partial word, its out-of-bounds bits // are guaranteed to be all set, so the formula below gives correct results. - var word = unsafe bucket.word + var word = bucket.word if let bit = unsafe words[word] .complement .subtracting(elementsBelow: bucket.bit) .minimum { - return unsafe Bucket(word: word, bit: bit) + return Bucket(word: word, bit: bit) } var wrap = false while true { @@ -415,7 +415,7 @@ extension _HashTable { word = 0 } if let bit = unsafe words[word].complement.minimum { - return unsafe Bucket(word: word, bit: bit) + return Bucket(word: word, bit: bit) } } fatalError() @@ -438,7 +438,7 @@ extension _HashTable { internal func insertNew(hashValue: Int) -> Bucket { let hole = unsafe nextHole(atOrAfter: idealBucket(forHashValue: hashValue)) unsafe insert(hole) - return unsafe hole + return hole } /// Insert a new entry for an element at `index`. @@ -473,7 +473,7 @@ extension _HashTable { // If we've put a hole in a chain of contiguous elements, some element after // the hole may belong where the new hole is. - var hole = unsafe bucket + var hole = bucket var candidate = unsafe self.bucket(wrappedAfter: hole) guard unsafe _isOccupied(candidate) else { @@ -489,17 +489,17 @@ extension _HashTable { // Relocate out-of-place elements in the chain, repeating until we get to // the end of the chain. while unsafe _isOccupied(candidate) { - let candidateHash = unsafe delegate.hashValue(at: candidate) + let candidateHash = delegate.hashValue(at: candidate) let ideal = unsafe idealBucket(forHashValue: candidateHash) // Does this element belong between start and hole? We need two // separate tests depending on whether [start, hole] wraps around the // end of the storage. - let c0 = unsafe ideal >= start - let c1 = unsafe ideal <= hole - if unsafe start <= hole ? (c0 && c1) : (c0 || c1) { - unsafe delegate.moveEntry(from: candidate, to: hole) - unsafe hole = unsafe candidate + let c0 = ideal >= start + let c1 = ideal <= hole + if start <= hole ? (c0 && c1) : (c0 || c1) { + delegate.moveEntry(from: candidate, to: hole) + hole = candidate } unsafe candidate = unsafe self.bucket(wrappedAfter: candidate) } diff --git a/stdlib/public/core/KeyPath.swift b/stdlib/public/core/KeyPath.swift index f0ebf1ceba403..6184bcf51e9d9 100644 --- a/stdlib/public/core/KeyPath.swift +++ b/stdlib/public/core/KeyPath.swift @@ -183,9 +183,9 @@ public class AnyKeyPath: _AppendKeyPath { var offset = 0 while true { let (rawComponent, optNextType) = unsafe buffer.next() - switch unsafe rawComponent.header.kind { + switch rawComponent.header.kind { case .struct: - unsafe offset += rawComponent._structOrClassOffset + offset += rawComponent._structOrClassOffset case .class, .computed, .optionalChain, .optionalForce, .optionalWrap, .external: return .none @@ -678,7 +678,7 @@ internal struct ComputedPropertyID: Hashable { } @_unavailableInEmbedded -@unsafe +@safe internal struct ComputedAccessorsPtr { #if INTERNAL_CHECKS_ENABLED internal let header: RawKeyPathComponent.Header @@ -687,7 +687,7 @@ internal struct ComputedAccessorsPtr { init(header: RawKeyPathComponent.Header, value: UnsafeRawPointer) { #if INTERNAL_CHECKS_ENABLED - unsafe self.header = unsafe header + self.header = header #endif unsafe self._value = unsafe value } @@ -714,14 +714,14 @@ internal struct ComputedAccessorsPtr { internal var getterPtr: UnsafeRawPointer { #if INTERNAL_CHECKS_ENABLED - unsafe _internalInvariant(header.kind == .computed, + _internalInvariant(header.kind == .computed, "not a computed property") #endif return unsafe _value } internal var setterPtr: UnsafeRawPointer { #if INTERNAL_CHECKS_ENABLED - unsafe _internalInvariant(header.isComputedSettable, + _internalInvariant(header.isComputedSettable, "not a settable property") #endif return unsafe _value + MemoryLayout.size @@ -738,7 +738,7 @@ internal struct ComputedAccessorsPtr { internal func nonmutatingSetter() -> NonmutatingSetter { #if INTERNAL_CHECKS_ENABLED - unsafe _internalInvariant(header.isComputedSettable && !header.isComputedMutating, + _internalInvariant(header.isComputedSettable && !header.isComputedMutating, "not a nonmutating settable property") #endif @@ -750,7 +750,7 @@ internal struct ComputedAccessorsPtr { internal func mutatingSetter() -> MutatingSetter { #if INTERNAL_CHECKS_ENABLED - unsafe _internalInvariant(header.isComputedSettable && header.isComputedMutating, + _internalInvariant(header.isComputedSettable && header.isComputedMutating, "not a mutating settable property") #endif @@ -838,7 +838,7 @@ internal struct ComputedArgumentWitnessesPtr { } @_unavailableInEmbedded -@unsafe +@safe internal enum KeyPathComponent { @unsafe internal struct ArgumentRef { @@ -890,7 +890,7 @@ internal enum KeyPathComponent { @_unavailableInEmbedded extension KeyPathComponent: @unsafe Hashable { internal static func ==(a: KeyPathComponent, b: KeyPathComponent) -> Bool { - switch unsafe (a, b) { + switch (a, b) { case (.struct(offset: let a), .struct(offset: let b)), (.class (offset: let a), .class (offset: let b)): return a == b @@ -948,7 +948,7 @@ extension KeyPathComponent: @unsafe Hashable { } } } - switch unsafe self { + switch self { case .struct(offset: let a): hasher.combine(0) hasher.combine(a) @@ -1119,13 +1119,13 @@ internal enum KeyPathComputedIDResolution { } @_unavailableInEmbedded -@unsafe +@safe internal struct RawKeyPathComponent { - internal var header: Header + @safe internal var header: Header internal var body: UnsafeRawBufferPointer internal init(header: Header, body: UnsafeRawBufferPointer) { - unsafe self.header = unsafe header + self.header = header unsafe self.body = unsafe body } @@ -1138,74 +1138,74 @@ internal struct RawKeyPathComponent { internal var _value: UInt32 init(discriminator: UInt32, payload: UInt32) { - unsafe _value = 0 - unsafe self.discriminator = discriminator - unsafe self.payload = payload + _value = 0 + self.discriminator = discriminator + self.payload = payload } internal var discriminator: UInt32 { get { - return unsafe (_value & Header.discriminatorMask) &>> Header.discriminatorShift + return (_value & Header.discriminatorMask) &>> Header.discriminatorShift } set { - let shifted = unsafe newValue &<< Header.discriminatorShift - unsafe _internalInvariant(shifted & Header.discriminatorMask == shifted, + let shifted = newValue &<< Header.discriminatorShift + _internalInvariant(shifted & Header.discriminatorMask == shifted, "discriminator doesn't fit") - unsafe _value = unsafe _value & ~Header.discriminatorMask | shifted + _value = _value & ~Header.discriminatorMask | shifted } } internal var payload: UInt32 { get { - return unsafe _value & Header.payloadMask + return _value & Header.payloadMask } set { - unsafe _internalInvariant(newValue & Header.payloadMask == newValue, + _internalInvariant(newValue & Header.payloadMask == newValue, "payload too big") - unsafe _value = unsafe _value & ~Header.payloadMask | newValue + _value = _value & ~Header.payloadMask | newValue } } internal var storedOffsetPayload: UInt32 { get { - unsafe _internalInvariant(kind == .struct || kind == .class, + _internalInvariant(kind == .struct || kind == .class, "not a stored component") - return unsafe _value & Header.storedOffsetPayloadMask + return _value & Header.storedOffsetPayloadMask } set { - unsafe _internalInvariant(kind == .struct || kind == .class, + _internalInvariant(kind == .struct || kind == .class, "not a stored component") - unsafe _internalInvariant(newValue & Header.storedOffsetPayloadMask == newValue, + _internalInvariant(newValue & Header.storedOffsetPayloadMask == newValue, "payload too big") - unsafe _value = unsafe _value & ~Header.storedOffsetPayloadMask | newValue + _value = _value & ~Header.storedOffsetPayloadMask | newValue } } internal var endOfReferencePrefix: Bool { get { - return unsafe _value & Header.endOfReferencePrefixFlag != 0 + return _value & Header.endOfReferencePrefixFlag != 0 } set { if newValue { - unsafe _value |= Header.endOfReferencePrefixFlag + _value |= Header.endOfReferencePrefixFlag } else { - unsafe _value &= ~Header.endOfReferencePrefixFlag + _value &= ~Header.endOfReferencePrefixFlag } } } internal var kind: KeyPathComponentKind { - switch unsafe (discriminator, payload) { - case (unsafe Header.externalTag, _): + switch (discriminator, payload) { + case (Header.externalTag, _): return .external - case (unsafe Header.structTag, _): + case (Header.structTag, _): return .struct - case (unsafe Header.classTag, _): + case (Header.classTag, _): return .class - case (unsafe Header.computedTag, _): + case (Header.computedTag, _): return .computed - case (unsafe Header.optionalTag, unsafe Header.optionalChainPayload): + case (Header.optionalTag, Header.optionalChainPayload): return .optionalChain - case (unsafe Header.optionalTag, unsafe Header.optionalWrapPayload): + case (Header.optionalTag, Header.optionalWrapPayload): return .optionalWrap - case (unsafe Header.optionalTag, unsafe Header.optionalForcePayload): + case (Header.optionalTag, Header.optionalForcePayload): return .optionalForce default: _internalInvariantFailure("invalid header") @@ -1269,24 +1269,24 @@ internal struct RawKeyPathComponent { } internal var isStoredMutable: Bool { - unsafe _internalInvariant(kind == .struct || kind == .class) - return unsafe _value & Header.storedMutableFlag != 0 + _internalInvariant(kind == .struct || kind == .class) + return _value & Header.storedMutableFlag != 0 } internal static var computedMutatingFlag: UInt32 { return _SwiftKeyPathComponentHeader_ComputedMutatingFlag } internal var isComputedMutating: Bool { - unsafe _internalInvariant(kind == .computed) - return unsafe _value & Header.computedMutatingFlag != 0 + _internalInvariant(kind == .computed) + return _value & Header.computedMutatingFlag != 0 } internal static var computedSettableFlag: UInt32 { return _SwiftKeyPathComponentHeader_ComputedSettableFlag } internal var isComputedSettable: Bool { - unsafe _internalInvariant(kind == .computed) - return unsafe _value & Header.computedSettableFlag != 0 + _internalInvariant(kind == .computed) + return _value & Header.computedSettableFlag != 0 } internal static var computedIDByStoredPropertyFlag: UInt32 { @@ -1296,8 +1296,8 @@ internal struct RawKeyPathComponent { return _SwiftKeyPathComponentHeader_ComputedIDByVTableOffsetFlag } internal var computedIDKind: KeyPathComputedIDKind { - let storedProperty = unsafe _value & Header.computedIDByStoredPropertyFlag != 0 - let vtableOffset = unsafe _value & Header.computedIDByVTableOffsetFlag != 0 + let storedProperty = _value & Header.computedIDByStoredPropertyFlag != 0 + let vtableOffset = _value & Header.computedIDByVTableOffsetFlag != 0 switch (storedProperty, vtableOffset) { case (true, true): @@ -1315,8 +1315,8 @@ internal struct RawKeyPathComponent { return _SwiftKeyPathComponentHeader_ComputedHasArgumentsFlag } internal var hasComputedArguments: Bool { - unsafe _internalInvariant(kind == .computed) - return unsafe _value & Header.computedHasArgumentsFlag != 0 + _internalInvariant(kind == .computed) + return _value & Header.computedHasArgumentsFlag != 0 } // If a computed component is instantiated from an external property @@ -1328,14 +1328,14 @@ internal struct RawKeyPathComponent { } internal var isComputedInstantiatedFromExternalWithArguments: Bool { get { - unsafe _internalInvariant(kind == .computed) + _internalInvariant(kind == .computed) return - unsafe _value & Header.computedInstantiatedFromExternalWithArgumentsFlag != 0 + _value & Header.computedInstantiatedFromExternalWithArgumentsFlag != 0 } set { - unsafe _internalInvariant(kind == .computed) - unsafe _value = - unsafe _value & ~Header.computedInstantiatedFromExternalWithArgumentsFlag + _internalInvariant(kind == .computed) + _value = + _value & ~Header.computedInstantiatedFromExternalWithArgumentsFlag | (newValue ? Header.computedInstantiatedFromExternalWithArgumentsFlag : 0) } @@ -1360,14 +1360,14 @@ internal struct RawKeyPathComponent { return _SwiftKeyPathComponentHeader_ComputedIDUnresolvedFunctionCall } internal var computedIDResolution: KeyPathComputedIDResolution { - switch unsafe payload & Header.computedIDResolutionMask { - case unsafe Header.computedIDResolved: + switch payload & Header.computedIDResolutionMask { + case Header.computedIDResolved: return .resolved - case unsafe Header.computedIDResolvedAbsolute: + case Header.computedIDResolvedAbsolute: return .resolvedAbsolute - case unsafe Header.computedIDUnresolvedIndirectPointer: + case Header.computedIDUnresolvedIndirectPointer: return .indirectPointer - case unsafe Header.computedIDUnresolvedFunctionCall: + case Header.computedIDUnresolvedFunctionCall: return .functionCall default: _internalInvariantFailure("invalid key path resolution") @@ -1381,27 +1381,27 @@ internal struct RawKeyPathComponent { } internal var isTrivialPropertyDescriptor: Bool { - return unsafe _value == + return _value == _SwiftKeyPathComponentHeader_TrivialPropertyDescriptorMarker } /// If this is the header for a component in a key path pattern, return /// the size of the body of the component. internal var patternComponentBodySize: Int { - return unsafe _componentBodySize(forPropertyDescriptor: false) + return _componentBodySize(forPropertyDescriptor: false) } /// If this is the header for a property descriptor, return /// the size of the body of the component. internal var propertyDescriptorBodySize: Int { - if unsafe isTrivialPropertyDescriptor { return 0 } - return unsafe _componentBodySize(forPropertyDescriptor: true) + if isTrivialPropertyDescriptor { return 0 } + return _componentBodySize(forPropertyDescriptor: true) } internal func _componentBodySize(forPropertyDescriptor: Bool) -> Int { - switch unsafe kind { + switch kind { case .struct, .class: - if unsafe storedOffsetPayload == Header.unresolvedFieldOffsetPayload + if storedOffsetPayload == Header.unresolvedFieldOffsetPayload || storedOffsetPayload == Header.outOfLineOffsetPayload || storedOffsetPayload == Header.unresolvedIndirectOffsetPayload { // A 32-bit offset is stored in the body. @@ -1414,19 +1414,19 @@ internal struct RawKeyPathComponent { // The body holds a pointer to the external property descriptor, // and some number of substitution arguments, the count of which is // in the payload. - return unsafe 4 &* (1 &+ Int(payload)) + return 4 &* (1 &+ Int(payload)) case .computed: // The body holds at minimum the id and getter. var size = 8 // If settable, it also holds the setter. - if unsafe isComputedSettable { + if isComputedSettable { size &+= 4 } // If there are arguments, there's also a layout function, // witness table, and initializer function. // Property descriptors never carry argument information, though. - if unsafe !forPropertyDescriptor && hasComputedArguments { + if !forPropertyDescriptor && hasComputedArguments { size &+= 12 } @@ -1439,17 +1439,17 @@ internal struct RawKeyPathComponent { } init(optionalForce: ()) { - unsafe self.init(discriminator: Header.optionalTag, + self.init(discriminator: Header.optionalTag, payload: Header.optionalForcePayload) } init(optionalWrap: ()) { - unsafe self.init(discriminator: Header.optionalTag, + self.init(discriminator: Header.optionalTag, payload: Header.optionalWrapPayload) } init(optionalChain: ()) { - unsafe self.init(discriminator: Header.optionalTag, + self.init(discriminator: Header.optionalTag, payload: Header.optionalChainPayload) } @@ -1458,14 +1458,14 @@ internal struct RawKeyPathComponent { inlineOffset: UInt32) { let discriminator: UInt32 switch kind { - case .struct: discriminator = unsafe Header.structTag - case .class: discriminator = unsafe Header.classTag + case .struct: discriminator = Header.structTag + case .class: discriminator = Header.classTag } - unsafe _internalInvariant(inlineOffset <= Header.maximumOffsetPayload) - let payload = unsafe inlineOffset + _internalInvariant(inlineOffset <= Header.maximumOffsetPayload) + let payload = inlineOffset | (mutable ? Header.storedMutableFlag : 0) - unsafe self.init(discriminator: discriminator, + self.init(discriminator: discriminator, payload: payload) } @@ -1473,14 +1473,14 @@ internal struct RawKeyPathComponent { mutable: Bool) { let discriminator: UInt32 switch kind { - case .struct: discriminator = unsafe Header.structTag - case .class: discriminator = unsafe Header.classTag + case .struct: discriminator = Header.structTag + case .class: discriminator = Header.classTag } - let payload = unsafe Header.outOfLineOffsetPayload + let payload = Header.outOfLineOffsetPayload | (mutable ? Header.storedMutableFlag : 0) - unsafe self.init(discriminator: discriminator, + self.init(discriminator: discriminator, payload: payload) } @@ -1489,9 +1489,9 @@ internal struct RawKeyPathComponent { settable: Bool, hasArguments: Bool, instantiatedFromExternalWithArguments: Bool) { - let discriminator = unsafe Header.computedTag + let discriminator = Header.computedTag var payload = - unsafe (mutating ? Header.computedMutatingFlag : 0) + (mutating ? Header.computedMutatingFlag : 0) | (settable ? Header.computedSettableFlag : 0) | (hasArguments ? Header.computedHasArgumentsFlag : 0) | (instantiatedFromExternalWithArguments @@ -1500,20 +1500,20 @@ internal struct RawKeyPathComponent { case .pointer: break case .storedPropertyIndex: - unsafe payload |= Header.computedIDByStoredPropertyFlag + payload |= Header.computedIDByStoredPropertyFlag case .vtableOffset: - unsafe payload |= Header.computedIDByVTableOffsetFlag + payload |= Header.computedIDByVTableOffsetFlag } - unsafe self.init(discriminator: discriminator, + self.init(discriminator: discriminator, payload: payload) } } internal var bodySize: Int { let ptrSize = MemoryLayout.size - switch unsafe header.kind { + switch header.kind { case .struct, .class: - if unsafe header.storedOffsetPayload == Header.outOfLineOffsetPayload { + if header.storedOffsetPayload == Header.outOfLineOffsetPayload { return 4 // overflowed } return 0 @@ -1523,19 +1523,19 @@ internal struct RawKeyPathComponent { return 0 case .computed: // align to pointer, minimum two pointers for id and get - var total = unsafe Header.pointerAlignmentSkew &+ ptrSize &* 2 + var total = Header.pointerAlignmentSkew &+ ptrSize &* 2 // additional word for a setter - if unsafe header.isComputedSettable { + if header.isComputedSettable { total &+= ptrSize } // include the argument size - if unsafe header.hasComputedArguments { + if header.hasComputedArguments { // two words for argument header: size, witnesses total &+= ptrSize &* 2 // size of argument area - unsafe total &+= _computedArgumentSize - if unsafe header.isComputedInstantiatedFromExternalWithArguments { - unsafe total &+= Header.externalWithArgumentsExtraSize + total &+= _computedArgumentSize + if header.isComputedInstantiatedFromExternalWithArguments { + total &+= Header.externalWithArgumentsExtraSize } } return total @@ -1543,37 +1543,37 @@ internal struct RawKeyPathComponent { } internal var _structOrClassOffset: Int { - unsafe _internalInvariant(header.kind == .struct || header.kind == .class, + _internalInvariant(header.kind == .struct || header.kind == .class, "no offset for this kind") // An offset too large to fit inline is represented by a signal and stored // in the body. - if unsafe header.storedOffsetPayload == Header.outOfLineOffsetPayload { + if header.storedOffsetPayload == Header.outOfLineOffsetPayload { // Offset overflowed into body unsafe _internalInvariant(body.count >= MemoryLayout.size, "component not big enough") return Int(truncatingIfNeeded: unsafe body.load(as: UInt32.self)) } - return unsafe Int(truncatingIfNeeded: header.storedOffsetPayload) + return Int(truncatingIfNeeded: header.storedOffsetPayload) } internal var _computedIDValue: Int { - unsafe _internalInvariant(header.kind == .computed, + _internalInvariant(header.kind == .computed, "not a computed property") return unsafe body.load(fromByteOffset: Header.pointerAlignmentSkew, as: Int.self) } internal var _computedID: ComputedPropertyID { - unsafe _internalInvariant(header.kind == .computed, + _internalInvariant(header.kind == .computed, "not a computed property") - return unsafe ComputedPropertyID( + return ComputedPropertyID( value: _computedIDValue, kind: header.computedIDKind) } internal var _computedAccessors: ComputedAccessorsPtr { - unsafe _internalInvariant(header.kind == .computed, + _internalInvariant(header.kind == .computed, "not a computed property") return unsafe ComputedAccessorsPtr( @@ -1583,7 +1583,7 @@ internal struct RawKeyPathComponent { } internal var _computedArgumentHeaderPointer: UnsafeRawPointer { - unsafe _internalInvariant(header.hasComputedArguments, "no arguments") + _internalInvariant(header.hasComputedArguments, "no arguments") return unsafe body.baseAddress._unsafelyUnwrappedUnchecked + Header.pointerAlignmentSkew @@ -1607,7 +1607,7 @@ internal struct RawKeyPathComponent { // with its own arguments, we include some additional capture info to // be able to map to the original argument context by adjusting the size // passed to the witness operations. - if unsafe header.isComputedInstantiatedFromExternalWithArguments { + if header.isComputedInstantiatedFromExternalWithArguments { unsafe base += Header.externalWithArgumentsExtraSize } return unsafe base @@ -1616,7 +1616,7 @@ internal struct RawKeyPathComponent { return unsafe UnsafeMutableRawPointer(mutating: _computedArguments) } internal var _computedArgumentWitnessSizeAdjustment: Int { - if unsafe header.isComputedInstantiatedFromExternalWithArguments { + if header.isComputedInstantiatedFromExternalWithArguments { return unsafe _computedArguments.load( fromByteOffset: 0 &- Header.externalWithArgumentsExtraSize, as: Int.self) @@ -1625,26 +1625,26 @@ internal struct RawKeyPathComponent { } internal var value: KeyPathComponent { - switch unsafe header.kind { + switch header.kind { case .struct: - return unsafe .struct(offset: _structOrClassOffset) + return .struct(offset: _structOrClassOffset) case .class: - return unsafe .class(offset: _structOrClassOffset) + return .class(offset: _structOrClassOffset) case .optionalChain: - return unsafe .optionalChain + return .optionalChain case .optionalForce: - return unsafe .optionalForce + return .optionalForce case .optionalWrap: - return unsafe .optionalWrap + return .optionalWrap case .computed: - let isSettable = unsafe header.isComputedSettable - let isMutating = unsafe header.isComputedMutating + let isSettable = header.isComputedSettable + let isMutating = header.isComputedMutating - let id = unsafe _computedID - let accessors = unsafe _computedAccessors + let id = _computedID + let accessors = _computedAccessors // Argument value is unused if there are no arguments. let argument: KeyPathComponent.ArgumentRef? - if unsafe header.hasComputedArguments { + if header.hasComputedArguments { unsafe argument = unsafe KeyPathComponent.ArgumentRef( data: UnsafeRawBufferPointer(start: _computedArguments, count: _computedArgumentSize), @@ -1674,7 +1674,7 @@ internal struct RawKeyPathComponent { } internal func destroy() { - switch unsafe header.kind { + switch header.kind { case .struct, .class, .optionalChain, @@ -1684,7 +1684,7 @@ internal struct RawKeyPathComponent { break case .computed: // Run destructor, if any - if unsafe header.hasComputedArguments, + if header.hasComputedArguments, let destructor = unsafe _computedArgumentWitnesses.destroy { unsafe destructor(_computedMutableArguments, _computedArgumentSize &- _computedArgumentWitnessSizeAdjustment) @@ -1696,15 +1696,15 @@ internal struct RawKeyPathComponent { internal func clone(into buffer: inout UnsafeMutableRawBufferPointer, endOfReferencePrefix: Bool) { - var newHeader = unsafe header - unsafe newHeader.endOfReferencePrefix = endOfReferencePrefix + var newHeader = header + newHeader.endOfReferencePrefix = endOfReferencePrefix - var componentSize = unsafe MemoryLayout
.size + var componentSize = MemoryLayout
.size unsafe buffer.storeBytes(of: newHeader, as: Header.self) - switch unsafe header.kind { + switch header.kind { case .struct, .class: - if unsafe header.storedOffsetPayload == Header.outOfLineOffsetPayload { + if header.storedOffsetPayload == Header.outOfLineOffsetPayload { let overflowOffset = unsafe body.load(as: UInt32.self) unsafe buffer.storeBytes(of: overflowOffset, toByteOffset: 4, as: UInt32.self) @@ -1716,12 +1716,12 @@ internal struct RawKeyPathComponent { break case .computed: // Fields are pointer-aligned after the header - unsafe componentSize += Header.pointerAlignmentSkew + componentSize += Header.pointerAlignmentSkew unsafe buffer.storeBytes(of: _computedIDValue, toByteOffset: componentSize, as: Int.self) componentSize += MemoryLayout.size - let accessors = unsafe _computedAccessors + let accessors = _computedAccessors unsafe (buffer.baseAddress.unsafelyUnwrapped + MemoryLayout.size * 2) ._copyAddressDiscriminatedFunctionPointer( @@ -1730,7 +1730,7 @@ internal struct RawKeyPathComponent { componentSize += MemoryLayout.size - if unsafe header.isComputedSettable { + if header.isComputedSettable { unsafe (buffer.baseAddress.unsafelyUnwrapped + MemoryLayout.size * 3) ._copyAddressDiscriminatedFunctionPointer( from: accessors.setterPtr, @@ -1740,9 +1740,9 @@ internal struct RawKeyPathComponent { componentSize += MemoryLayout.size } - if unsafe header.hasComputedArguments { + if header.hasComputedArguments { let arguments = unsafe _computedArguments - let argumentSize = unsafe _computedArgumentSize + let argumentSize = _computedArgumentSize unsafe buffer.storeBytes(of: argumentSize, toByteOffset: componentSize, as: Int.self) @@ -1752,7 +1752,7 @@ internal struct RawKeyPathComponent { as: ComputedArgumentWitnessesPtr.self) componentSize += MemoryLayout.size - if unsafe header.isComputedInstantiatedFromExternalWithArguments { + if header.isComputedInstantiatedFromExternalWithArguments { // Include the extra matter for components instantiated from // external property descriptors with arguments. unsafe buffer.storeBytes(of: _computedArgumentWitnessSizeAdjustment, @@ -1760,14 +1760,14 @@ internal struct RawKeyPathComponent { as: Int.self) componentSize += MemoryLayout.size } - let adjustedSize = unsafe argumentSize - _computedArgumentWitnessSizeAdjustment + let adjustedSize = argumentSize - _computedArgumentWitnessSizeAdjustment let argumentDest = unsafe buffer.baseAddress.unsafelyUnwrapped + componentSize unsafe _computedArgumentWitnesses.copy( arguments, argumentDest, adjustedSize) - if unsafe header.isComputedInstantiatedFromExternalWithArguments { + if header.isComputedInstantiatedFromExternalWithArguments { // The extra information for external property descriptor arguments // can always be memcpy'd. unsafe _memcpy(dest: argumentDest + adjustedSize, @@ -1793,7 +1793,7 @@ internal struct RawKeyPathComponent { _ isBreak: inout Bool, pointer: UnsafeMutablePointer ) { - switch unsafe value { + switch value { case .struct(let offset): unsafe _withUnprotectedUnsafeBytes(of: base) { let p = unsafe $0.baseAddress._unsafelyUnwrappedUnchecked + offset @@ -1899,7 +1899,7 @@ internal struct RawKeyPathComponent { isRoot: Bool, keepAlive: inout AnyObject? ) -> UnsafeRawPointer { - switch unsafe value { + switch value { case .struct(let offset): return unsafe base.advanced(by: offset) case .class(let offset): @@ -2012,9 +2012,9 @@ internal struct KeyPathBuffer { unsafe data = unsafe UnsafeRawBufferPointer( start: base + MemoryLayout.size, count: header.size) - unsafe trivial = unsafe header.trivial - unsafe hasReferencePrefix = unsafe header.hasReferencePrefix - unsafe isSingleComponent = unsafe header.isSingleComponent + unsafe trivial = header.trivial + unsafe hasReferencePrefix = header.hasReferencePrefix + unsafe isSingleComponent = header.isSingleComponent } internal init(partialData: UnsafeRawBufferPointer, @@ -2084,8 +2084,8 @@ internal struct KeyPathBuffer { hasReferencePrefix: Bool, isSingleComponent: Bool ) { - unsafe _internalInvariant(size <= Int(Header.sizeMask), "key path too big") - unsafe _value = unsafe UInt32(size) + _internalInvariant(size <= Int(Header.sizeMask), "key path too big") + _value = UInt32(size) | (trivial ? Header.trivialFlag : 0) | (hasReferencePrefix ? Header.hasReferencePrefixFlag : 0) | (isSingleComponent ? Header.isSingleComponentFlag : 0) @@ -2107,30 +2107,30 @@ internal struct KeyPathBuffer { return _SwiftKeyPathBufferHeader_IsSingleComponentFlag } - internal var size: Int { return unsafe Int(_value & Header.sizeMask) } - internal var trivial: Bool { return unsafe _value & Header.trivialFlag != 0 } + internal var size: Int { return Int(_value & Header.sizeMask) } + internal var trivial: Bool { return _value & Header.trivialFlag != 0 } internal var hasReferencePrefix: Bool { get { - return unsafe _value & Header.hasReferencePrefixFlag != 0 + return _value & Header.hasReferencePrefixFlag != 0 } set { if newValue { - unsafe _value |= Header.hasReferencePrefixFlag + _value |= Header.hasReferencePrefixFlag } else { - unsafe _value &= ~Header.hasReferencePrefixFlag + _value &= ~Header.hasReferencePrefixFlag } } } internal var isSingleComponent: Bool { get { - return unsafe _value & Header.isSingleComponentFlag != 0 + return _value & Header.isSingleComponentFlag != 0 } set { if newValue { - unsafe _value |= Header.isSingleComponentFlag + _value |= Header.isSingleComponentFlag } else { - unsafe _value &= ~Header.isSingleComponentFlag + _value &= ~Header.isSingleComponentFlag } } } @@ -2138,11 +2138,11 @@ internal struct KeyPathBuffer { // In a key path pattern, the "trivial" flag is used to indicate // "instantiable in-line" internal var instantiableInLine: Bool { - return unsafe trivial + return trivial } internal func validateReservedBits() { - unsafe _precondition(_value & Header.reservedMask == 0, + _precondition(_value & Header.reservedMask == 0, "Reserved bits set to an unexpected bit pattern") } } @@ -2154,7 +2154,7 @@ internal struct KeyPathBuffer { var bufferToDestroy = unsafe self while true { let (component, type) = unsafe bufferToDestroy.next() - unsafe component.destroy() + component.destroy() guard let _ = type else { break } } } @@ -2162,7 +2162,7 @@ internal struct KeyPathBuffer { internal mutating func next() -> (RawKeyPathComponent, Any.Type?) { let header = unsafe _pop(from: &data, as: RawKeyPathComponent.Header.self) // Track if this is the last component of the reference prefix. - if unsafe header.endOfReferencePrefix { + if header.endOfReferencePrefix { unsafe _internalInvariant(self.hasReferencePrefix, "beginMutation marker in non-reference-writable key path?") unsafe self.hasReferencePrefix = false @@ -2170,7 +2170,7 @@ internal struct KeyPathBuffer { var component = unsafe RawKeyPathComponent(header: header, body: data) // Shrinkwrap the component buffer size. - let size = unsafe component.bodySize + let size = component.bodySize unsafe component.body = unsafe UnsafeRawBufferPointer(start: component.body.baseAddress, count: size) _ = unsafe _pop(from: &data, as: Int8.self, count: size) @@ -2182,7 +2182,7 @@ internal struct KeyPathBuffer { } else { nextType = unsafe _pop(from: &data, as: Any.Type.self) } - return unsafe (component, nextType) + return (component, nextType) } } @@ -2716,7 +2716,7 @@ internal func _appendingKeyPaths< } else if isLast && leafIsReferenceWritable { endOfReferencePrefix = true } else { - endOfReferencePrefix = unsafe component.header.endOfReferencePrefix + endOfReferencePrefix = component.header.endOfReferencePrefix } unsafe component.clone( @@ -2835,7 +2835,7 @@ public func _swift_getKeyPath(pattern: UnsafeMutableRawPointer, let bufferHeader = unsafe patternPtr.load(fromByteOffset: keyPathPatternHeaderSize, as: KeyPathBuffer.Header.self) - unsafe bufferHeader.validateReservedBits() + bufferHeader.validateReservedBits() // If the first word is nonzero, it relative-references a cache variable // we can use to reference a single shared instantiation of this key path. @@ -3158,14 +3158,14 @@ internal func _walkKeyPathPattern( // header word, or else be stored out-of-line, or need instantiation of some // kind. let offset: KeyPathPatternStoredOffset - switch unsafe header.storedOffsetPayload { - case unsafe RawKeyPathComponent.Header.outOfLineOffsetPayload: + switch header.storedOffsetPayload { + case RawKeyPathComponent.Header.outOfLineOffsetPayload: unsafe offset = unsafe .outOfLine(_pop(from: &componentBuffer, as: UInt32.self)) - case unsafe RawKeyPathComponent.Header.unresolvedFieldOffsetPayload: + case RawKeyPathComponent.Header.unresolvedFieldOffsetPayload: unsafe offset = unsafe .unresolvedFieldOffset(_pop(from: &componentBuffer, as: UInt32.self)) - case unsafe RawKeyPathComponent.Header.unresolvedIndirectOffsetPayload: + case RawKeyPathComponent.Header.unresolvedIndirectOffsetPayload: let base = unsafe componentBuffer.baseAddress._unsafelyUnwrappedUnchecked let relativeOffset = unsafe _pop(from: &componentBuffer, as: Int32.self) @@ -3175,7 +3175,7 @@ internal func _walkKeyPathPattern( default: unsafe offset = unsafe .inline(header.storedOffsetPayload) } - let kind: KeyPathStructOrClass = unsafe header.kind == .struct + let kind: KeyPathStructOrClass = header.kind == .struct ? .struct : .class unsafe walker.visitStoredComponent(kind: kind, mutable: header.isStoredMutable, @@ -3194,7 +3194,7 @@ internal func _walkKeyPathPattern( let getterRef = unsafe _pop(from: &componentBuffer, as: Int32.self) let getter = unsafe _resolveCompactFunctionPointer(getterBase, getterRef) let setter: UnsafeRawPointer? - if unsafe header.isComputedSettable { + if header.isComputedSettable { let setterBase = unsafe componentBuffer.baseAddress._unsafelyUnwrappedUnchecked let setterRef = unsafe _pop(from: &componentBuffer, as: Int32.self) unsafe setter = unsafe _resolveCompactFunctionPointer(setterBase, setterRef) @@ -3208,7 +3208,7 @@ internal func _walkKeyPathPattern( func popComputedArguments(header: RawKeyPathComponent.Header, componentBuffer: inout UnsafeRawBufferPointer) -> KeyPathPatternComputedArguments? { - if unsafe header.hasComputedArguments { + if header.hasComputedArguments { let getLayoutBase = unsafe componentBuffer.baseAddress._unsafelyUnwrappedUnchecked let getLayoutRef = unsafe _pop(from: &componentBuffer, as: Int32.self) let getLayoutRaw = unsafe _resolveCompactFunctionPointer(getLayoutBase, getLayoutRef) @@ -3264,11 +3264,11 @@ internal func _walkKeyPathPattern( _internalInvariant({ bufferSizeBefore = buffer.count - expectedPop = unsafe header.patternComponentBodySize + expectedPop = header.patternComponentBodySize return true }()) - switch unsafe header.kind { + switch header.kind { case .class, .struct: unsafe visitStored(header: header, componentBuffer: &buffer) case .computed: @@ -3299,7 +3299,7 @@ internal func _walkKeyPathPattern( case .external: // Look at the external property descriptor to see if we should take it // over the component given in the pattern. - let genericParamCount = unsafe Int(header.payload) + let genericParamCount = Int(header.payload) let descriptorBase = unsafe buffer.baseAddress._unsafelyUnwrappedUnchecked let descriptorOffset = unsafe _pop(from: &buffer, as: Int32.self) @@ -3308,7 +3308,7 @@ internal func _walkKeyPathPattern( let descriptorHeader: RawKeyPathComponent.Header if unsafe descriptor != UnsafeRawPointer(bitPattern: 0) { unsafe descriptorHeader = unsafe descriptor.load(as: RawKeyPathComponent.Header.self) - if unsafe descriptorHeader.isTrivialPropertyDescriptor { + if descriptorHeader.isTrivialPropertyDescriptor { // If the descriptor is trivial, then use the local candidate. // Skip the external generic parameter accessors to get to it. _ = unsafe _pop(from: &buffer, as: Int32.self, count: genericParamCount) @@ -3329,18 +3329,18 @@ internal func _walkKeyPathPattern( // a computed property. let localCandidateHeader = unsafe _pop(from: &buffer, as: RawKeyPathComponent.Header.self) - let localCandidateSize = unsafe localCandidateHeader.patternComponentBodySize + let localCandidateSize = localCandidateHeader.patternComponentBodySize _internalInvariant({ expectedPop += localCandidateSize + 4 return true }()) - let descriptorSize = unsafe descriptorHeader.propertyDescriptorBodySize + let descriptorSize = descriptorHeader.propertyDescriptorBodySize var descriptorBuffer = unsafe UnsafeRawBufferPointer(start: descriptor + 4, count: descriptorSize) // Look at what kind of component the external property has. - switch unsafe descriptorHeader.kind { + switch descriptorHeader.kind { case .struct, .class: // A stored component. We can instantiate it // without help from the local candidate. @@ -3358,7 +3358,7 @@ internal func _walkKeyPathPattern( // Get the arguments from the external descriptor and/or local candidate // component. let arguments: KeyPathPatternComputedArguments? - if unsafe localCandidateHeader.kind == .computed + if localCandidateHeader.kind == .computed && localCandidateHeader.hasComputedArguments { // If both have arguments, then we have to build a bit of a chimera. // The canonical identity and accessors come from the descriptor, @@ -3762,7 +3762,7 @@ internal struct InstantiateKeyPathBuffer: KeyPathPatternVisitor { // Resolve the offset. switch unsafe offset { case .inline(let value): - let header = unsafe RawKeyPathComponent.Header(stored: kind, + let header = RawKeyPathComponent.Header(stored: kind, mutable: mutable, inlineOffset: value) unsafe pushDest(header) @@ -3773,7 +3773,7 @@ internal struct InstantiateKeyPathBuffer: KeyPathPatternVisitor { break } case .outOfLine(let offset): - let header = unsafe RawKeyPathComponent.Header(storedWithOutOfLineOffset: kind, + let header = RawKeyPathComponent.Header(storedWithOutOfLineOffset: kind, mutable: mutable) unsafe pushDest(header) unsafe pushDest(offset) @@ -3792,7 +3792,7 @@ internal struct InstantiateKeyPathBuffer: KeyPathPatternVisitor { unsafe structOffset += offset } - let header = unsafe RawKeyPathComponent.Header(storedWithOutOfLineOffset: kind, + let header = RawKeyPathComponent.Header(storedWithOutOfLineOffset: kind, mutable: mutable) unsafe pushDest(header) unsafe pushDest(offset) @@ -3801,7 +3801,7 @@ internal struct InstantiateKeyPathBuffer: KeyPathPatternVisitor { // pointer. unsafe _internalInvariant(pointerToOffset.pointee <= UInt32.max) let offset = unsafe UInt32(truncatingIfNeeded: pointerToOffset.pointee) - let header = unsafe RawKeyPathComponent.Header(storedWithOutOfLineOffset: kind, + let header = RawKeyPathComponent.Header(storedWithOutOfLineOffset: kind, mutable: mutable) unsafe pushDest(header) unsafe pushDest(offset) @@ -3960,19 +3960,19 @@ internal struct InstantiateKeyPathBuffer: KeyPathPatternVisitor { mutating func visitOptionalChainComponent() { unsafe isPureStruct.append(false) let _ = unsafe updatePreviousComponentAddr() - let header = unsafe RawKeyPathComponent.Header(optionalChain: ()) + let header = RawKeyPathComponent.Header(optionalChain: ()) unsafe pushDest(header) } mutating func visitOptionalWrapComponent() { unsafe isPureStruct.append(false) let _ = unsafe updatePreviousComponentAddr() - let header = unsafe RawKeyPathComponent.Header(optionalWrap: ()) + let header = RawKeyPathComponent.Header(optionalWrap: ()) unsafe pushDest(header) } mutating func visitOptionalForceComponent() { unsafe isPureStruct.append(false) let _ = unsafe updatePreviousComponentAddr() - let header = unsafe RawKeyPathComponent.Header(optionalForce: ()) + let header = RawKeyPathComponent.Header(optionalForce: ()) unsafe pushDest(header) } @@ -4183,7 +4183,7 @@ internal func _instantiateKeyPathBuffer( if let endOfReferencePrefixComponent = unsafe endOfReferencePrefixComponent { var componentHeader = unsafe endOfReferencePrefixComponent .load(as: RawKeyPathComponent.Header.self) - unsafe componentHeader.endOfReferencePrefix = true + componentHeader.endOfReferencePrefix = true unsafe endOfReferencePrefixComponent.storeBytes(of: componentHeader, as: RawKeyPathComponent.Header.self) } @@ -4224,7 +4224,7 @@ public func _createOffsetBasedKeyPath( let kpBufferSize = MemoryLayout.size + MemoryLayout.size let kp = unsafe kpTy._create(capacityInBytes: kpBufferSize) { var builder = unsafe KeyPathBuffer.Builder($0) - let header = unsafe KeyPathBuffer.Header( + let header = KeyPathBuffer.Header( size: kpBufferSize - MemoryLayout.size, trivial: true, hasReferencePrefix: false, @@ -4233,7 +4233,7 @@ public func _createOffsetBasedKeyPath( unsafe builder.pushHeader(header) - let componentHeader = unsafe RawKeyPathComponent.Header( + let componentHeader = RawKeyPathComponent.Header( stored: _MetadataKind(root) == .struct ? .struct : .class, mutable: false, inlineOffset: UInt32(offset) @@ -4301,7 +4301,7 @@ public func _rerootKeyPath( capacityInBytes: capacity ) { var builder = unsafe KeyPathBuffer.Builder($0) - let header = unsafe KeyPathBuffer.Header( + let header = KeyPathBuffer.Header( size: componentSize, trivial: isTrivial, hasReferencePrefix: hasReferencePrefix, @@ -4393,13 +4393,13 @@ extension AnyKeyPath: CustomDebugStringConvertible { let (rawComponent, optNextType) = unsafe buffer.next() let hasEnded = optNextType == nil let nextType = optNextType ?? Self.valueType - switch unsafe rawComponent.value { + switch rawComponent.value { case .optionalForce, .optionalWrap, .optionalChain: break default: description.append(".") } - switch unsafe rawComponent.value { + switch rawComponent.value { case .class(let offset), .struct(let offset): let count = _getRecursiveChildCount(valueType) @@ -4429,7 +4429,7 @@ extension AnyKeyPath: CustomDebugStringConvertible { .mutatingGetSet(_, let accessors, _): func project(base: Base.Type) -> String { func project2(leaf: Leaf.Type) -> String { - unsafe dynamicLibraryAddress( + dynamicLibraryAddress( of: accessors, base, leaf diff --git a/stdlib/public/core/NativeDictionary.swift b/stdlib/public/core/NativeDictionary.swift index d7eba4c7e583e..039ce5eef3a81 100644 --- a/stdlib/public/core/NativeDictionary.swift +++ b/stdlib/public/core/NativeDictionary.swift @@ -120,6 +120,7 @@ extension _NativeDictionary { // Primitive fields extension _NativeDictionary { // Low-level unchecked operations @inlinable @inline(__always) + @unsafe internal func uncheckedKey(at bucket: Bucket) -> Key { defer { _fixLifetime(self) } unsafe _internalInvariant(hashTable.isOccupied(bucket)) @@ -128,6 +129,7 @@ extension _NativeDictionary { // Low-level unchecked operations @inlinable @inline(__always) + @unsafe internal func uncheckedValue(at bucket: Bucket) -> Value { defer { _fixLifetime(self) } unsafe _internalInvariant(hashTable.isOccupied(bucket)) @@ -136,6 +138,7 @@ extension _NativeDictionary { // Low-level unchecked operations @inlinable // FIXME(inline-always) was usableFromInline @inline(__always) + @unsafe internal func uncheckedInitialize( at bucket: Bucket, toKey key: __owned Key, @@ -148,6 +151,7 @@ extension _NativeDictionary { // Low-level unchecked operations @inlinable // FIXME(inline-always) was usableFromInline @inline(__always) + @unsafe internal func uncheckedDestroy(at bucket: Bucket) { defer { _fixLifetime(self) } unsafe _internalInvariant(hashTable.isValid(bucket)) @@ -300,7 +304,7 @@ extension _NativeDictionary { let key = _forceBridgeFromObjectiveC(cocoa.key, Key.self) let (bucket, found) = find(key) if found { - return unsafe bucket + return bucket } } _preconditionFailure( @@ -331,7 +335,7 @@ extension _NativeDictionary: _DictionaryBuffer { internal func index(after index: Index) -> Index { #if _runtime(_ObjC) guard _fastPath(index._isNative) else { - let _ = unsafe validatedBucket(for: index) + let _ = validatedBucket(for: index) let i = index._asCocoa return Index(_cocoa: i.dictionary.index(after: i)) } @@ -384,7 +388,7 @@ extension _NativeDictionary: _DictionaryBuffer { @inlinable @inline(__always) func lookup(_ index: Index) -> (key: Key, value: Value) { - let bucket = unsafe validatedBucket(for: index) + let bucket = validatedBucket(for: index) let key = unsafe self.uncheckedKey(at: bucket) let value = unsafe self.uncheckedValue(at: bucket) return (key, value) @@ -393,14 +397,14 @@ extension _NativeDictionary: _DictionaryBuffer { @inlinable @inline(__always) func key(at index: Index) -> Key { - let bucket = unsafe validatedBucket(for: index) + let bucket = validatedBucket(for: index) return unsafe self.uncheckedKey(at: bucket) } @inlinable @inline(__always) func value(at index: Index) -> Value { - let bucket = unsafe validatedBucket(for: index) + let bucket = validatedBucket(for: index) return unsafe self.uncheckedValue(at: bucket) } } @@ -429,14 +433,14 @@ extension _NativeDictionary { } else { // **Insertion.** Insert the new entry at the correct place. Note // that `mutatingFind` already ensured that we have enough capacity. - unsafe _insert(at: bucket, key: key, value: value) + _insert(at: bucket, key: key, value: value) } } else { if found { // **Removal.** We've already deinitialized the value; deinitialize // the key too and register the removal. unsafe (_keys + bucket.offset).deinitialize(count: 1) - unsafe _delete(at: bucket) + _delete(at: bucket) } else { // Noop } @@ -477,7 +481,7 @@ extension _NativeDictionary { // Insertions // elements -- these imply that the Element type violates Hashable // requirements. This is generally more costly than a direct insertion, // because we'll need to compare elements in case of hash collisions. - let (bucket, found) = unsafe find(key, hashValue: hashValue) + let (bucket, found) = find(key, hashValue: hashValue) guard !found else { #if !$Embedded KEY_TYPE_OF_DICTIONARY_VIOLATES_HASHABLE_REQUIREMENTS(Key.self) @@ -512,7 +516,7 @@ extension _NativeDictionary { // Insertions unsafe (_values + bucket.offset).pointee = value } else { _precondition(count < capacity) - unsafe _insert(at: bucket, key: key, value: value) + _insert(at: bucket, key: key, value: value) } } @@ -546,7 +550,7 @@ extension _NativeDictionary { // Insertions let rehashed = ensureUnique( isUnique: isUnique, capacity: count + (found ? 0 : 1)) - guard rehashed else { return unsafe (bucket, found) } + guard rehashed else { return (bucket, found) } let (b, f) = find(key) if f != found { #if !$Embedded @@ -555,7 +559,7 @@ extension _NativeDictionary { // Insertions fatalError("duplicate keys in a Dictionary") #endif } - return unsafe (b, found) + return (b, found) } @inlinable @@ -581,7 +585,7 @@ extension _NativeDictionary { // Insertions unsafe (_values + bucket.offset).initialize(to: value) return oldValue } - unsafe _insert(at: bucket, key: key, value: value) + _insert(at: bucket, key: key, value: value) return nil } @@ -595,7 +599,7 @@ extension _NativeDictionary { // Insertions if found { unsafe (_values + bucket.offset).pointee = value } else { - unsafe _insert(at: bucket, key: key, value: value) + _insert(at: bucket, key: key, value: value) } } } @@ -716,6 +720,7 @@ extension _NativeDictionary { // Deletion @inlinable @_semantics("optimize.sil.specialize.generic.size.never") + @unsafe internal mutating func uncheckedRemove( at bucket: Bucket, isUnique: Bool @@ -725,7 +730,7 @@ extension _NativeDictionary { // Deletion _internalInvariant(!rehashed) let oldKey = unsafe (_keys + bucket.offset).move() let oldValue = unsafe (_values + bucket.offset).move() - unsafe _delete(at: bucket) + _delete(at: bucket) return (oldKey, oldValue) } @@ -763,7 +768,7 @@ extension _NativeDictionary { // High-level operations for unsafe bucket in unsafe hashTable { let key = unsafe self.uncheckedKey(at: bucket) let value = unsafe self.uncheckedValue(at: bucket) - try unsafe result._insert(at: bucket, key: key, value: transform(value)) + try result._insert(at: bucket, key: key, value: transform(value)) } return result } @@ -790,7 +795,7 @@ extension _NativeDictionary { // High-level operations #endif } } else { - unsafe _insert(at: bucket, key: key, value: value) + _insert(at: bucket, key: key, value: value) } } } @@ -818,7 +823,7 @@ extension _NativeDictionary { // High-level operations #endif } } else { - unsafe _insert(at: bucket, key: key, value: value) + _insert(at: bucket, key: key, value: value) } } } @@ -837,7 +842,7 @@ extension _NativeDictionary { // High-level operations if found { unsafe _values[bucket.offset].append(value) } else { - unsafe _insert(at: bucket, key: key, value: [value]) + _insert(at: bucket, key: key, value: [value]) } } } diff --git a/stdlib/public/core/NativeSet.swift b/stdlib/public/core/NativeSet.swift index f16fac868cfd9..111f489d43967 100644 --- a/stdlib/public/core/NativeSet.swift +++ b/stdlib/public/core/NativeSet.swift @@ -117,6 +117,7 @@ extension _NativeSet { // Primitive fields extension _NativeSet { // Low-level unchecked operations @inlinable @inline(__always) + @unsafe internal func uncheckedElement(at bucket: Bucket) -> Element { defer { _fixLifetime(self) } unsafe _internalInvariant(hashTable.isOccupied(bucket)) @@ -125,6 +126,7 @@ extension _NativeSet { // Low-level unchecked operations @inlinable @inline(__always) + @unsafe internal func uncheckedInitialize( at bucket: Bucket, to element: __owned Element @@ -135,6 +137,7 @@ extension _NativeSet { // Low-level unchecked operations @_alwaysEmitIntoClient @inlinable // Introduced in 5.1 @inline(__always) + @unsafe internal func uncheckedAssign( at bucket: Bucket, to element: __owned Element @@ -155,7 +158,7 @@ extension _NativeSet { // Low-level lookup operations @inlinable @inline(__always) internal func find(_ element: Element) -> (bucket: Bucket, found: Bool) { - return unsafe find(element, hashValue: self.hashValue(for: element)) + return find(element, hashValue: self.hashValue(for: element)) } /// Search for a given element, assuming it has the specified hash value. @@ -172,11 +175,11 @@ extension _NativeSet { // Low-level lookup operations var bucket = unsafe hashTable.idealBucket(forHashValue: hashValue) while unsafe hashTable._isOccupied(bucket) { if unsafe uncheckedElement(at: bucket) == element { - return unsafe (bucket, true) + return (bucket, true) } unsafe bucket = unsafe hashTable.bucket(wrappedAfter: bucket) } - return unsafe (bucket, false) + return (bucket, false) } } @@ -191,7 +194,7 @@ extension _NativeSet { // ensureUnique if count > 0 { for unsafe bucket in unsafe hashTable { let element = unsafe (self._elements + bucket.offset).move() - result._unsafeInsertNew(element) + unsafe result._unsafeInsertNew(element) } // Clear out old storage, ensuring that its deinit won't overrelease the // elements we've just moved out. @@ -283,7 +286,7 @@ extension _NativeSet { let element = _forceBridgeFromObjectiveC(cocoa.element, Element.self) let (bucket, found) = find(element) if found { - return unsafe bucket + return bucket } } _preconditionFailure( @@ -348,7 +351,7 @@ extension _NativeSet: _SetBuffer { @inlinable @inline(__always) internal func element(at index: Index) -> Element { - let bucket = unsafe validatedBucket(for: index) + let bucket = validatedBucket(for: index) return unsafe uncheckedElement(at: bucket) } } @@ -375,6 +378,7 @@ extension _NativeSet { // Insertions /// Storage must be uniquely referenced with adequate capacity. /// The `element` must not be already present in the Set. @inlinable + @unsafe internal func _unsafeInsertNew(_ element: __owned Element) { _internalInvariant(count + 1 <= capacity) let hashValue = self.hashValue(for: element) @@ -383,7 +387,7 @@ extension _NativeSet { // Insertions // elements -- these imply that the Element type violates Hashable // requirements. This is generally more costly than a direct insertion, // because we'll need to compare elements in case of hash collisions. - let (bucket, found) = unsafe find(element, hashValue: hashValue) + let (bucket, found) = find(element, hashValue: hashValue) guard !found else { #if !$Embedded ELEMENT_TYPE_OF_SET_VIOLATES_HASHABLE_REQUIREMENTS(Element.self) @@ -406,10 +410,11 @@ extension _NativeSet { // Insertions @inlinable internal mutating func insertNew(_ element: __owned Element, isUnique: Bool) { _ = ensureUnique(isUnique: isUnique, capacity: count + 1) - _unsafeInsertNew(element) + unsafe _unsafeInsertNew(element) } @inlinable + @unsafe internal func _unsafeInsertNew(_ element: __owned Element, at bucket: Bucket) { unsafe hashTable.insert(bucket) unsafe uncheckedInitialize(at: bucket, to: element) @@ -423,7 +428,7 @@ extension _NativeSet { // Insertions isUnique: Bool ) { unsafe _internalInvariant(!hashTable.isOccupied(bucket)) - var bucket = unsafe bucket + var bucket = bucket let rehashed = ensureUnique(isUnique: isUnique, capacity: count + 1) if rehashed { let (b, f) = find(element) @@ -434,7 +439,7 @@ extension _NativeSet { // Insertions fatalError("duplicate elements in a Set") #endif } - unsafe bucket = unsafe b + bucket = b } unsafe _unsafeInsertNew(element, at: bucket) } @@ -457,7 +462,7 @@ extension _NativeSet { // Insertions fatalError("duplicate elements in a Set") #endif } - unsafe bucket = unsafe b + bucket = b } if found { let old = unsafe (_elements + bucket.offset).move() @@ -540,6 +545,7 @@ extension _NativeSet { // Deletion @inlinable @inline(__always) + @unsafe internal mutating func uncheckedRemove( at bucket: Bucket, isUnique: Bool) -> Element { @@ -547,7 +553,7 @@ extension _NativeSet { // Deletion let rehashed = ensureUnique(isUnique: isUnique, capacity: capacity) _internalInvariant(!rehashed) let old = unsafe (_elements + bucket.offset).move() - unsafe _delete(at: bucket) + _delete(at: bucket) return old } @@ -710,11 +716,11 @@ extension _NativeSet { while let next = it.next() { let (b, found) = find(next) if found { - unsafe bucket = unsafe b + bucket = b break } } - guard let bucket = unsafe bucket else { return self } + guard let bucket = bucket else { return self } // Rather than directly creating a new set, calculate the difference in a // bitset first. This ensures we hash each element (in both sets) only once, diff --git a/stdlib/public/core/Pointer.swift b/stdlib/public/core/Pointer.swift index 3fc7e0ee3199b..d74ef63ca80fe 100644 --- a/stdlib/public/core/Pointer.swift +++ b/stdlib/public/core/Pointer.swift @@ -304,12 +304,12 @@ extension _Pointer /*: Strideable*/ { extension _Pointer /*: Hashable */ { @inlinable - public func hash(into hasher: inout Hasher) { + @safe public func hash(into hasher: inout Hasher) { hasher.combine(UInt(bitPattern: self)) } @inlinable - public func _rawHashValue(seed: Int) -> Int { + @safe public func _rawHashValue(seed: Int) -> Int { return Hasher._hash(seed: seed, UInt(bitPattern: self)) } } @@ -317,14 +317,14 @@ extension _Pointer /*: Hashable */ { @_unavailableInEmbedded extension _Pointer /*: CustomDebugStringConvertible */ { /// A textual representation of the pointer, suitable for debugging. - public var debugDescription: String { + @safe public var debugDescription: String { return _rawPointerToString(_rawValue) } } #if SWIFT_ENABLE_REFLECTION extension _Pointer /*: CustomReflectable */ { - public var customMirror: Mirror { + @safe public var customMirror: Mirror { let ptrValue = UInt64( bitPattern: Int64(Int(Builtin.ptrtoint_Word(_rawValue)))) return Mirror(self, children: ["pointerValue": ptrValue]) diff --git a/stdlib/public/core/SetBridging.swift b/stdlib/public/core/SetBridging.swift index 458b1d30424bf..50fef663beec7 100644 --- a/stdlib/public/core/SetBridging.swift +++ b/stdlib/public/core/SetBridging.swift @@ -103,12 +103,12 @@ final internal class _SwiftSetNSEnumerator @objc internal func nextObject() -> AnyObject? { - if unsafe nextBucket == endBucket { + if nextBucket == endBucket { return nil } - let bucket = unsafe nextBucket + let bucket = nextBucket unsafe nextBucket = base.hashTable.occupiedBucket(after: nextBucket) - return unsafe self.bridgedElement(at: bucket) + return self.bridgedElement(at: bucket) } @objc(countByEnumeratingWithState:objects:count:) @@ -124,7 +124,7 @@ final internal class _SwiftSetNSEnumerator unsafe theState.mutationsPtr = _fastEnumerationStorageMutationsPtr } - if unsafe nextBucket == endBucket { + if nextBucket == endBucket { unsafe state.pointee = theState return 0 } @@ -276,7 +276,7 @@ final internal class _SwiftDeferredNSSet var stored = 0 for i in 0.. { public mutating func add(member: Element) { _precondition(_target.count < _requestedCount, "Can't add more members than promised") - _target._unsafeInsertNew(member) + unsafe _target._unsafeInsertNew(member) } @inlinable diff --git a/stdlib/public/core/SetCasting.swift b/stdlib/public/core/SetCasting.swift index d39aba31daf32..76208d91649c6 100644 --- a/stdlib/public/core/SetCasting.swift +++ b/stdlib/public/core/SetCasting.swift @@ -29,7 +29,7 @@ extension Set { } else { for m in source { guard let member = transform(m) else { return nil } - target._unsafeInsertNew(member) + unsafe target._unsafeInsertNew(member) } } self.init(_native: target) diff --git a/stdlib/public/core/SetStorage.swift b/stdlib/public/core/SetStorage.swift index 9705a7fee064e..fe4c0b1199014 100644 --- a/stdlib/public/core/SetStorage.swift +++ b/stdlib/public/core/SetStorage.swift @@ -289,7 +289,7 @@ final internal class _SetStorage "Invalid fast enumeration state") var stored = 0 for i in 0.., by areInIncreasingOrder: (Element, Element) throws -> Bool ) rethrows -> Bool { - unsafe _internalInvariant(runs[i - 1].upperBound == runs[i].lowerBound) - let low = unsafe runs[i - 1].lowerBound - let middle = unsafe runs[i].lowerBound - let high = unsafe runs[i].upperBound + _internalInvariant(runs[i - 1].upperBound == runs[i].lowerBound) + let low = runs[i - 1].lowerBound + let middle = runs[i].lowerBound + let high = runs[i].upperBound try unsafe _merge( low: baseAddress! + low, @@ -542,8 +542,8 @@ extension UnsafeMutableBufferPointer { buffer: buffer, by: areInIncreasingOrder) - unsafe runs[i - 1] = unsafe low.. 1 { - var lastIndex = unsafe runs.count - 1 + while runs.count > 1 { + var lastIndex = runs.count - 1 // Check for the three invariant-breaking conditions, and break out of // the while loop if none are met. - if unsafe lastIndex >= 3 && + if lastIndex >= 3 && (runs[lastIndex - 3].count <= runs[lastIndex - 2].count + runs[lastIndex - 1].count) { // Second-to-last three runs do not follow W > X + Y. // Always merge Y with the smaller of X or Z. - if unsafe runs[lastIndex - 2].count < runs[lastIndex].count { + if runs[lastIndex - 2].count < runs[lastIndex].count { lastIndex -= 1 } - } else if unsafe lastIndex >= 2 && + } else if lastIndex >= 2 && (runs[lastIndex - 2].count <= runs[lastIndex - 1].count + runs[lastIndex].count) { // Last three runs do not follow X > Y + Z. // Always merge Y with the smaller of X or Z. - if unsafe runs[lastIndex - 2].count < runs[lastIndex].count { + if runs[lastIndex - 2].count < runs[lastIndex].count { lastIndex -= 1 } - } else if unsafe runs[lastIndex - 1].count <= runs[lastIndex].count { + } else if runs[lastIndex - 1].count <= runs[lastIndex].count { // Last two runs do not follow Y > Z, so merge Y and Z. // This block is intentionally blank--the merge happens below. } else { @@ -645,7 +645,7 @@ extension UnsafeMutableBufferPointer { buffer: UnsafeMutablePointer, by areInIncreasingOrder: (Element, Element) throws -> Bool ) rethrows -> Bool { - while unsafe runs.count > 1 { + while runs.count > 1 { try unsafe _mergeRuns( &runs, at: runs.count - 1, buffer: buffer, by: areInIncreasingOrder) } @@ -677,7 +677,7 @@ extension UnsafeMutableBufferPointer { // closure, since the buffer is guaranteed to be uninitialized at exit. _ = try unsafe Array(_unsafeUninitializedCapacity: count / 2) { buffer, _ in - var runs: [Range] = unsafe [] + var runs: [Range] = [] var start = startIndex while start < endIndex { @@ -690,24 +690,24 @@ extension UnsafeMutableBufferPointer { // If the current run is shorter than the minimum length, use the // insertion sort to extend it. - if unsafe end < endIndex && end - start < minimumRunLength { + if end < endIndex && end - start < minimumRunLength { let newEnd = Swift.min(endIndex, start + minimumRunLength) try unsafe _insertionSort( within: start..) -> UTF8ValidationR func _legacyNarrowIllegalRange(buf: Slice>) -> Range { var reversePacked: UInt32 = 0 if let third = unsafe buf.dropFirst(2).first { - unsafe reversePacked |= UInt32(third) + reversePacked |= UInt32(third) reversePacked <<= 8 } if let second = unsafe buf.dropFirst().first { - unsafe reversePacked |= UInt32(second) + reversePacked |= UInt32(second) reversePacked <<= 8 } unsafe reversePacked |= UInt32(buf.first!) @@ -177,8 +177,8 @@ internal func validateUTF8(_ buf: UnsafeBufferPointer) -> UTF8ValidationR var endIndex = unsafe buf.startIndex var iter = unsafe buf.makeIterator() _ = unsafe iter.next() - while let cu = unsafe iter.next(), unsafe UTF8.isContinuation(cu) { - unsafe endIndex += 1 + while let cu = unsafe iter.next(), UTF8.isContinuation(cu) { + endIndex += 1 // Unicode's Maximal subpart of an ill-formed subsequence will yield // at most 3 bytes of error. if unsafe buf.distance(from: buf.startIndex, to: endIndex) >= 3 { diff --git a/stdlib/public/core/UnsafeBufferPointer.swift.gyb b/stdlib/public/core/UnsafeBufferPointer.swift.gyb index ca385ef259525..94897c6afd15b 100644 --- a/stdlib/public/core/UnsafeBufferPointer.swift.gyb +++ b/stdlib/public/core/UnsafeBufferPointer.swift.gyb @@ -1300,7 +1300,7 @@ extension UnsafeMutableBufferPointer where Element: ~Copyable { /// - index: The index of the element to initialize @_alwaysEmitIntoClient public func initializeElement(at index: Index, to value: consuming Element) { - _debugPrecondition(unsafe startIndex <= index && index < endIndex) + _debugPrecondition(startIndex <= index && index < endIndex) let p = unsafe baseAddress._unsafelyUnwrappedUnchecked.advanced(by: index) unsafe p.initialize(to: value) } @@ -1317,7 +1317,7 @@ extension UnsafeMutableBufferPointer where Element: ~Copyable { /// - Returns: The instance referenced by this index in this buffer. @_alwaysEmitIntoClient public func moveElement(from index: Index) -> Element { - _debugPrecondition(unsafe startIndex <= index && index < endIndex) + _debugPrecondition(startIndex <= index && index < endIndex) return unsafe baseAddress._unsafelyUnwrappedUnchecked.advanced(by: index).move() } @@ -1331,7 +1331,7 @@ extension UnsafeMutableBufferPointer where Element: ~Copyable { /// - index: The index of the buffer element to deinitialize. @_alwaysEmitIntoClient public func deinitializeElement(at index: Index) { - _debugPrecondition(unsafe startIndex <= index && index < endIndex) + _debugPrecondition(startIndex <= index && index < endIndex) let p = unsafe baseAddress._unsafelyUnwrappedUnchecked.advanced(by: index) unsafe p.deinitialize(count: 1) } diff --git a/stdlib/public/core/VarArgs.swift b/stdlib/public/core/VarArgs.swift index c520741096b5b..949805a726633 100644 --- a/stdlib/public/core/VarArgs.swift +++ b/stdlib/public/core/VarArgs.swift @@ -567,7 +567,7 @@ final internal class __VaListBuilder { @inlinable // c-abi internal func va_list() -> CVaListPointer { #if arch(x86_64) || arch(s390x) - header.reg_save_area = storage._baseAddress + unsafe header.reg_save_area = storage._baseAddress unsafe header.overflow_arg_area = storage._baseAddress + _registerSaveWords return unsafe CVaListPointer( diff --git a/test/Unsafe/safe.swift b/test/Unsafe/safe.swift index 439788892ee93..48886d8d0675f 100644 --- a/test/Unsafe/safe.swift +++ b/test/Unsafe/safe.swift @@ -271,3 +271,40 @@ struct UnsafeWrapTest { @safe @unsafe struct ConfusedStruct { } // expected-error{{struct 'ConfusedStruct' cannot be both @safe and @unsafe}} + +@unsafe +struct UnsafeContainingUnspecified { + typealias A = Int + + func getA() -> A { 0 } + + @safe + struct Y { + var value: Int + } + + func f() { + _ = Y(value: 5) + } +} + + +@unsafe func f(x: UnsafeContainingUnspecified) { + let a = unsafe x.getA() + _ = a +} + +extension Slice { + // Make sure we aren't diagnosing the 'defer' as unsafe. + public func withContiguousMutableStorageIfAvailable( + _ body: (_ buffer: inout UnsafeMutableBufferPointer) throws -> R + ) rethrows -> R? where Base == UnsafeMutableBufferPointer { + try unsafe base.withContiguousStorageIfAvailable { buffer in + let start = unsafe base.baseAddress?.advanced(by: startIndex) + var slice = unsafe UnsafeMutableBufferPointer(start: start, count: count) + defer { + } + return try unsafe body(&slice) + } + } +}