mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
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)
This commit is contained in:
@@ -91,6 +91,7 @@ struct NestedValueVisitor {
|
||||
auto Visit(ValueNodeView) -> bool { return true; }
|
||||
auto Visit(int) -> bool { return true; }
|
||||
auto Visit(Address) -> bool { return true; }
|
||||
auto Visit(ExpressionCategory) -> bool { return true; }
|
||||
auto Visit(const std::string&) -> bool { return true; }
|
||||
auto Visit(Nonnull<const NominalClassValue**>) -> bool {
|
||||
// This is the pointer to the most-derived value within a class value,
|
||||
@@ -567,6 +568,10 @@ void Value::Print(llvm::raw_ostream& out) const {
|
||||
case Value::Kind::LocationValue:
|
||||
out << "lval<" << cast<LocationValue>(*this).address() << ">";
|
||||
break;
|
||||
case Value::Kind::ReferenceExpressionValue:
|
||||
out << "ref_expr<" << cast<ReferenceExpressionValue>(*this).address()
|
||||
<< ">";
|
||||
break;
|
||||
case Value::Kind::BoolType:
|
||||
out << "bool";
|
||||
break;
|
||||
@@ -997,6 +1002,7 @@ auto TypeEqual(Nonnull<const Value*> t1, Nonnull<const Value*> t2,
|
||||
case Value::Kind::StringValue:
|
||||
case Value::Kind::PointerValue:
|
||||
case Value::Kind::LocationValue:
|
||||
case Value::Kind::ReferenceExpressionValue:
|
||||
case Value::Kind::BindingPlaceholderValue:
|
||||
case Value::Kind::AddrValue:
|
||||
case Value::Kind::UninitializedValue:
|
||||
@@ -1148,6 +1154,7 @@ auto ValueStructurallyEqual(
|
||||
case Value::Kind::AlternativeConstructorValue:
|
||||
case Value::Kind::PointerValue:
|
||||
case Value::Kind::LocationValue:
|
||||
case Value::Kind::ReferenceExpressionValue:
|
||||
case Value::Kind::UninitializedValue:
|
||||
case Value::Kind::MemberName:
|
||||
// TODO: support pointer comparisons once we have a clearer distinction
|
||||
|
||||
Reference in New Issue
Block a user