Files
carbon-lang/explorer/testdata/let/pinned_value_copied.carbon
T
Adrien Leravat d02366f881 Explorer: Prevent copies when initializing a let binding from reference expression (#2946)
Prevent copies when initializing value expression from reference
expression. This is based on
https://github.com/carbon-language/carbon-lang/pull/2006, which
introduces expression categories, and how it is possible to convert
to/from those different categories. Continuation of
https://github.com/carbon-language/carbon-lang/pull/2907

## Functional changes

* Initializing a value expression from a reference expression takes its
value without a copy
* Reading from the value expression causes an error if the value changed
from the time it was initialized
* In this situation, prevents a copy both for variable definitions, and
call parameter bindings

## Main implementation changes

* Add new `ExpressionCategoryAction`, which evaluates an expression and
returns an `ExpressionValue` containing its category and address (if
any), in addition to the resulting `Value*`
* `ExpressionAction`s now invokes `ExpressionCategoryAction` and unwraps
the returned `ExpressionValue`
* `RuntimeScope::BindAndPin` method, and corresponding when attempting
to read a `value_node`.

## Next work

* Avoid unnecessary copies from value expression to value expression,
after ensuring that even value expression temporaries are registered for
destruction (https://github.com/Pixep/carbon-lang/pull/9)
2023-07-17 23:26:01 +00:00

28 lines
671 B
Plaintext

// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// AUTOUPDATE
// CHECK:STDOUT: a: 2
// CHECK:STDOUT: a_pinned2: 1
// CHECK:STDOUT: result: 0
package ExplorerTest api;
fn Main() -> i32 {
var a: i32 = 1;
let a_pinned: i32 = a;
let a_pinned_copy: i32 = a_pinned;
// OK: Value unused after being mutated.
a = 2;
Print("a: {0}", a);
// OK: Value was copied from `a_pinned`, and reflects previous value.
// TODO: Avoid value->value copy when possible.
Print("a_pinned2: {0}", a_pinned_copy);
return 0;
}