blob: 1246326270b3f5092572077a727d92fa15b6c268 [file] [log] [blame]
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -c -swift-version 4 -primary-file %s -emit-migrated-file-path %t/optional_try_migration.result.swift
// RUN: diff -u %S/optional_try_migration.swift.expected %t/optional_try_migration.result.swift
func fetchOptInt() throws -> Int? {
return 3
}
func fetchInt() throws -> Int {
return 3
}
func fetchAny() throws -> Any {
return 3
}
func testOnlyMigrateChangedBehavior() {
// No migration needed
let _ = try? fetchInt()
// Migration needed
let _ = ((try? fetchOptInt()) as Int??)
}
func testExplicitCasts() {
// No migration needed, because there's an explicit cast on the try already
let _ = (try? fetchOptInt()) as? Int
// Migration needed; the 'as? Int' is part of the sub-expression
let _ = ((try? fetchAny() as? Int) as Int??)
// No migration needed; the subexpression is non-optional so behavior has not changed
let _ = (try? fetchAny()) as? Int
// No migration needed, because there's an explicit cast on the try already
let _ = (try? fetchOptInt()) as! Int // expected-warning {{forced cast from 'Int??' to 'Int' only unwraps optionals; did you mean to use '!!'?}}
// No migration needed; the subexpression is non-optional
let _ = try? fetchAny() as! Int
// No migration needed; the subexpression is non-optional so behavior has not changed
let _ = (try? fetchAny()) as! Int
// Migration needed; the explicit cast is not directly on the try?
let _ = String(describing: ((try? fetchOptInt()) as Int??)) as Any
// No migration needed, because the try's subexpression is non-optional
let _ = String(describing: try? fetchInt()) as Any
}
func testOptionalChaining() {
struct Thing {
func fetchInt() throws -> Int { return 3 }
func fetchOptInt() throws -> Int { return 3 }
}
let thing = Thing()
let optThing: Thing? = Thing()
// Migration needed
let _ = ((try? optThing?.fetchInt()) as Int??)
// Migration needed
let _ = ((try? optThing?.fetchOptInt()) as Int??)
// No migration needed
let _ = try? optThing!.fetchOptInt()
// No migration needed, because of the explicit cast
let _ = (try? optThing?.fetchOptInt()) as? Int
// Migration needed
let _ = try? thing.fetchInt()
// Migration needed
let _ = try? thing.fetchOptInt()
// No migration needed, because of the explicit cast
let _ = (try? thing.fetchOptInt()) as! Int // expected-warning {{forced cast from 'Int?' to 'Int' only unwraps optionals; did you mean to use '!'?}}
}
func testIfLet() {
// Migration needed
if let optionalX = ((try? fetchOptInt()) as Int??),
let x = optionalX
{
print(x)
}
// Don't change 'try?'s that haven't changed behavior
if let x = try? fetchInt(),
let y = try? fetchInt() {
print(x, y)
}
}
func testCaseMatching() {
// Migration needed
if case let x?? = ((try? fetchOptInt()) as Int??) {
print(x)
}
// No migration needed
if case let x? = try? fetchInt() {
print(x)
}
}