Skip to content

Add some availability attributes for UnsafePointer conversion. #4064

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

Merged
merged 1 commit into from
Aug 6, 2016
Merged
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
1 change: 1 addition & 0 deletions stdlib/public/core/Integers.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ extension BinaryInteger {
public init?<T : FloatingPoint>(exactly source: T) {
// FIXME(integers): implement
fatalError()
return nil
}

public init<T : FloatingPoint>(_ source: T) {
Expand Down
24 changes: 24 additions & 0 deletions stdlib/public/core/UnsafePointer.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,30 @@ public func -= <Pointee>(lhs: inout ${Self}<Pointee>, rhs: Int) {
}

extension ${Self} {
@available(*, unavailable, message:
"use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.")
public init<U>(_ from : UnsafeMutablePointer<U>) { Builtin.unreachable() }

@available(*, unavailable, message:
"use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.")
public init?<U>(_ from : UnsafeMutablePointer<U>?) { Builtin.unreachable(); return nil }

@available(*, unavailable, message:
"use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.")
public init<U>(_ from : UnsafePointer<U>) { Builtin.unreachable() }

@available(*, unavailable, message:
"use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.")
public init?<U>(_ from : UnsafePointer<U>?) { Builtin.unreachable(); return nil }

% if mutable:
@available(*, unavailable, renamed: "init(mutating:)")
public init(_ from : UnsafePointer<Pointee>) { Builtin.unreachable() }

@available(*, unavailable, renamed: "init(mutating:)")
public init?(_ from : UnsafePointer<Pointee>?) { Builtin.unreachable(); return nil }
% end

@available(*, unavailable, renamed: "Pointee")
public typealias Memory = Pointee

Expand Down
13 changes: 13 additions & 0 deletions stdlib/public/core/UnsafeRawPointer.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -549,3 +549,16 @@ extension UInt {

% end # for mutable

extension UnsafeMutableRawPointer {
@available(*, unavailable, renamed: "init(mutating:)")
public init(_ from : UnsafeRawPointer) { Builtin.unreachable() }

@available(*, unavailable, renamed: "init(mutating:)")
public init?(_ from : UnsafeRawPointer?) { Builtin.unreachable(); return nil }

@available(*, unavailable, renamed: "init(mutating:)")
public init<T>(_ from : UnsafePointer<T>) { Builtin.unreachable() }

@available(*, unavailable, renamed: "init(mutating:)")
public init?<T>(_ from : UnsafePointer<T>?) { Builtin.unreachable(); return nil }
}
80 changes: 80 additions & 0 deletions test/1_stdlib/UnsafePointerDiagnostics.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// RUN: %target-parse-verify-swift

// Test availability attributes on UnsafePointer initializers.
// Assume the original source contains no UnsafeRawPointer types.
//
// TODO:
// - implement the Unsafe[Mutable]Pointer<Void> to Unsafe[Mutable]RawPointer rename
// - test multiple fix-its per line: type rename + initializer rename/diagnostic
func unsafePointerConversionAvailability(
mrp: UnsafeMutableRawPointer,
rp: UnsafeRawPointer,
umpv: UnsafeMutablePointer<Void>,
upv: UnsafePointer<Void>,
umpi: UnsafeMutablePointer<Int>,
upi: UnsafePointer<Int>,
umps: UnsafeMutablePointer<String>,
ups: UnsafePointer<String>) {

_ = UnsafeMutableRawPointer(mrp)
_ = UnsafeMutableRawPointer(rp) // expected-error {{'init' has been renamed to 'init(mutating:)'}}
_ = UnsafeMutableRawPointer(umpv)
_ = UnsafeMutableRawPointer(upv) // expected-error {{'init' has been renamed to 'init(mutating:)'}}
_ = UnsafeMutableRawPointer(umpi)
_ = UnsafeMutableRawPointer(upi) // expected-error {{'init' has been renamed to 'init(mutating:)'}}
_ = UnsafeMutableRawPointer(umps)
_ = UnsafeMutableRawPointer(ups) // expected-error {{'init' has been renamed to 'init(mutating:)'}}

// These all correctly pass with no error.
_ = UnsafeRawPointer(mrp)
_ = UnsafeRawPointer(rp)
_ = UnsafeRawPointer(umpv)
_ = UnsafeRawPointer(upv)
_ = UnsafeRawPointer(umpi)
_ = UnsafeRawPointer(upi)
_ = UnsafeRawPointer(umps)
_ = UnsafeRawPointer(ups)

// FIXME: All of these should yield a fix-it to rename
// UnsafeMutablePointer<Void> to UnsafeMutableRawPointer(umpv)
_ = UnsafeMutablePointer<Void>(rp) // expected-error {{cannot invoke initializer for type 'UnsafeMutablePointer<Void>' with an argument list of type '(UnsafeRawPointer)'}} expected-note {{}}
_ = UnsafeMutablePointer<Void>(mrp) // expected-error {{cannot invoke initializer for type 'UnsafeMutablePointer<Void>' with an argument list of type '(UnsafeMutableRawPointer)'}} expected-note {{}}
_ = UnsafeMutablePointer<Void>(umpv)
_ = UnsafeMutablePointer<Void>(upv) // expected-error {{'init' has been renamed to 'init(mutating:)'}}
_ = UnsafeMutablePointer<Void>(umpi)
_ = UnsafeMutablePointer<Void>(upi) // expected-error {{'init' has been renamed to 'init(mutating:)'}}
_ = UnsafeMutablePointer<Void>(umps)
_ = UnsafeMutablePointer<Void>(ups) // expected-error {{'init' has been renamed to 'init(mutating:)'}}

// FIXME: All of these should yield a fix-it to rename
// UnsafePointer<Void> to UnsafeRawPointer(umpv)
_ = UnsafePointer<Void>(rp) // expected-error {{cannot invoke initializer for type 'UnsafePointer<Void>' with an argument list of type '(UnsafeRawPointer)'}} expected-note {{}}
_ = UnsafePointer<Void>(mrp) // expected-error {{cannot invoke initializer for type 'UnsafePointer<Void>' with an argument list of type '(UnsafeMutableRawPointer)'}} expected-note {{}}
_ = UnsafePointer<Void>(umpv)
_ = UnsafePointer<Void>(upv)
_ = UnsafePointer<Void>(umpi)
_ = UnsafePointer<Void>(upi)
_ = UnsafePointer<Void>(umps)
_ = UnsafePointer<Void>(ups)

// FIXME: Conversion from UnsafePointer<Void> or UnsafeRawPointer to a typed
// pointer should have a diagnostic: 'init' is unavailable: Conversion
// restricted. Use 'assumingMemoryBound(to:)' or 'bindMemory(to:capacity:)'
_ = UnsafeMutablePointer<Int>(rp) // expected-error {{cannot invoke initializer for type 'UnsafeMutablePointer<Int>' with an argument list of type '(UnsafeRawPointer)'}} expected-note {{}}
_ = UnsafeMutablePointer<Int>(mrp) // expected-error {{cannot invoke initializer for type 'UnsafeMutablePointer<Int>' with an argument list of type '(UnsafeMutableRawPointer)'}} expected-note {{}}
_ = UnsafeMutablePointer<Int>(umpv) // expected-error {{'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.}}
_ = UnsafeMutablePointer<Int>(upv) // expected-error {{'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.}}
_ = UnsafeMutablePointer<Int>(umpi)
_ = UnsafeMutablePointer<Int>(upi) // expected-error {{'init' has been renamed to 'init(mutating:)'}}
_ = UnsafeMutablePointer<Int>(umps) // expected-error {{'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.}}
_ = UnsafeMutablePointer<Int>(ups) // expected-error {{'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.}}

_ = UnsafePointer<Int>(rp) // expected-error {{cannot invoke initializer for type 'UnsafePointer<Int>' with an argument list of type '(UnsafeRawPointer)'}} expected-note {{}}
_ = UnsafePointer<Int>(mrp) // expected-error {{cannot invoke initializer for type 'UnsafePointer<Int>' with an argument list of type '(UnsafeMutableRawPointer)'}} expected-note {{}}
_ = UnsafePointer<Int>(umpv) // expected-error {{'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.}}
_ = UnsafePointer<Int>(upv) // expected-error {{'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.}}
_ = UnsafePointer<Int>(umpi)
_ = UnsafePointer<Int>(upi)
_ = UnsafePointer<Int>(umps) // expected-error {{'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.}}
_ = UnsafePointer<Int>(ups) // expected-error {{'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type.}}
}
4 changes: 2 additions & 2 deletions test/Sema/diag_init.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: %target-parse-verify-swift

func foo(a : UnsafePointer<Void>)->UnsafeMutablePointer<Void> {
return UnsafeMutablePointer(a) // expected-error {{cannot invoke initializer for type 'UnsafeMutablePointer<_>' with an argument list of type '(UnsafePointer<Void>)'}} // expected-note {{do you want to add 'mutating'}}{{31-31=mutating: }} // expected-note {{overloads for 'UnsafeMutablePointer<_>' exist with these partially matching parameter lists: (RawPointer), (OpaquePointer), (OpaquePointer?), (UnsafeMutablePointer<Pointee>), (UnsafeMutablePointer<Pointee>?)}}
}
return UnsafeMutablePointer(a) // expected-error {{'init' has been renamed to 'init(mutating:)'}}
}