title: How do I safely cast a `_Nullable` to a `_Nonnull` in Objective-C?
body: <p>When compiling with <code>-Wnullable-to-nonnull-conversion</code>, we get a proper warning with the following code:</p>
  
  <pre><code>NSString * _Nullable maybeFoo = @"foo";
  ^(NSString * _Nonnull bar) {  
  }(maybeFoo);
  
  Tests.m:32:7: error: implicit conversion from nullable pointer 'NSString * _Nullable' to non-nullable pointer type 'NSString * _Nonnull' [-Werror,-Wnullable-to-nonnull-conversion]
      }(maybeFoo);
        ^
  1 error generated.
  </code></pre>
  
  <p>How do I safely cast <code>foo</code> from an <code>NSString * _Nullable</code> to an <code>NSString * _Nonnull</code>?</p>
  
  <p><strong>The best solution I have so far</strong></p>
  
  <p>The best I've come up with is this macro:</p>
  
  <pre><code>#define ForceUnwrap(type, nullableExpression) ^type _Nonnull () { \
    type _Nullable maybeValue___ = nullableExpression; \
    if (maybeValue___) { \
      return (type _Nonnull) maybeValue___; \
    } else { \
      NSLog(@"Attempted to force unwrap a null: " #nullableExpression); \
      abort(); \
    } \
  }()
  </code></pre>
  
  <p>Which is used like:</p>
  
  <pre><code>NSString * _Nullable maybeFoo = @"foo";
  if (maybeFoo) {
      NSString * _Nonnull foo = ForceUnwrap(NSString *, maybeFoo);
      ^(NSString * _Nonnull bar) {
      }(foo);
  }
  </code></pre>
  
  <p>And which produces an error if assigned to a wrongly-typed variable:</p>
  
  <pre><code>NSString * _Nullable maybeFoo = @"foo";
  if (maybeFoo) {
      NSNumber * _Nonnull foo = ForceUnwrap(NSString *, maybeFoo);
      ^(NSNumber * _Nonnull bar) {
      }(foo);
  }
  
  Tests.m:40:29: error: incompatible pointer types initializing 'NSNumber * _Nonnull' with an expression of type 'NSString * _Nonnull' [-Werror,-Wincompatible-pointer-types]
          NSNumber * _Nonnull foo = ForceUnwrap(NSString *, maybeFoo);
                              ^     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1 error generated.
  </code></pre>
  
  <p>And which produces an error if cast to the wrong type:</p>
  
  <pre><code>NSString * _Nullable maybeFoo = @"foo";
  if (maybeFoo) {
      NSNumber * _Nonnull foo = ForceUnwrap(NSNumber *, maybeFoo);
      ^(NSNumber * _Nonnull bar) {
      }(foo);
  }
  
  Tests.m:40:35: error: incompatible pointer types initializing 'NSNumber * _Nullable' with an expression of type 'NSString * _Nullable' [-Werror,-Wincompatible-pointer-types]
          NSNumber * _Nonnull foo = ForceUnwrap(NSNumber *, maybeFoo);
                                    ^                       ~~~~~~~~
  Tests.m:27:16: note: expanded from macro 'ForceUnwrap'
  type _Nullable maybeValue___ = nullableExpression; \
                 ^               ~~~~~~~~~~~~~~~~~~
  1 error generated.
  </code></pre>
  
  <p>Unfortunately, if you need to cast to a generic type with multiple arguments, you have to resort to <a href="https://stackoverflow.com/a/19841470/9636">preprocessor</a> <a href="https://stackoverflow.com/a/13842612/9636">hacks</a>:</p>
  
  <pre><code>NSDictionary&lt;NSString *, NSString *&gt; * _Nullable maybeFoo = 
  [NSDictionary&lt;NSString *, NSString *&gt; new];
  if (maybeFoo) {
    NSDictionary&lt;NSString *, NSString *&gt; * _Nonnull foo =
  #define COMMA ,
    ForceUnwrap(NSDictionary&lt;NSString * COMMMA NSString *&gt;, maybeFoo);
  #undef COMMA
    ^(NSDictionary&lt;NSString *, NSString *&gt; * _Nonnull bar) {
    }(foo);
  }
  </code></pre>
  
  <p><strong>Things I've tried that don't work</strong></p>
  
  <p>Assigning <code>maybeFoo</code> directly to an <code>NSString * _Nonnull</code> doesn't work. It produces the same error as before:</p>
  
  <pre><code>NSString * _Nullable maybeFoo = @"foo";
  if (maybeFoo) {
    NSString * _Nonnull foo = maybeFoo;
    ^(NSString * _Nonnull bar) {  
    }(foo);
  }
  
  Tests.m:30:35: error: implicit conversion from nullable pointer 'NSString * _Nullable' to non-nullable pointer type 'NSString * _Nonnull' [-Werror,-Wnullable-to-nonnull-conversion]
          NSString * _Nonnull foo = maybeFoo;
                                    ^
  1 error generated.
  </code></pre>
  
  <p>And casting to <code>maybeFoo</code> to <code>NSString * _Nonnull</code> isn't safe because if <code>maybeFoo</code>'s type changes, the compiler won't break:</p>
  
  <pre><code>NSNumber * _Nullable maybeFoo = @"foo";
  if (maybeFoo) {
    NSString * _Nonnull foo = (NSString * _Nonnull) maybeFoo;
    ^(NSString * _Nonnull bar) {  
    }(foo);
  }
  // no errors!
  </code></pre>
  
  <p>I also tried using <code>__typeof__</code>, when casting, but <code>__typeof__</code> carries the nullability specifier, so when you try to cast to <code>__typeof__(maybeFoo) _Nonnull</code> you get a nullability conflict:</p>
  
  <pre><code>NSString * _Nullable maybeFoo = @"foo";
  if (maybeFoo) {
      NSString * _Nonnull foo = (__typeof__(maybeFoo) _Nonnull) maybeFoo;
      ^(NSString * _Nonnull bar) {
      }(foo);
  }
  
  Tests.m:30:57: error: nullability specifier '_Nonnull' conflicts with existing specifier '_Nullable'
          NSString * _Nonnull foo = (__typeof__(maybeFoo) _Nonnull) maybeFoo;
                                                          ^
  Tests.m:30:35: error: implicit conversion from nullable pointer 'NSString * _Nullable' to non-nullable pointer type 'NSString * _Nonnull' [-Werror,-Wnullable-to-nonnull-conversion]
          NSString * _Nonnull foo = (__typeof__(maybeFoo) _Nonnull) maybeFoo;
                                    ^
  2 errors generated.
  </code></pre>
  
  <p>Everything was run with the deep static analyzer and compiled with <code>Xcode 8.2.1</code> with the following flags:</p>
  
  <pre><code>-Wnon-modular-include-in-framework-module 
  -Werror=non-modular-include-in-framework-module
  -Wno-trigraphs
  -Werror
  -Wno-missing-field-initializers
  -Wno-missing-prototypes
  -Wunreachable-code
  -Wno-implicit-atomic-properties
  -Wno-arc-repeated-use-of-weak
  -Wduplicate-method-match
  -Wno-missing-braces
  -Wparentheses
  -Wswitch
  -Wunused-function
  -Wno-unused-label
  -Wno-unused-parameter
  -Wunused-variable
  -Wunused-value
  -Wempty-body
  -Wuninitialized
  -Wno-unknown-pragmas
  -Wno-shadow
  -Wno-four-char-constants
  -Wno-conversion
  -Wconstant-conversion
  -Wint-conversion
  -Wbool-conversion
  -Wenum-conversion
  -Wshorten-64-to-32
  -Wpointer-sign
  -Wno-newline-eof
  -Wno-selector
  -Wno-strict-selector-match
  -Wundeclared-selector
  -Wno-deprecated-implementations
  -Wno-sign-conversion
  -Wno-infinite-recursion
  -Weverything
  -Wno-auto-import
  -Wno-objc-missing-property-synthesis
  -Wno-cstring-format-directive
  -Wno-direct-ivar-access
  -Wno-double-promotion
  </code></pre>