# All paths through this function will call itself

**URL:** <https://forums.swift.org/t/all-paths-through-this-function-will-call-itself/31068>\
**Category:** Using Swift\
**Tags:** compiler-warning\
**Created:** [November 23, 2019, 12:04pm UTC](https://forums.swift.org/t/all-paths-through-this-function-will-call-itself/31068 "2019-11-23T12:04:15Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![neil.nothing](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/neil.nothing/32/23577_2.png) [@neil.nothing](https://forums.swift.org/u/neil.nothing)\
**Post date:** [November 23, 2019, 12:04pm UTC](https://forums.swift.org/t/all-paths-through-this-function-will-call-itself/31068/1 "2019-11-23T12:04:15Z")

</div>

I started to support the new dark mode to an app. So I used to create UIColor extension.

```swift
import UIKit

extension UIColor {
    static var groupedBackground: UIColor {
         if #available(iOS 13, *) {
             return UIColor.systemGroupedBackground
         } else {
             return UIColor.groupedBackground
         }
    }
}

```

You may notice that I have a typo here that I am calling the same variable for iOS versions other than 13. Which will result in crash for less iOS 13 devices.

While swift compiler warns if I write like below.

```swift
extension UIColor {
    static var groupedBackground: UIColor {
         return UIColor.groupedBackground
    }
}

```

The Swift Compiler warning here is `All paths through this function will call itself`.

So why I am not getting the same warning for the conditional code above?

---

<div class="post-metadata">

**Author:** ![michelf](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/michelf/32/1180_2.png) [@michelf](https://forums.swift.org/u/michelf)\
**Post date:** [November 23, 2019, 12:51pm UTC](https://forums.swift.org/t/all-paths-through-this-function-will-call-itself/31068/2 "2019-11-23T12:51:11Z")

</div>

Probably because there's a path where the function does not call itself: the path where `#available` returns `true`. It'd nevertheless be useful to have a warning that says: "All paths through this function will call itself on iOS \<13". That's more complicated to detect: paths would need to be checked for all the platform version ranges the function can have. Seems doable though.

---

<div class="post-metadata">

**Author:** ![cukr](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/cukr/32/889_2.png) [@cukr](https://forums.swift.org/u/cukr)\
**Post date:** [November 23, 2019, 12:59pm UTC](https://forums.swift.org/t/all-paths-through-this-function-will-call-itself/31068/3 "2019-11-23T12:59:09Z")

</div>

tl;dr because nobody taught the compiler that you cannot update iOS while the app is running

There are two kinds of checks in swift, compile time and runtime.

Let's look at the compile time checks:

```swift
extension UIColor {
    static var groupedBackground: UIColor {
         #if FOO
             return UIColor.systemGroupedBackground
         #else
             return UIColor.groupedBackground
         #endif
    }
}

```

If FOO is false, then the second path will be hardcoded into the binary, and the first choice will be deleted, as if it never existed, and the compiler will warn you.

The other kind of checks is made at runtime, and compiler cannot guarantee that the condition won't change

```swift
extension UIColor {
    static var groupedBackground: UIColor {
         if foo {
            return UIColor.systemGroupedBackground
         } else {
            return UIColor.groupedBackground
         }
    }
}

```

System version checks must be done at runtime, because you can run the same binary on different operating system versions, or even update your linux machine without rebooting it.

I can imagine `#available` being made a special case in a compiler though, because it would be very weird for the OS version to change in the middle of running the app

---

<div class="post-metadata">

**Author:** ![beccadax](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/beccadax/32/34217_2.png) [@beccadax](https://forums.swift.org/u/beccadax)\
**Post date:** [November 23, 2019, 8:20pm UTC](https://forums.swift.org/t/all-paths-through-this-function-will-call-itself/31068/4 "2019-11-23T20:20:42Z")

</div>

cukr’s analysis sounds correct—the DiagnoseInfiniteRecursion pass doesn’t understand that `#available(iOS 13, *)` is effectively constant, and in fact I don’t think it understands at all that a branch on a constant will always go the same way.

Neil, this would make an excellent bug report.

---

<div class="post-metadata">

**Author:** ![neil.nothing](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/neil.nothing/32/23577_2.png) [@neil.nothing](https://forums.swift.org/u/neil.nothing)\
**Post date:** [November 24, 2019, 2:47pm UTC](https://forums.swift.org/t/all-paths-through-this-function-will-call-itself/31068/5 "2019-11-24T14:47:23Z")

</div>

Thanks @beccadax for reply. I have create the bug report here: [SR-11842](https://bugs.swift.org/browse/SR-11842)

---

<div class="post-metadata">

**Author:** ![beccadax](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/beccadax/32/34217_2.png) [@beccadax](https://forums.swift.org/u/beccadax)\
**Post date:** [November 24, 2019, 7:07pm UTC](https://forums.swift.org/t/all-paths-through-this-function-will-call-itself/31068/6 "2019-11-24T19:07:50Z")

</div>

That report looks great—thank you!
