There are two ?? operators:
public func ??<T>(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T
public func ??<T>(optional: T?, defaultValue: @autoclosure () throws -> T?) rethrows -> T?
If we simplify the declarations by ignoring that the second parameter is
a possibly throwing autoclosure, we get
public func ??<T>(optional: T?, defaultValue: T) -> T // (1)
public func ??<T>(optional: T?, defaultValue: T?) -> T? // (2)
In nickName ?? fullName, the first argument is an optional
and the second a non-optional, which means that the first variant is
used, and the result is a non-optional:
nickName ?? fullName // (String? ?? String) -> String
If nickName != nil then the result is the unwrapped (!) nickName,
otherwise fullName.
In fullName ?? nickName, the first argument is a non-optional
and the second one an optional. This does not match any those
function declarations.
What the compiler does is to "wrap" the first argument into an
optional in order to make it compile (using the second variant).
The result is an optional:
fullName ?? nickName // (String? ?? String?) -> String?
The result will always be Optional(fullName).
In a compiled project you will also get the warning
warning: left side of nil coalescing operator '??' has non-optional type 'String', so the right side is never used
The second variant is usually used when chaining nil-coalescing operators:
let result = optA ?? optB ?? optC ?? nonOptD
(2) (2) (1)