What's this _value property?

(Jens Persson) #1

I first noticed this in the REPL:

$ swift
Welcome to Apple Swift version 4.2 (swiftlang-1000.0.36 clang-1000.0.4). Type :help for assistance.

  1> let a = 123
a: Int = 123

  2> let b = (123)     // Note how, just because I wrapped 123 in parens,
b: (Int) = {           // the type of `b` is shown as a single element
  _value = 123         // tuple (even though there's supposedly no such thing),
}                      // it's (unlabeled) single element labeled "_value". 

  3> b._value          // And I can access this element/property of b. 
$R0: Int64 = 123

  4> b._value + b._value // But it seems to be a special kind of Int64 ...
error: repl.swift:4:10: error: binary operator '+' cannot be applied to two 'Int64' operands
b._value + b._value
~~~~~~~~ ^ ~~~~~~~~

repl.swift:4:10: note: overloads for '+' exist with these partially matching parameter lists: (Float, Float), (Double, Double), (Float80, Float80), (UInt8, UInt8), (Int8, Int8), (UInt16, UInt16), (Int16, Int16), (UInt32, UInt32), (Int32, Int32), (UInt64, UInt64), (Int64, Int64), (UInt, UInt), (Int, Int), (String, String), (Self, Self.Stride), (Self.Stride, Self), (Self, Other), (Other, Self)
b._value + b._value

  4> a._value     // Turns out that this _value-thing is present even for
$R1: Int64 = 123  // eg regular Ints, like a that we defined without parents above.

This is Xcode 10.0 beta 6 (10L232m), default toolchain.

It's not specific to the REPL, for example the following (cmd line) program compiles and runs, and shows some other mysterious properties of this _value thing:

let a: UInt8 = 255
print(type(of: a._value)) // Prints "Builtin.Int8", why not "Builtin.UInt8"?
print(a._value) // (Opaque Value)

let b: Float80 = 1.23
print(type(of: b._value)) // Prints "Builtin.Int128".
print(b._value) // (Opaque Value)

The REPL is a bit more explicit about the above:

$ swift
Welcome to Apple Swift version 4.2 (swiftlang-1000.0.36 clang-1000.0.4). Type :help for assistance.
  1> let a: UInt8 = 255
a: UInt8 = 255
  2> type(of: a._value)
$R0: Int8.Type = Builtin.Int8
  3> a._value
$R1: Int8 = -1
  4> let b: Float80 = 1.23
b: Float80 = 1.23000000000000000002
  5> type(of: b._value)
$R2: FPIEEE80.Type = Builtin.FPIEEE80
  6> b._value
$R3: FPIEEE80 = 1.23000000000000000002

I guess that _value is supposed to be internal to the compiler implementation, but it would be interesting to know more about it.

(Mark Lacey) #2

What you're looking at is this.

It's just the declaration of the storage within the type.

(Zach Wolfe) #3

The Builtin.IntX refer to LLVM types, of which there are no unsigned equivalents. The instructions performed on those values define their semantics (signed or unsigned, or apparently 80-bit floating point).

(Jens Persson) #4

Thank you both. I guess it isn't supposed to manifest itself in user code (and on top of that, in the form of a labeled element of a supposedly nonexisting unlabeled single element tuple) though?

(John McCall) #5

Yeah, it's not supposed to manifest in user code; these things are supposed to be rendered at a higher level.

(Jens Persson) #6