# How does Swift prevent SwiftUI \`body: Never\` properties from being called?

**URL:** <https://forums.swift.org/t/how-does-swift-prevent-swiftui-body-never-properties-from-being-called/59253>\
**Category:** Using Swift\
**Created:** [July 27, 2022, 2:11pm UTC](https://forums.swift.org/t/how-does-swift-prevent-swiftui-body-never-properties-from-being-called/59253 "2022-07-27T14:11:24Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![stephencelis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/stephencelis/32/2675_2.png) [@stephencelis](https://forums.swift.org/u/stephencelis)\
**Post date:** [July 27, 2022, 2:11pm UTC](https://forums.swift.org/t/how-does-swift-prevent-swiftui-body-never-properties-from-being-called/59253/1 "2022-07-27T14:11:24Z")

</div>

It's been asked a couple times before ([1](https://forums.swift.org/t/swiftui-why-cant-call-text-image-struct-body-property/26182), [2](https://forums.swift.org/t/how-do-some-swiftui-views-hide-their-body-property-at-compile-time/38658)) without an answer, so does anyone know what prevents the following from compiling?

```swift
Text("Hello").body // 🛑 

```

> 🛑 Value of type 'Text' has no member 'body'

`Text` (and many other SwiftUI views) have `Body = Never`, and while it makes sense that invoking `.body` isn't useful, it's not clear what compiler affordance is preventing it.

The closest I've found to an explanation is @mayoff's post that finds the underscored `_UnaryView` protocol: [ios - How do view types like Text or Image conform to the View protocol in SwiftUI? - Stack Overflow](https://stackoverflow.com/questions/56470614/how-do-view-types-like-text-or-image-conform-to-the-view-protocol-in-swiftui/61166327#61166327)

I haven't been able to reproduce the behavior myself, though, by employing an underscored protocol, so is it something else? Is there special compiler logic involved? An underscored attribute that I'm overlooking in the Swift interface?

---

<div class="post-metadata">

**Author:** ![Avi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/avi/32/2962_2.png) [@Avi](https://forums.swift.org/u/Avi)\
**Post date:** [July 27, 2022, 2:15pm UTC](https://forums.swift.org/t/how-does-swift-prevent-swiftui-body-never-properties-from-being-called/59253/2 "2022-07-27T14:15:00Z")

</div>

Isn't simpler than that? `Text("Hi there").body` is requesting that a value be materialized, and that's simply not possible for `Never` types, by definition.

---

<div class="post-metadata">

**Author:** ![stephencelis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/stephencelis/32/2675_2.png) [@stephencelis](https://forums.swift.org/u/stephencelis)\
**Post date:** [July 27, 2022, 2:17pm UTC](https://forums.swift.org/t/how-does-swift-prevent-swiftui-body-never-properties-from-being-called/59253/3 "2022-07-27T14:17:05Z")

</div>

> [@Avi](#):
>
> Isn't simpler than that? `Text("Hi there").body` is requesting that a value be materialized, and that's simply not possible for `Never` types, by definition.

Unfortunately not. The following as noted in one of the previous threads compiles just fine:

```swift
struct MyView: View {
  var body: Never { fatalError() }
}

MyView().body // ✅ Compiles fine.

```

It just fatal-errors at runtime.

So there does appear to be specific compiler "magic" at work here.

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [July 27, 2022, 2:51pm UTC](https://forums.swift.org/t/how-does-swift-prevent-swiftui-body-never-properties-from-being-called/59253/4 "2022-07-27T14:51:05Z")

</div>

SwiftUI doesn't call the `body` of views directly, it invokes a hidden requirement of the `View` protocol. The default implementation of that requirement, which all user-defined views call, is defined in terms of `body`. Primitive views provided by the framework have implementations that don't use the `body`. No compiler magic necessary.

---

<div class="post-metadata">

**Author:** ![mayoff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mayoff/32/613_2.png) [@mayoff](https://forums.swift.org/u/mayoff)\
**Post date:** [July 27, 2022, 2:57pm UTC](https://forums.swift.org/t/how-does-swift-prevent-swiftui-body-never-properties-from-being-called/59253/5 "2022-07-27T14:57:44Z")

</div>

> [@Joe\_Groff](#):
>
> No compiler magic necessary.

Some magic is necessary to make the compiler issue the `value of type 'Text' has no member 'body'` error.

A `Text` value has a `body` property, as all `View`s do. `Text`'s `body` calls `fatalError`:

```swift
import SwiftUI

func body<V: View>(of view: V) -> V.Body { view.body }

body(of: Text("hello"))

// runtime output:

SwiftUI/View.swift:94: Fatal error: body() should not be called on Text.

```

However, if we attempt to access the `body` property directly, the compiler rejects the program:

```swift
import SwiftUI

Text("hello").body

```

Output:

 ![image](https://global.discourse-cdn.com/swift/original/3X/8/d/8d6c3fe79af1b47db39e9c2995b5211f18c59de5.png)

In fact, SwiftUI's `swiftinterface` file doesn't declare a `body` property for `Text`. Perhaps there is no compiler magic, and instead the SwiftUI framework simply has a (magic) build step that strips it from the `swiftinterface` file.

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [July 27, 2022, 3:56pm UTC](https://forums.swift.org/t/how-does-swift-prevent-swiftui-body-never-properties-from-being-called/59253/6 "2022-07-27T15:56:23Z")

</div>

> [@mayoff](#):
>
> In fact, SwiftUI's `swiftinterface` file doesn't declare a `body` property for `Text`. Perhaps there is no compiler magic, and instead the SwiftUI framework simply has a (magic) build step that strips it from the `swiftinterface` file.

Great detective work! And I like your "body(of: Text("hello"))" (so we can still call it even if it is "hidden").

I totally understand the desire to know the relevant ins and outs of how compiler doing this. That aside, I'm curious why would anyone want to call View's body directly?

---

<div class="post-metadata">

**Author:** ![stephencelis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/stephencelis/32/2675_2.png) [@stephencelis](https://forums.swift.org/u/stephencelis)\
**Post date:** [July 27, 2022, 4:02pm UTC](https://forums.swift.org/t/how-does-swift-prevent-swiftui-body-never-properties-from-being-called/59253/7 "2022-07-27T16:02:07Z")

</div>

> [@tera](#):
>
> I totally understand the desire to know the relevant ins and outs of how compiler doing this. That aside, I'm curious why would anyone want to call View's body directly?

While I'm sure there are folks who can come up with some interesting use cases, I'm more interested from a library design perspective. Principles of SwiftUI's design can be applied to a lot of other problem domains where you compose types together using result builders, and the `Body = Never` pattern is a nice way to express primitives that aren't directly composed out of other units. I was curious if the compiler magic that prevented the concrete `body` properties from being invoked was more broadly available, but if @mayoff's right about the Swift interface itself being stripped, I guess that's not the case 😄

---

<div class="post-metadata">

**Author:** ![mlienert](https://avatars.discourse-cdn.com/v4/letter/m/e99b99/32.png) [@mlienert](https://forums.swift.org/u/mlienert)\
**Post date:** [July 27, 2022, 4:53pm UTC](https://forums.swift.org/t/how-does-swift-prevent-swiftui-body-never-properties-from-being-called/59253/8 "2022-07-27T16:53:32Z")

</div>

Maybe out of topic but I am curious: How do you hide a protocol requirement (outside of the module I suppose ?) ?

---

<div class="post-metadata">

**Author:** ![Nickolas\_Pohilets](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nickolas_pohilets/32/10659_2.png) [@Nickolas\_Pohilets](https://forums.swift.org/u/Nickolas_Pohilets)\
**Post date:** [July 27, 2022, 4:58pm UTC](https://forums.swift.org/t/how-does-swift-prevent-swiftui-body-never-properties-from-being-called/59253/9 "2022-07-27T16:58:58Z")

</div>

It's just a convention - Xcode hides methods with leading underscore from the interface, but actually they are public methods in the protocol and you can implement them yourself, but to provide a meaningful implementation you need access to private types.

See [How does SwiftUI hides private protocol requirements of SwiftUI.View protocol](https://forums.swift.org/t/how-does-swiftui-hides-private-protocol-requirements-of-swiftui-view-protocol/44183)

---

<div class="post-metadata">

**Author:** ![mayoff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mayoff/32/613_2.png) [@mayoff](https://forums.swift.org/u/mayoff)\
**Post date:** [July 27, 2022, 6:01pm UTC](https://forums.swift.org/t/how-does-swift-prevent-swiftui-body-never-properties-from-being-called/59253/10 "2022-07-27T18:01:53Z")

</div>

By default, Swift tooling hides any identifier that starts with an underscore and is declared in a `swiftinterface` file. The compiler only generates a `swiftinterface` file for a module built with library evolution enabled, so this doesn't normally apply to your own modules, only to system modules and third-party binary modules.

From the [Underscored Attributes Reference](https://github.com/apple/swift/blob/main/docs/ReferenceGuides/UnderscoredAttributes.md#_show_in_interface):

> ## `@_show_in_interface`
> 
> Shows underscored protocols from the standard library in the generated interface.
> 
> By default, SourceKit hides underscored protocols from the generated swiftinterface (for all modules, not just the standard library), but this attribute can be used to override that behavior for the standard library.

---

<div class="post-metadata">

**Author:** ![harlanhaskins](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/harlanhaskins/32/333_2.png) [@harlanhaskins](https://forums.swift.org/u/harlanhaskins)\
**Post date:** [July 27, 2022, 7:47pm UTC](https://forums.swift.org/t/how-does-swift-prevent-swiftui-body-never-properties-from-being-called/59253/11 "2022-07-27T19:47:48Z")

</div>

Worth pointing out that there's a difference between "the generated interface", which is what Xcode shows when you command-click a module and displays all the declarations in a module, and the `swiftinterface` file, which is a stable textual format that fully specifies the ABI of a module, and while it more-or-less human readable, full human readability is not required for this format the way that it is for the "generated interface"

---

<div class="post-metadata">

**Author:** ![mayoff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mayoff/32/613_2.png) [@mayoff](https://forums.swift.org/u/mayoff)\
**Post date:** [August 10, 2022, 7:44am UTC](https://forums.swift.org/t/how-does-swift-prevent-swiftui-body-never-properties-from-being-called/59253/12 "2022-08-10T07:44:49Z")

</div>

We can use `@_spi` to omit a declaration from a `.swiftinterface` file. No magic build step needed.

I put the following into `MyView.swift`:

```swift
import SwiftUI

public struct MyView: View {
    @_spi(Private)
    public var body: Never { fatalError() }
}

```

Then I compiled it as follows, based on the “Directly invoking the compiler” instructions found [here](https://www.swift.org/blog/library-evolution/):

```swift
swiftc MyView.swift -module-name MyLib -emit-module -emit-library -emit-module-interface -enable-library-evolution

```

The compiler writes `MyLib.swiftinterface` as follows, **omitting the `body` declaration** :

```swift
// swift-interface-format-version: 1.0
// swift-compiler-version: Apple Swift version 5.7 (swiftlang-5.7.0.123.7 clang-1400.0.29.50)
// swift-module-flags: -target arm64-apple-macosx12.0 -enable-objc-interop -enable-library-evolution -module-name MyLib
import Swift
import SwiftUI
import _Concurrency
import _StringProcessing
public struct MyView : SwiftUI.View {
  public typealias Body = Swift.Never
}

```

And it writes `MyLib.private.swiftinterface` as follows, containing the `body` declaration:

```swift
// swift-interface-format-version: 1.0
// swift-compiler-version: Apple Swift version 5.7 (swiftlang-5.7.0.123.7 clang-1400.0.29.50)
// swift-module-flags: -target arm64-apple-macosx12.0 -enable-objc-interop -enable-library-evolution -module-name MyLib
import Swift
import SwiftUI
import _Concurrency
import _StringProcessing
public struct MyView : SwiftUI.View {
  @_spi(Private) @_Concurrency.MainActor(unsafe) public var body: Swift.Never {
    get
  }
  public typealias Body = Swift.Never
}

```

---

<div class="post-metadata">

**Author:** ![moyerr](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/moyerr/32/13602_2.png) [@moyerr](https://forums.swift.org/u/moyerr)\
**Post date:** [September 9, 2022, 8:28pm UTC](https://forums.swift.org/t/how-does-swift-prevent-swiftui-body-never-properties-from-being-called/59253/13 "2022-09-09T20:28:02Z")

</div>

@mayoff Thank you for sharing this insight! It makes me wonder why the library doesn't hide more implementation details this way, such as `Never`'s body, the various public-but-underscored requirements for `View`, `ViewModifier`, etc.

---

<div class="post-metadata">

**Author:** ![curt](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/curt/32/1961_2.png) [@curt](https://forums.swift.org/u/curt)\
**Post date:** [September 10, 2022, 3:29am UTC](https://forums.swift.org/t/how-does-swift-prevent-swiftui-body-never-properties-from-being-called/59253/14 "2022-09-10T03:29:34Z")

</div>

The `@_spi` attribute was introduced a couple of years after SwiftUI. Most underscored members and types pre-date the attribute, though there are still some cases where `@_spi` isn’t general enough and underscored members are still used.
