I just updated to Xcode 14.3.
Until now, I could have code like this:
let myArray = [1, 2, 3]
if let element = myArray[3] {
print("yes")
} else {
print("no")
}
Now I'm getting the error:
error: initializer for conditional binding must have Optional type, not 'Int'.
Of course accessing myArray[3] will lead to a Fatal error: Index out of range.
Why were there changes and how can I get the old behaviour back?
There's nothing new about this. You're misremembering; probably thinking of how Dictionary works. There is no built-in subscript with index validation for Array, but there should be.
do {
try myArray[validating: 3]
print("yes")
} else {
print("no")
}
/// Thrown when `[validating:]` is called with an invalid index.
public struct IndexingError<Collection: Swift.Collection>: Error { }
public extension Collection {
typealias IndexingError = ModuleName.IndexingError<Self>
/// Ensure an index is valid before accessing an element of the collection.
/// - Returns: The same as the unlabeled subscript, if an error is not thrown.
/// - Throws: `IndexingError` if `indices` does not contain `index`.
subscript(validating index: Index) -> Element {
get throws {
guard indices.contains(index) else { throw IndexingError() }
return self[index]
}
}
}
I downloaded Xcode 14.2 to test. You're right, I remembered wrong. I found out, that the problem lies in SwiftUI.
It's really weird, I have SwiftUI-code what actually has this code. I simplified it and it is okay too:
struct TestView: View {
@Binding var myStrings: [String]
let index: Int
var body: some View {
Group {
if self.index < self.myStrings.count, let myString = self.myStrings[self.index] {
Text(myString)
}
}
}
}
I investigated a little more: If I remove Group, it stops compiling. 
In Swift 5.8, a major improvement has been made to the implementation of result builder. As a result, the compiler now throws errors for some error cases that were previously overlooked. I have the exact same behavior in my SwiftUI code.
If you really liked that code, though, the solution for all versions of Swift is to add case.
if index < myStrings.count, case let myString = myStrings[index] {
I would do
(try? myStrings[validating: index]).map(Text.init)
Thanks so much for this answer (and the question). I had a similar issue with my "if let var = blah" in my SwiftUI view when updating from Xcode 14.1 to 14.3. The case statement helped. Thanks