Skip to content

[stdlib] Clean up some more unsafeBitCast warnings #7329

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion stdlib/public/SDK/Foundation/Data.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public final class _DataStorage {
var dest = dest_
var source = source_
var num = num_
if _DataStorage.vmOpsThreshold <= num && ((unsafeBitCast(source, to: Int.self) | unsafeBitCast(dest, to: Int.self)) & (NSPageSize() - 1)) == 0 {
if _DataStorage.vmOpsThreshold <= num && ((Int(bitPattern: source) | Int(bitPattern: dest)) & (NSPageSize() - 1)) == 0 {
let pages = NSRoundDownToMultipleOfPageSize(num)
NSCopyMemoryPages(source!, dest, pages)
source = source!.advanced(by: pages)
Expand Down
5 changes: 4 additions & 1 deletion stdlib/public/SDK/Foundation/DateInterval.swift
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,10 @@ public struct DateInterval : ReferenceConvertible, Comparable, Hashable {
public var hashValue: Int {
var buf: (UInt, UInt) = (UInt(start.timeIntervalSinceReferenceDate), UInt(end.timeIntervalSinceReferenceDate))
return withUnsafeMutablePointer(to: &buf) {
return Int(bitPattern: CFHashBytes(unsafeBitCast($0, to: UnsafeMutablePointer<UInt8>.self), CFIndex(MemoryLayout<UInt>.size * 2)))
let size = MemoryLayout<UInt>.size * 2
return $0.withMemoryRebound(to: UInt8.self, capacity: size) {
Int(bitPattern: CFHashBytes($0, CFIndex(size)))
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions stdlib/public/SDK/Foundation/IndexSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,7 @@ private final class _MutablePairHandle<ImmutableType : NSObject, MutableType : N
return try whatToDo(i)
case .Mutable(let m):
// TODO: It should be possible to reflect the constraint that MutableType is a subtype of ImmutableType in the generics for the class, but I haven't figured out how yet. For now, cheat and unsafe bit cast.
return try whatToDo(unsafeBitCast(m, to: ImmutableType.self))
return try whatToDo(unsafeDowncast(m, to: ImmutableType.self))
}
}

Expand All @@ -966,7 +966,7 @@ private final class _MutablePairHandle<ImmutableType : NSObject, MutableType : N
return i
case .Mutable(let m):
// TODO: It should be possible to reflect the constraint that MutableType is a subtype of ImmutableType in the generics for the class, but I haven't figured out how yet. For now, cheat and unsafe bit cast.
return unsafeBitCast(m, to: ImmutableType.self)
return unsafeDowncast(m, to: ImmutableType.self)
}
}
}
44 changes: 30 additions & 14 deletions stdlib/public/SDK/Foundation/UUID.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@
@_exported import Foundation // Clang module
import Darwin.uuid

func withUnsafeMutablePointer<T, U, Result>(
to arg: inout T,
as type: U.Type,
capacity count: Int,
_ body: (UnsafeMutablePointer<U>) -> Result
) -> Result
{
return withUnsafeMutablePointer(to: &arg) {
$0.withMemoryRebound(to: type, capacity: count) { ptr in
body(ptr)
}
}
}

/// Represents UUID strings, which can be used to uniquely identify types, interfaces, and other items.
@available(OSX 10.8, iOS 6.0, *)
public struct UUID : ReferenceConvertible, Hashable, Equatable, CustomStringConvertible {
Expand All @@ -22,15 +36,15 @@ public struct UUID : ReferenceConvertible, Hashable, Equatable, CustomStringConv

/* Create a new UUID with RFC 4122 version 4 random bytes */
public init() {
withUnsafeMutablePointer(to: &uuid) {
uuid_generate_random(unsafeBitCast($0, to: UnsafeMutablePointer<UInt8>.self))
withUnsafeMutablePointer(to: &uuid, as: UInt8.self, capacity: MemoryLayout.size(ofValue: uuid)) {
uuid_generate_random($0)
}
}

fileprivate init(reference: NSUUID) {
var bytes: uuid_t = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
withUnsafeMutablePointer(to: &bytes) {
reference.getBytes(unsafeBitCast($0, to: UnsafeMutablePointer<UInt8>.self))
withUnsafeMutablePointer(to: &bytes, as: UInt8.self, capacity: MemoryLayout.size(ofValue: bytes)) {
reference.getBytes($0)
}
uuid = bytes
}
Expand All @@ -39,8 +53,8 @@ public struct UUID : ReferenceConvertible, Hashable, Equatable, CustomStringConv
///
/// Returns nil for invalid strings.
public init?(uuidString string: String) {
let res = withUnsafeMutablePointer(to: &uuid) {
return uuid_parse(string, unsafeBitCast($0, to: UnsafeMutablePointer<UInt8>.self))
let res = withUnsafeMutablePointer(to: &uuid, as: UInt8.self, capacity: MemoryLayout.size(ofValue: uuid)) {
uuid_parse(string, $0)
}
if res != 0 {
return nil
Expand All @@ -56,18 +70,20 @@ public struct UUID : ReferenceConvertible, Hashable, Equatable, CustomStringConv
public var uuidString: String {
var bytes: uuid_string_t = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
var localValue = uuid
return withUnsafeMutablePointer(to: &localValue) { val in
withUnsafeMutablePointer(to: &bytes) { str in
uuid_unparse(unsafeBitCast(val, to: UnsafePointer<UInt8>.self), unsafeBitCast(str, to: UnsafeMutablePointer<Int8>.self))
return String(cString: unsafeBitCast(str, to: UnsafePointer<CChar>.self), encoding: .utf8)!
return withUnsafeMutablePointer(to: &localValue, as: UInt8.self, capacity: MemoryLayout.size(ofValue: localValue)) { val in
withUnsafeMutablePointer(to: &bytes, as: Int8.self, capacity: MemoryLayout.size(ofValue: bytes)) { str in
uuid_unparse(val, str)
return str.withMemoryRebound(to: CChar.self, capacity: MemoryLayout.size(ofValue: bytes)) {
String(cString: $0, encoding: .utf8)!
}
}
}
}

public var hashValue: Int {
var localValue = uuid
return withUnsafeMutablePointer(to: &localValue) {
return Int(bitPattern: CFHashBytes(unsafeBitCast($0, to: UnsafeMutablePointer<UInt8>.self), CFIndex(MemoryLayout<uuid_t>.size)))
return withUnsafeMutablePointer(to: &localValue, as: UInt8.self, capacity: MemoryLayout.size(ofValue: localValue)) {
return Int(bitPattern: CFHashBytes($0, CFIndex(MemoryLayout<uuid_t>.size)))
}
}

Expand All @@ -83,8 +99,8 @@ public struct UUID : ReferenceConvertible, Hashable, Equatable, CustomStringConv

fileprivate var reference: NSUUID {
var bytes = uuid
return withUnsafePointer(to: &bytes) {
return NSUUID(uuidBytes: unsafeBitCast($0, to: UnsafePointer<UInt8>.self))
return withUnsafeMutablePointer(to: &bytes, as: UInt8.self, capacity: MemoryLayout.size(ofValue: bytes)) {
return NSUUID(uuidBytes: $0)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, I didn't know about that form of withUnsafePointer. That might be a better recommendation for the compiler to emit a warning for when bitcasting from a homogeneous tuple to its element type. Mind filing a bug for that diagnostic improvement?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that was one I'd written just for UUID.swift since it has so many of the two operations together (convert to pointer and then cast). It's here—could be a nice addition, but I don't know that it's necessary: https://github.com/apple/swift/pull/7329/files/cf260a26173985f867fb33cf52c808ec481aad44#diff-9e8b701cacc2a5ba71da8979a386a127R16

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I missed that. It does seem like a generally useful variant.

}

Expand Down