SLN SLN - 2 months ago 5x
Swift Question

A guess for a mechanism behind Type Inference

I've tried this code in the xCode:

let bigNum = Int8.max + Int("1")!
The compiler infers the variable bigNum of type
and give me a overflow error.

Int8.max + Int("1")!
: the left side of "+" has the type of
the right side has the type of
. Why the compiler did not infer the bigNum as type of

Guess: Swift's compiler always infer the tye by the more narrow/restricted value types, because
is a more small and narrow type compare to the
, therefore adding an
and an
number would lead to an
type inference.

Question: Am I right? or mostly right but not precise. If so, please correct me.



The type inference engine doesn't know the bit-width of the Ints. It doesn't even know that Ints are numbers. The engine doesn't know anything about the "restrictedness" or "narrowness" of how types are implemented. It just knows how types relate to each other as supertypes and subtypes ("ISA" relationships), and tries to solve constraint problems by figuring out what it can plug into the type variables you've provided.

The type inference engine instead is basing its choice on the version of + that is selected. None of the Int-based + functions apply. They're all of the form:

public func +(lhs: Int8, rhs: Int8) -> Int8

And this doesn't have an Int8 on both sides. So it picks the next most specific one it can find:

public func +<T : Strideable>(lhs: T, rhs: T.Stride) -> T

Why this one? An Int8 is a SignedInteger. SignedInteger implements Strideable this way:

public protocol Strideable : Comparable {
    associatedtype Stride : SignedNumber
    public func distance(to other: Self) -> Self.Stride
    public func advanced(by n: Self.Stride) -> Self

extension SignedInteger {
    public func distance(to other: Self) -> Int
    public func advanced(by n: Int) -> Self

By type-inference we see that Stride is Int. So our function is:

public func +(lhs: Int8, rhs: Int) -> Int8

And that of course overflows at runtime.

BTW, the best way to figure out what function Swift has chosen is to Option-Click the + symbol. It'll tell you what types it's using.