Files
swift-mirror/test/Constraints/unchecked_optional.swift
Mark Lacey f08823757a IUO: Generate Optional<T> rather than ImplicitlyUnwrappedOptional<T>.
Stop creating ImplicitlyUnwrappedOptional<T> so that we can remove it
from the type system.

Enable the code that generates disjunctions for Optional<T> and
rewrites expressions based on the original declared type being 'T!'.

Most of the changes supporting this were previously merged to master,
but some things were difficult to merge to master without actually
removing IUOs from the type system:
- Dynamic member lookup and dynamic subscripting
- Changes to ensure the bridging peephole still works

Past commits have attempted to retain as much fidelity with how we
were printing things as possible. There are some cases where we still
are not printing things the same way:
- In diagnostics we will print '?' rather than '!'
- Some SourceKit and Code Completion output where we print a Type
  rather than Decl.

Things like module printing via swift-ide-test attempt to print '!'
any place that we now have Optional types that were declared as IUOs.

There are some diagnostics regressions related to the fact that we can
no longer "look through" IUOs. For the same reason some output and
functionality changes in Code Completion. I have an idea of how we can
restore these, and have opened a bug to investigate doing so.

There are some small source compatibility breaks that result from
this change:
- Results of dynamic lookup that are themselves declared IUO can in
  rare circumstances be inferred differently. This shows up in
  test/ClangImporter/objc_parse.swift, where we have
    var optStr = obj.nsstringProperty
  Rather than inferring optStr to be 'String!?', we now infer this to
  be 'String??', which is in line with the expectations of SE-0054.
  The fact that we were only inferring the outermost IUO to be an
  Optional in Swift 4 was a result of the incomplete implementation of
  SE-0054 as opposed to a particular design. This should rarely cause
  problems since in the common-case of actually using the property rather
  than just assigning it to a value with inferred type, we will behave
  the same way.
- Overloading functions with inout parameters strictly by a difference
  in optionality (i.e. Optional<T> vs. ImplicitlyUnwrappedOptional<T>)
  will result in an error rather than the diagnostic that was added
  in Swift 4.1.
- Any place where '!' was being used where it wasn't supposed to be
  allowed by SE-0054 will now treat the '!' as if it were '?'.
  Swift 4.1 generates warnings for these saying that putting '!'
  in that location is deprecated. These locations include for example
  typealiases or any place where '!' is nested in another type like
  `Int!?` or `[Int!]`.

This commit effectively means ImplicitlyUnwrappedOptional<T> is no
longer part of the type system, although I haven't actually removed
all of the code dealing with it yet.

ImplicitlyUnwrappedOptional<T> is is dead, long live implicitly
unwrapped Optional<T>!

Resolves rdar://problem/33272674.
2018-01-31 12:15:58 -08:00

93 lines
1.5 KiB
Swift

// RUN: %target-typecheck-verify-swift
class A {
func do_a() {}
func do_b(_ x: Int) {}
func do_b(_ x: Float) {}
func do_c(x: Int) {}
func do_c(y: Int) {}
}
func test0(_ a : A!) {
a.do_a()
a.do_b(1)
a.do_b(5.0)
a.do_c(1) // expected-error {{cannot invoke 'do_c' with an argument list of type '(Int)'}}
a.do_c(x: 1)
}
func test1(_ a : A!) {
a?.do_a()
a?.do_b(1)
a?.do_b(5.0)
a?.do_c(1) // expected-error {{cannot invoke 'do_c' with an argument list of type '(Int)'}}
a?.do_c(x: 1)
}
struct B {
var x : Int
}
func test2(_ b : B!) {
var b: B! = b
let x = b.x
b.x = x
b = nil
}
struct Subscriptable {
subscript(x : Int) -> Int {
get {
return x
}
}
}
func test3(_ x: Subscriptable!) -> Int {
return x[0]
}
// Callable
func test4(_ f: ((Int) -> Float)!) -> Float {
return f(5)
}
func test5(_ value : Int!) {
let _ : Int? = value
}
func test6(_ value : Int!) {
let _ : Int? = value
}
class Test9a {}
class Test9b : Test9a {}
func test9_produceUnchecked() -> Test9b! { return Test9b() }
func test9_consume(_ foo : Test9b) {}
func test9() -> Test9a {
let foo = test9_produceUnchecked()!
test9_consume(foo)
let _ : Test9a = foo
return foo
}
func test10_helper(_ x : Int!) -> Int? { return x }
func test10(_ x : Int?) -> Int! { return test10_helper(x) }
// Fall back to object type behind an implicitly-unwrapped optional.
protocol P11 { }
extension Int : P11 { }
func test11_helper<T : P11>(_ t: T) { }
func test11(_ i: Int!, j: Int!) {
var j = j
test11_helper(i)
test11_helper(j!)
j = nil
}