AST – Understanding @lvalue


(Tim Bodeit) #1

I couldn’t find any documentation about lvalues in Swift. Can anybody give me a short explanation of what exactly an lvalue is?

In C++ all variables, including those marked with the const modifier seem to be lvalues. It seems to me, that this is not the case for let constants in Swift.

I compared the output of swiftc -dump-ast for
let i = 42
let j = i+1
and
var i = 42
let j = i+1

Where i was respectively accessed as:

(declref_expr type='Int' location=lvaluetest.swift:2:9 range=[lvaluetest.swift:2:9 - line:2:9] decl=lvaluetest.(file).i@lvaluetest.swift:1:5 direct_to_storage specialized=no)

(load_expr implicit type='Int' location=lvaluetest.swift:2:9 range=[lvaluetest.swift:2:9 - line:2:9]
  (declref_expr type='@lvalue Int' accessKind=read location=lvaluetest.swift:2:9 range=[lvaluetest.swift:2:9 - line:2:9] decl=lvaluetest.(file).i@lvaluetest.swift:1:5 direct_to_storage specialized=no))

Is my assumption correct, that let constants are not lvalues?

Cheers,

Tim


(Greg Titus) #2

An lvalue is something that can be assigned to / changed. The terminology comes from assignment statements: in “foo = bar”, “foo” is a left-value (lvalue) and “bar" is a right-value (rvalue). The difference is that the lvalue is a named location that can take on a new value and an rvalue is just a plain value.

See: https://en.wikipedia.org/wiki/Value_(computer_science)#lrvalue <https://en.wikipedia.org/wiki/Value_(computer_science)#lrvalue>

In Swift’s AST, you’ll see @lvalue as the type coming from a declaration reference (declref) for var’s and for inout parameters inside a method implementation. You’ll see function application require @lvalue types for inout parameters (most of which will be the implicit first parameters of ‘mutating’ functions - the thing to be mutated). A load converts an expression from an lvalue to being an rvalue, and a store takes an lvalue and a new rvalue to be put there.

Hope this helps!
  - Greg

···

On May 24, 2016, at 9:48 AM, Tim Bodeit via swift-dev <swift-dev@swift.org> wrote:

I couldn’t find any documentation about lvalues in Swift. Can anybody give me a short explanation of what exactly an lvalue is?

In C++ all variables, including those marked with the const modifier seem to be lvalues. It seems to me, that this is not the case for let constants in Swift.

I compared the output of swiftc -dump-ast for
let i = 42
let j = i+1
and
var i = 42
let j = i+1

Where i was respectively accessed as:

(declref_expr type='Int' location=lvaluetest.swift:2:9 range=[lvaluetest.swift:2:9 - line:2:9] decl=lvaluetest.(file).i@lvaluetest.swift <mailto:i@lvaluetest.swift>:1:5 direct_to_storage specialized=no)

(load_expr implicit type='Int' location=lvaluetest.swift:2:9 range=[lvaluetest.swift:2:9 - line:2:9]
  (declref_expr type='@lvalue Int' accessKind=read location=lvaluetest.swift:2:9 range=[lvaluetest.swift:2:9 - line:2:9] decl=lvaluetest.(file).i@lvaluetest.swift <mailto:i@lvaluetest.swift>:1:5 direct_to_storage specialized=no))

Is my assumption correct, that let constants are not lvalues?

Cheers,

Tim
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


(John McCall) #3

I couldn’t find any documentation about lvalues in Swift. Can anybody give me a short explanation of what exactly an lvalue is?

In C++ all variables, including those marked with the const modifier seem to be lvalues. It seems to me, that this is not the case for let constants in Swift.

Correct. There are potential language directions Swift could head in that would force us to formalize a notion of addressable but immutable memory in our typing judgement, but right now that is not necessary.

If you are looking at compiler internals, note that SILGen does sometimes form LValues for immutable values (which it then avoids actually mutating).

John.

···

On May 24, 2016, at 9:48 AM, Tim Bodeit via swift-dev <swift-dev@swift.org> wrote:

I compared the output of swiftc -dump-ast for
let i = 42
let j = i+1
and
var i = 42
let j = i+1

Where i was respectively accessed as:

(declref_expr type='Int' location=lvaluetest.swift:2:9 range=[lvaluetest.swift:2:9 - line:2:9] decl=lvaluetest.(file).i@lvaluetest.swift <mailto:i@lvaluetest.swift>:1:5 direct_to_storage specialized=no)

(load_expr implicit type='Int' location=lvaluetest.swift:2:9 range=[lvaluetest.swift:2:9 - line:2:9]
  (declref_expr type='@lvalue Int' accessKind=read location=lvaluetest.swift:2:9 range=[lvaluetest.swift:2:9 - line:2:9] decl=lvaluetest.(file).i@lvaluetest.swift <mailto:i@lvaluetest.swift>:1:5 direct_to_storage specialized=no))

Is my assumption correct, that let constants are not lvalues?

Cheers,

Tim
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev