Files
swift-mirror/test/stdlib/ImplicitlyUnwrappedOptional.swift
Mark Lacey dc8c88058f Fix an issue with the constraint favoring code in the constraint optimizer.
The code was favoring overloads where *either* argument matched its
parameter type and where both parameter types were the same. This
is really overly broad and can result in bugs like the one here, where
we only attempt the
  (Int, Int) -> Bool
overload of '!=' despite the fact that it means forcing an
optional. We should select the
  <T>(T?, T?) -> Bool
overload instead, and inject the non-optional operand into an optional.

Making this require *both* arguments to match mostly disables this
optimization, though, since for somethin like "a"+"b"+"c" the second
add has a type variable and string literal as arugments.

So instead, we'll just disable this in cases where one argument is the
optional of the other, to ensure we never try forcing one side. This
also means we'll disable the optimization in cases where we would
inject one operand into an optional, but that's likely find as we
don't have long chains of expressions where that happens.

Fixes rdar://problem/37073401.
2018-02-13 10:24:30 -08:00

75 lines
1.8 KiB
Swift

// RUN: %target-run-simple-swift | %FileCheck %s
// REQUIRES: executable_test
var x : Int! = .none
if x != nil {
print("x is non-empty!")
} else {
print("an empty optional is logically false")
}
// CHECK: an empty optional is logically false
x = .some(0)
if x != nil {
print("a non-empty optional is logically true")
} else {
print("x is empty!")
}
// CHECK: a non-empty optional is logically true
class C {}
var c : C! = C()
if c === nil {
print("x is nil!")
} else {
print("a non-empty class optional should not equal nil")
}
// CHECK: a non-empty class optional should not equal nil
c = nil
if c === nil {
print("an empty class optional should equal nil")
} else {
print("x is not nil!")
}
// CHECK: an empty class optional should equal nil
import StdlibUnittest
import Swift
var ImplicitlyUnwrappedOptionalTests = TestSuite("ImplicitlyUnwrappedOptional")
ImplicitlyUnwrappedOptionalTests.test("flatMap") {
// FIXME(19798684): can't call map or flatMap on ImplicitlyUnwrappedOptional
// let half: Int32 -> Int16! =
// { if $0 % 2 == 0 { return Int16($0 / 2) } else { return .none } }
// expectOptionalEqual(2 as Int16, half(4))
// expectNil(half(3))
// expectNil((.none as Int!).flatMap(half))
// expectOptionalEqual(2 as Int16, (4 as Int!).flatMap(half))
// expectNil((3 as Int!).flatMap(half))
}
infix operator *^* : ComparisonPrecedence
func *^*(lhs: Int?, rhs: Int?) -> Bool { return true }
func *^*(lhs: Int, rhs: Int) -> Bool { return true }
ImplicitlyUnwrappedOptionalTests.test("preferOptional") {
let i: Int! = nil
let j: Int = 1
if i != j {} // we should choose != for Optionals rather than forcing i
if i == j {} // we should choose == for Optionals rather than forcing i
// FIXME: https://bugs.swift.org/browse/SR-6988
// if i *^* j {} // we should choose *^* for Optionals rather than forcing i
}
runAllTests()