diff --git a/explorer/ast/BUILD b/explorer/ast/BUILD index 6b9662ff4cce..01311d2a778b 100644 --- a/explorer/ast/BUILD +++ b/explorer/ast/BUILD @@ -43,9 +43,9 @@ cc_library( "value_kinds.def", ], deps = [ + ":expression_category", ":library_name", ":paren_contents", - ":value_category", "//common:check", "//common:enum_base", "//common:error", @@ -155,6 +155,6 @@ cc_library( ) cc_library( - name = "value_category", - hdrs = ["value_category.h"], + name = "expression_category", + hdrs = ["expression_category.h"], ) diff --git a/explorer/ast/declaration.h b/explorer/ast/declaration.h index 8ca32512b66f..90ac321a1cac 100644 --- a/explorer/ast/declaration.h +++ b/explorer/ast/declaration.h @@ -14,11 +14,11 @@ #include "common/ostream.h" #include "explorer/ast/ast_node.h" #include "explorer/ast/clone_context.h" +#include "explorer/ast/expression_category.h" #include "explorer/ast/impl_binding.h" #include "explorer/ast/pattern.h" #include "explorer/ast/return_term.h" #include "explorer/ast/statement.h" -#include "explorer/ast/value_category.h" #include "explorer/ast/value_node.h" #include "explorer/common/nonnull.h" #include "explorer/common/source_location.h" @@ -200,7 +200,9 @@ class NamespaceDeclaration : public Declaration { } auto name() const -> const DeclaredName& { return name_; } - auto value_category() const -> ValueCategory { return ValueCategory::Let; } + auto expression_category() const -> ExpressionCategory { + return ExpressionCategory::Value; + } private: DeclaredName name_; @@ -255,7 +257,9 @@ class CallableDeclaration : public Declaration { auto body() -> std::optional> { return body_; } auto virt_override() const -> VirtualOverride { return virt_override_; } - auto value_category() const -> ValueCategory { return ValueCategory::Let; } + auto expression_category() const -> ExpressionCategory { + return ExpressionCategory::Value; + } auto is_method() const -> bool { return self_pattern_.has_value(); } @@ -356,7 +360,9 @@ class SelfDeclaration : public Declaration { } static auto name() -> std::string_view { return "Self"; } - auto value_category() const -> ValueCategory { return ValueCategory::Let; } + auto expression_category() const -> ExpressionCategory { + return ExpressionCategory::Value; + } }; enum class ClassExtensibility { None, Base, Abstract }; @@ -410,7 +416,9 @@ class ClassDeclaration : public Declaration { return std::nullopt; } - auto value_category() const -> ValueCategory { return ValueCategory::Let; } + auto expression_category() const -> ExpressionCategory { + return ExpressionCategory::Value; + } auto base_expr() const -> std::optional> { return base_expr_; @@ -474,7 +482,9 @@ class MixinDeclaration : public Declaration { return members_; } - auto value_category() const -> ValueCategory { return ValueCategory::Let; } + auto expression_category() const -> ExpressionCategory { + return ExpressionCategory::Value; + } private: DeclaredName name_; @@ -600,7 +610,9 @@ class ChoiceDeclaration : public Declaration { return alternatives_; } - auto value_category() const -> ValueCategory { return ValueCategory::Let; } + auto expression_category() const -> ExpressionCategory { + return ExpressionCategory::Value; + } auto FindAlternative(std::string_view name) const -> std::optional; @@ -617,18 +629,18 @@ class VariableDeclaration : public Declaration { VariableDeclaration(SourceLocation source_loc, Nonnull binding, std::optional> initializer, - ValueCategory value_category) + ExpressionCategory expression_category) : Declaration(AstNodeKind::VariableDeclaration, source_loc), binding_(binding), initializer_(initializer), - value_category_(value_category) {} + expression_category_(expression_category) {} explicit VariableDeclaration(CloneContext& context, const VariableDeclaration& other) : Declaration(context, other), binding_(context.Clone(other.binding_)), initializer_(context.Clone(other.initializer_)), - value_category_(other.value_category_) {} + expression_category_(other.expression_category_) {} static auto classof(const AstNode* node) -> bool { return InheritsFromVariableDeclaration(node->kind()); @@ -638,7 +650,9 @@ class VariableDeclaration : public Declaration { auto binding() -> BindingPattern& { return *binding_; } auto initializer() const -> const Expression& { return **initializer_; } auto initializer() -> Expression& { return **initializer_; } - auto value_category() const -> ValueCategory { return value_category_; } + auto expression_category() const -> ExpressionCategory { + return expression_category_; + } auto has_initializer() const -> bool { return initializer_.has_value(); } @@ -651,7 +665,7 @@ class VariableDeclaration : public Declaration { private: Nonnull binding_; std::optional> initializer_; - ValueCategory value_category_; + ExpressionCategory expression_category_; }; // Base class for constraint and interface declarations. Interfaces and named @@ -703,7 +717,9 @@ class ConstraintTypeDeclaration : public Declaration { return members_; } - auto value_category() const -> ValueCategory { return ValueCategory::Let; } + auto expression_category() const -> ExpressionCategory { + return ExpressionCategory::Value; + } // Get the constraint type corresponding to this interface, or nullopt if // this interface is incomplete. @@ -846,7 +862,9 @@ class AssociatedConstantDeclaration : public Declaration { auto binding() const -> const GenericBinding& { return *binding_; } auto binding() -> GenericBinding& { return *binding_; } - auto value_category() const -> ValueCategory { return ValueCategory::Let; } + auto expression_category() const -> ExpressionCategory { + return ExpressionCategory::Value; + } private: Nonnull binding_; @@ -908,7 +926,9 @@ class ImplDeclaration : public Declaration { auto members() const -> llvm::ArrayRef> { return members_; } - auto value_category() const -> ValueCategory { return ValueCategory::Let; } + auto expression_category() const -> ExpressionCategory { + return ExpressionCategory::Value; + } void set_impl_bindings(llvm::ArrayRef> imps) { impl_bindings_ = imps; } @@ -993,7 +1013,9 @@ class AliasDeclaration : public Declaration { auto name() const -> const DeclaredName& { return name_; } auto target() const -> const Expression& { return *target_; } auto target() -> Expression& { return *target_; } - auto value_category() const -> ValueCategory { return ValueCategory::Let; } + auto expression_category() const -> ExpressionCategory { + return ExpressionCategory::Value; + } private: DeclaredName name_; diff --git a/explorer/ast/element_test.cpp b/explorer/ast/element_test.cpp index dc208c354556..7d7491ae2439 100644 --- a/explorer/ast/element_test.cpp +++ b/explorer/ast/element_test.cpp @@ -34,8 +34,8 @@ TEST_F(ElementTest, NamedElementType) { src_loc, arena.New(src_loc, "valuename", arena.New(src_loc), - ValueCategory::Var), - std::nullopt, ValueCategory::Var}; + ExpressionCategory::Reference), + std::nullopt, ExpressionCategory::Reference}; const auto* static_type = arena.New(1); decl.set_static_type(static_type); NamedElement element_decl(&decl); @@ -53,8 +53,8 @@ TEST_F(ElementTest, NamedElementDeclaration) { src_loc, arena.New(src_loc, "valuename", arena.New(src_loc), - ValueCategory::Var), - std::nullopt, ValueCategory::Var}; + ExpressionCategory::Reference), + std::nullopt, ExpressionCategory::Reference}; const auto* static_type = arena.New(1); NamedElement element_decl(&decl); @@ -71,8 +71,8 @@ TEST_F(ElementTest, NamedElementIsNamed) { src_loc, arena.New(src_loc, "valuename", arena.New(src_loc), - ValueCategory::Var), - std::nullopt, ValueCategory::Var}; + ExpressionCategory::Reference), + std::nullopt, ExpressionCategory::Reference}; NamedElement member_decl(&decl); EXPECT_TRUE(member_decl.IsNamed("valuename")); EXPECT_FALSE(member_decl.IsNamed("anything")); diff --git a/explorer/ast/expression.h b/explorer/ast/expression.h index 97e04228c97e..32016b5402dd 100644 --- a/explorer/ast/expression.h +++ b/explorer/ast/expression.h @@ -16,8 +16,8 @@ #include "explorer/ast/ast_node.h" #include "explorer/ast/bindings.h" #include "explorer/ast/element.h" +#include "explorer/ast/expression_category.h" #include "explorer/ast/paren_contents.h" -#include "explorer/ast/value_category.h" #include "explorer/ast/value_node.h" #include "explorer/common/arena.h" #include "explorer/common/source_location.h" @@ -66,20 +66,22 @@ class Expression : public AstNode { // The value category of this expression. Cannot be called before // typechecking. - auto value_category() const -> ValueCategory { return *value_category_; } + auto expression_category() const -> ExpressionCategory { + return *expression_category_; + } // Sets the value category of this expression. Can be called multiple times, // but the argument must have the same value each time. - void set_value_category(ValueCategory value_category) { - CARBON_CHECK(!value_category_.has_value() || - value_category == *value_category_); - value_category_ = value_category; + void set_expression_category(ExpressionCategory expression_category) { + CARBON_CHECK(!expression_category_.has_value() || + expression_category == *expression_category_); + expression_category_ = expression_category; } // Determines whether the expression has already been type-checked. Should // only be used by type-checking. auto is_type_checked() const -> bool { - return static_type_.has_value() && value_category_.has_value(); + return static_type_.has_value() && expression_category_.has_value(); } protected: @@ -94,7 +96,7 @@ class Expression : public AstNode { private: std::optional> static_type_; - std::optional value_category_; + std::optional expression_category_; }; // A mixin for expressions that can be rewritten to a different expression by @@ -114,7 +116,7 @@ class RewritableMixin : public Base { CARBON_CHECK(!rewritten_form_.has_value()) << "rewritten form set twice"; rewritten_form_ = rewritten_form; this->set_static_type(&rewritten_form->static_type()); - this->set_value_category(rewritten_form->value_category()); + this->set_expression_category(rewritten_form->expression_category()); } // Get the rewritten form of this expression. A rewritten form is used when @@ -477,7 +479,7 @@ class BaseAccessExpression : public MemberAccessExpression { object), base_(base) { set_static_type(&base->type()); - set_value_category(ValueCategory::Let); + set_expression_category(ExpressionCategory::Value); } explicit BaseAccessExpression(CloneContext& context, @@ -849,10 +851,11 @@ class ValueLiteral : public ConstantValueLiteral { // Value literals are created by type-checking, and so are created with their // type and value category already known. ValueLiteral(SourceLocation source_loc, Nonnull value, - Nonnull type, ValueCategory value_category) + Nonnull type, + ExpressionCategory expression_category) : ConstantValueLiteral(AstNodeKind::ValueLiteral, source_loc, value) { set_static_type(type); - set_value_category(value_category); + set_expression_category(expression_category); } explicit ValueLiteral(CloneContext& context, const ValueLiteral& other) @@ -1140,7 +1143,7 @@ class BuiltinConvertExpression : public Expression { source_expression->source_loc()), source_expression_(source_expression) { set_static_type(destination_type); - set_value_category(ValueCategory::Let); + set_expression_category(ExpressionCategory::Value); } explicit BuiltinConvertExpression(CloneContext& context, diff --git a/explorer/ast/expression_category.h b/explorer/ast/expression_category.h new file mode 100644 index 000000000000..fa3aff401bf7 --- /dev/null +++ b/explorer/ast/expression_category.h @@ -0,0 +1,23 @@ +// 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 + +#ifndef CARBON_EXPLORER_AST_EXPRESSION_CATEGORY_H_ +#define CARBON_EXPLORER_AST_EXPRESSION_CATEGORY_H_ + +namespace Carbon { + +// The category of a Carbon expression indicates whether it evaluates +// to a value, reference, or initialization. +enum class ExpressionCategory { + // A "value expression" produces a value (with no associated location). + Value, + // A "reference expression" produces a location of an existing value. + Reference, + // An "initializing expression" takes a location and initialize it. + Initializing, +}; + +} // namespace Carbon + +#endif // CARBON_EXPLORER_AST_EXPRESSION_CATEGORY_H_ diff --git a/explorer/ast/impl_binding.h b/explorer/ast/impl_binding.h index 203378f322c1..89a9153e37ce 100644 --- a/explorer/ast/impl_binding.h +++ b/explorer/ast/impl_binding.h @@ -10,7 +10,7 @@ #include "common/check.h" #include "common/ostream.h" #include "explorer/ast/ast_node.h" -#include "explorer/ast/value_category.h" +#include "explorer/ast/expression_category.h" namespace Carbon { @@ -77,7 +77,9 @@ class ImplBinding : public AstNode { auto static_type() const -> const Value& { CARBON_FATAL() << "an ImplBinding has no type"; } - auto value_category() const -> ValueCategory { return ValueCategory::Let; } + auto expression_category() const -> ExpressionCategory { + return ExpressionCategory::Value; + } // Return the original impl binding. auto original() const -> Nonnull { diff --git a/explorer/ast/pattern.h b/explorer/ast/pattern.h index 0a9e26bc989e..4d7ff7284aea 100644 --- a/explorer/ast/pattern.h +++ b/explorer/ast/pattern.h @@ -14,7 +14,7 @@ #include "explorer/ast/ast_rtti.h" #include "explorer/ast/clone_context.h" #include "explorer/ast/expression.h" -#include "explorer/ast/value_category.h" +#include "explorer/ast/expression_category.h" #include "explorer/ast/value_node.h" #include "explorer/common/source_location.h" #include "llvm/ADT/ArrayRef.h" @@ -152,7 +152,9 @@ class VarPattern : public Pattern { auto pattern() const -> const Pattern& { return *pattern_; } auto pattern() -> Pattern& { return *pattern_; } - auto value_category() const -> ValueCategory { return ValueCategory::Var; } + auto expression_category() const -> ExpressionCategory { + return ExpressionCategory::Reference; + } private: Nonnull pattern_; @@ -166,17 +168,17 @@ class BindingPattern : public Pattern { BindingPattern(SourceLocation source_loc, std::string name, Nonnull type, - std::optional value_category) + std::optional expression_category) : Pattern(AstNodeKind::BindingPattern, source_loc), name_(std::move(name)), type_(type), - value_category_(value_category) {} + expression_category_(expression_category) {} explicit BindingPattern(CloneContext& context, const BindingPattern& other) : Pattern(context, other), name_(other.name_), type_(context.Clone(other.type_)), - value_category_(other.value_category_) {} + expression_category_(other.expression_category_) {} static auto classof(const AstNode* node) -> bool { return InheritsFromBindingPattern(node->kind()); @@ -193,21 +195,21 @@ class BindingPattern : public Pattern { // Returns the value category of this pattern. Can only be called after // typechecking. - auto value_category() const -> ValueCategory { - return value_category_.value(); + auto expression_category() const -> ExpressionCategory { + return expression_category_.value(); } // Returns whether the value category has been set. Should only be called // during typechecking. - auto has_value_category() const -> bool { - return value_category_.has_value(); + auto has_expression_category() const -> bool { + return expression_category_.has_value(); } // Sets the value category of the variable being bound. Can only be called // once during typechecking - void set_value_category(ValueCategory vc) { - CARBON_CHECK(!value_category_.has_value()); - value_category_ = vc; + void set_expression_category(ExpressionCategory vc) { + CARBON_CHECK(!expression_category_.has_value()); + expression_category_ = vc; } auto constant_value() const -> std::optional> { @@ -220,7 +222,7 @@ class BindingPattern : public Pattern { private: std::string name_; Nonnull type_; - std::optional value_category_; + std::optional expression_category_; }; class AddrPattern : public Pattern { @@ -305,7 +307,9 @@ class GenericBinding : public Pattern { index_ = index; } - auto value_category() const -> ValueCategory { return ValueCategory::Let; } + auto expression_category() const -> ExpressionCategory { + return ExpressionCategory::Value; + } auto constant_value() const -> std::optional> { return template_value_; diff --git a/explorer/ast/statement.h b/explorer/ast/statement.h index 110cecb72bd2..8ba8dd5f1c16 100644 --- a/explorer/ast/statement.h +++ b/explorer/ast/statement.h @@ -12,9 +12,9 @@ #include "explorer/ast/ast_node.h" #include "explorer/ast/clone_context.h" #include "explorer/ast/expression.h" +#include "explorer/ast/expression_category.h" #include "explorer/ast/pattern.h" #include "explorer/ast/return_term.h" -#include "explorer/ast/value_category.h" #include "explorer/ast/value_node.h" #include "explorer/common/arena.h" #include "explorer/common/source_location.h" @@ -219,11 +219,12 @@ class VariableDefinition : public Statement { VariableDefinition(SourceLocation source_loc, Nonnull pattern, std::optional> init, - ValueCategory value_category, DefinitionType def_type) + ExpressionCategory expression_category, + DefinitionType def_type) : Statement(AstNodeKind::VariableDefinition, source_loc), pattern_(pattern), init_(init), - value_category_(value_category), + expression_category_(expression_category), def_type_(def_type) {} explicit VariableDefinition(CloneContext& context, @@ -231,7 +232,7 @@ class VariableDefinition : public Statement { : Statement(context, other), pattern_(context.Clone(other.pattern_)), init_(context.Clone(other.init_)), - value_category_(other.value_category_), + expression_category_(other.expression_category_), def_type_(other.def_type_) {} static auto classof(const AstNode* node) -> bool { @@ -258,14 +259,16 @@ class VariableDefinition : public Statement { init_ = init; } - auto value_category() const -> ValueCategory { return value_category_; } + auto expression_category() const -> ExpressionCategory { + return expression_category_; + } auto is_returned() const -> bool { return def_type_ == Returned; }; private: Nonnull pattern_; std::optional> init_; - ValueCategory value_category_; + ExpressionCategory expression_category_; const DefinitionType def_type_; }; @@ -620,7 +623,9 @@ class Continuation : public Statement { static_type_ = type; } - auto value_category() const -> ValueCategory { return ValueCategory::Var; } + auto expression_category() const -> ExpressionCategory { + return ExpressionCategory::Reference; + } auto constant_value() const -> std::optional> { return std::nullopt; } diff --git a/explorer/ast/value.cpp b/explorer/ast/value.cpp index 580cf1eb91ca..0172977c4b82 100644 --- a/explorer/ast/value.cpp +++ b/explorer/ast/value.cpp @@ -479,8 +479,8 @@ void Value::Print(llvm::raw_ostream& out) const { case Value::Kind::PointerValue: out << "ptr<" << cast(*this).address() << ">"; break; - case Value::Kind::LValue: - out << "lval<" << cast(*this).address() << ">"; + case Value::Kind::LocationValue: + out << "lval<" << cast(*this).address() << ">"; break; case Value::Kind::BoolType: out << "bool"; @@ -895,7 +895,7 @@ auto TypeEqual(Nonnull t1, Nonnull t2, case Value::Kind::AlternativeConstructorValue: case Value::Kind::StringValue: case Value::Kind::PointerValue: - case Value::Kind::LValue: + case Value::Kind::LocationValue: case Value::Kind::BindingPlaceholderValue: case Value::Kind::AddrValue: case Value::Kind::ContinuationValue: @@ -1049,7 +1049,7 @@ auto ValueStructurallyEqual( case Value::Kind::AlternativeConstructorValue: case Value::Kind::ContinuationValue: case Value::Kind::PointerValue: - case Value::Kind::LValue: + case Value::Kind::LocationValue: case Value::Kind::UninitializedValue: case Value::Kind::MemberName: // TODO: support pointer comparisons once we have a clearer distinction diff --git a/explorer/ast/value.h b/explorer/ast/value.h index 7b37c2770dc2..bb9b05c4d271 100644 --- a/explorer/ast/value.h +++ b/explorer/ast/value.h @@ -68,8 +68,8 @@ class Value { // Returns the sub-Value specified by `path`, which must be a valid element // path for *this. If the sub-Value is a method and its self_pattern is an - // AddrPattern, then pass the LValue representing the receiver as `me_value`, - // otherwise pass `*this`. + // AddrPattern, then pass the LocationValue representing the receiver as + // `me_value`, otherwise pass `*this`. auto GetElement(Nonnull arena, const ElementPath& path, SourceLocation source_loc, Nonnull me_value) const @@ -237,13 +237,13 @@ class DestructorValue : public Value { }; // The value of a location in memory. -class LValue : public Value { +class LocationValue : public Value { public: - explicit LValue(Address value) - : Value(Kind::LValue), value_(std::move(value)) {} + explicit LocationValue(Address value) + : Value(Kind::LocationValue), value_(std::move(value)) {} static auto classof(const Value* value) -> bool { - return value->kind() == Kind::LValue; + return value->kind() == Kind::LocationValue; } template diff --git a/explorer/ast/value_category.h b/explorer/ast/value_category.h deleted file mode 100644 index 9f300cb44baf..000000000000 --- a/explorer/ast/value_category.h +++ /dev/null @@ -1,22 +0,0 @@ -// 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 - -#ifndef CARBON_EXPLORER_AST_VALUE_CATEGORY_H_ -#define CARBON_EXPLORER_AST_VALUE_CATEGORY_H_ - -namespace Carbon { - -// The value category of a Carbon expression indicates whether it evaluates -// to a variable or a value. A variable can be mutated, and can have its -// address taken, whereas a value cannot. -enum class ValueCategory { - // A variable. This roughly corresponds to a C++ lvalue. - Var, - // A value. This roughly corresponds to a C++ rvalue. - Let, -}; - -} // namespace Carbon - -#endif // CARBON_EXPLORER_AST_VALUE_CATEGORY_H_ diff --git a/explorer/ast/value_kinds.def b/explorer/ast/value_kinds.def index 58c0f9789923..4ae49a92e92d 100644 --- a/explorer/ast/value_kinds.def +++ b/explorer/ast/value_kinds.def @@ -15,7 +15,7 @@ CARBON_VALUE_KIND(FunctionValue) CARBON_VALUE_KIND(DestructorValue) CARBON_VALUE_KIND(BoundMethodValue) CARBON_VALUE_KIND(PointerValue) -CARBON_VALUE_KIND(LValue) +CARBON_VALUE_KIND(LocationValue) CARBON_VALUE_KIND(BoolValue) CARBON_VALUE_KIND(StructValue) CARBON_VALUE_KIND(NominalClassValue) diff --git a/explorer/ast/value_node.h b/explorer/ast/value_node.h index 114c108773f3..d718933dd8d4 100644 --- a/explorer/ast/value_node.h +++ b/explorer/ast/value_node.h @@ -11,7 +11,7 @@ #include "explorer/ast/ast_node.h" #include "explorer/ast/clone_context.h" -#include "explorer/ast/value_category.h" +#include "explorer/ast/expression_category.h" #include "explorer/common/nonnull.h" namespace Carbon { @@ -44,7 +44,7 @@ static constexpr bool ImplementsValueNode = false; // auto static_type() const -> const Value&; // // // Returns the value category of an IdentifierExpression that names *this. -// auto value_category() const -> ValueCategory; +// auto expression_category() const -> ExpressionCategory; // // // Print the node's identity (e.g. its name). // void PrintID(llvm::raw_ostream& out) const; @@ -81,8 +81,8 @@ class ValueNodeView { static_type_([](const AstNode& base) -> const Value& { return llvm::cast(base).static_type(); }), - value_category_([](const AstNode& base) -> ValueCategory { - return llvm::cast(base).value_category(); + expression_category_([](const AstNode& base) -> ExpressionCategory { + return llvm::cast(base).expression_category(); }) {} explicit ValueNodeView(CloneContext& context, const ValueNodeView& other) @@ -92,7 +92,7 @@ class ValueNodeView { symbolic_identity_(other.symbolic_identity_), print_(other.print_), static_type_(other.static_type_), - value_category_(other.value_category_) {} + expression_category_(other.expression_category_) {} ValueNodeView(const ValueNodeView&) = default; ValueNodeView(ValueNodeView&&) = default; @@ -117,9 +117,9 @@ class ValueNodeView { // Returns node->static_type() auto static_type() const -> const Value& { return static_type_(*base_); } - // Returns node->value_category() - auto value_category() const -> ValueCategory { - return value_category_(*base_); + // Returns node->expression_category() + auto expression_category() const -> ExpressionCategory { + return expression_category_(*base_); } friend auto operator==(const ValueNodeView& lhs, const ValueNodeView& rhs) @@ -145,7 +145,7 @@ class ValueNodeView { symbolic_identity_; std::function print_; std::function static_type_; - std::function value_category_; + std::function expression_category_; }; } // namespace Carbon diff --git a/explorer/interpreter/action.cpp b/explorer/interpreter/action.cpp index 00bea0aa042b..87f34007380d 100644 --- a/explorer/interpreter/action.cpp +++ b/explorer/interpreter/action.cpp @@ -46,16 +46,17 @@ void RuntimeScope::Print(llvm::raw_ostream& out) const { void RuntimeScope::Bind(ValueNodeView value_node, Nonnull value) { CARBON_CHECK(!value_node.constant_value().has_value()); - CARBON_CHECK(value->kind() != Value::Kind::LValue); + CARBON_CHECK(value->kind() != Value::Kind::LocationValue); auto allocation_id = heap_->GetAllocationId(value); if (!allocation_id) { auto id = heap_->AllocateValue(value); - auto [it, success] = - locals_.insert({value_node, heap_->arena().New(Address(id))}); + auto [it, success] = locals_.insert( + {value_node, heap_->arena().New(Address(id))}); CARBON_CHECK(success) << "Duplicate definition of " << value_node.base(); } else { auto [it, success] = locals_.insert( - {value_node, heap_->arena().New(Address(*allocation_id))}); + {value_node, + heap_->arena().New(Address(*allocation_id))}); CARBON_CHECK(success) << "Duplicate definition of " << value_node.base(); } } @@ -63,10 +64,11 @@ void RuntimeScope::Bind(ValueNodeView value_node, Nonnull value) { void RuntimeScope::Initialize(ValueNodeView value_node, Nonnull value) { CARBON_CHECK(!value_node.constant_value().has_value()); - CARBON_CHECK(value->kind() != Value::Kind::LValue); + CARBON_CHECK(value->kind() != Value::Kind::LocationValue); allocations_.push_back(heap_->AllocateValue(value)); auto [it, success] = locals_.insert( - {value_node, heap_->arena().New(Address(allocations_.back()))}); + {value_node, + heap_->arena().New(Address(allocations_.back()))}); CARBON_CHECK(success) << "Duplicate definition of " << value_node.base(); } @@ -83,7 +85,7 @@ void RuntimeScope::Merge(RuntimeScope other) { } auto RuntimeScope::Get(ValueNodeView value_node) const - -> std::optional> { + -> std::optional> { auto it = locals_.find(value_node); if (it != locals_.end()) { return it->second; @@ -108,8 +110,8 @@ auto RuntimeScope::Capture( void Action::Print(llvm::raw_ostream& out) const { switch (kind()) { - case Action::Kind::LValAction: - out << cast(*this).expression() << " "; + case Action::Kind::LocationAction: + out << cast(*this).expression() << " "; break; case Action::Kind::ExpressionAction: out << cast(*this).expression() << " "; diff --git a/explorer/interpreter/action.h b/explorer/interpreter/action.h index 84da93bb697f..a51835f3ac33 100644 --- a/explorer/interpreter/action.h +++ b/explorer/interpreter/action.h @@ -60,7 +60,7 @@ class RuntimeScope { // Returns the local storage for value_node, if it has storage local to // this scope. auto Get(ValueNodeView value_node) const - -> std::optional>; + -> std::optional>; // Returns the local values in created order auto allocations() const -> const std::vector& { @@ -68,7 +68,7 @@ class RuntimeScope { } private: - llvm::MapVector, + llvm::MapVector, std::map> locals_; std::vector allocations_; @@ -90,7 +90,7 @@ class RuntimeScope { class Action { public: enum class Kind { - LValAction, + LocationAction, ExpressionAction, WitnessAction, StatementAction, @@ -164,14 +164,14 @@ class Action { }; // An Action which implements evaluation of an Expression to produce an -// LValue. -class LValAction : public Action { +// LocationValue. +class LocationAction : public Action { public: - explicit LValAction(Nonnull expression) - : Action(Kind::LValAction), expression_(expression) {} + explicit LocationAction(Nonnull expression) + : Action(Kind::LocationAction), expression_(expression) {} static auto classof(const Action* action) -> bool { - return action->kind() == Kind::LValAction; + return action->kind() == Kind::LocationAction; } // The Expression this Action evaluates. @@ -181,8 +181,7 @@ class LValAction : public Action { Nonnull expression_; }; -// An Action which implements evaluation of an Expression to produce an -// rvalue. The result is expressed as a Value. +// An Action which implements evaluation of an Expression to produce a `Value*`. class ExpressionAction : public Action { public: explicit ExpressionAction(Nonnull expression) @@ -298,26 +297,26 @@ class CleanUpAction : public Action { // values. class DestroyAction : public Action { public: - // lvalue: Address of the object to be destroyed - // value: The value to be destroyed - // In most cases the lvalue address points to value - // In the case that the member of a class is to be destroyed, - // the lvalue points to the address of the class object - // and the value is the member of the class - explicit DestroyAction(Nonnull lvalue, + // location: Location of the object to be destroyed + // value: The value to be destroyed + // In most cases the location address points to value + // In the case that the member of a class is to be destroyed, + // the location points to the address of the class object + // and the value is the member of the class + explicit DestroyAction(Nonnull location, Nonnull value) - : Action(Kind::DestroyAction), lvalue_(lvalue), value_(value) {} + : Action(Kind::DestroyAction), location_(location), value_(value) {} static auto classof(const Action* action) -> bool { return action->kind() == Kind::DestroyAction; } - auto lvalue() const -> Nonnull { return lvalue_; } + auto location() const -> Nonnull { return location_; } auto value() const -> Nonnull { return value_; } private: - Nonnull lvalue_; + Nonnull location_; Nonnull value_; }; diff --git a/explorer/interpreter/action_stack.cpp b/explorer/interpreter/action_stack.cpp index 8a7421a30eaf..64b66cdd5ec0 100644 --- a/explorer/interpreter/action_stack.cpp +++ b/explorer/interpreter/action_stack.cpp @@ -129,7 +129,7 @@ static auto FinishActionKindFor(Action::Kind kind) -> FinishActionKind { switch (kind) { case Action::Kind::ExpressionAction: case Action::Kind::WitnessAction: - case Action::Kind::LValAction: + case Action::Kind::LocationAction: case Action::Kind::TypeInstantiationAction: return FinishActionKind::Value; case Action::Kind::StatementAction: diff --git a/explorer/interpreter/action_stack.h b/explorer/interpreter/action_stack.h index 579936959235..383dd8562cc6 100644 --- a/explorer/interpreter/action_stack.h +++ b/explorer/interpreter/action_stack.h @@ -49,7 +49,7 @@ class ActionStack { void Initialize(ValueNodeView value_node, Nonnull value); // Returns the value bound to `value_node`. If `value_node` is a local - // variable, this will be an LValue. + // variable, this will be an LocationValue. auto ValueOfNode(ValueNodeView value_node, SourceLocation source_loc) const -> ErrorOr>; diff --git a/explorer/interpreter/interpreter.cpp b/explorer/interpreter/interpreter.cpp index 5b3c3f2175b2..a17ed744a185 100644 --- a/explorer/interpreter/interpreter.cpp +++ b/explorer/interpreter/interpreter.cpp @@ -84,7 +84,7 @@ class Interpreter { // State transitions for expressions. auto StepExp() -> ErrorOr; // State transitions for lvalues. - auto StepLvalue() -> ErrorOr; + auto StepLocation() -> ErrorOr; // State transitions for witnesses. auto StepWitness() -> ErrorOr; // State transition for statements. @@ -249,7 +249,7 @@ auto Interpreter::EvalPrim(Operator op, Nonnull /*static_type*/, case Operator::Deref: return heap_.Read(cast(*args[0]).address(), source_loc); case Operator::AddressOf: - return arena_->New(cast(*args[0]).address()); + return arena_->New(cast(*args[0]).address()); case Operator::As: case Operator::Eq: case Operator::NotEq: @@ -299,10 +299,10 @@ auto PatternMatch(Nonnull p, Nonnull v, } case Value::Kind::AddrValue: { const auto& addr = cast(*p); - CARBON_CHECK(v->kind() == Value::Kind::LValue); - const auto& lvalue = cast(*v); + CARBON_CHECK(v->kind() == Value::Kind::LocationValue); + const auto& location = cast(*v); return PatternMatch( - &addr.pattern(), arena->New(lvalue.address()), + &addr.pattern(), arena->New(location.address()), source_loc, bindings, generic_args, trace_stream, arena); } case Value::Kind::VariableType: { @@ -406,11 +406,11 @@ auto PatternMatch(Nonnull p, Nonnull v, } } -auto Interpreter::StepLvalue() -> ErrorOr { +auto Interpreter::StepLocation() -> ErrorOr { Action& act = todo_.CurrentAction(); - const Expression& exp = cast(act).expression(); + const Expression& exp = cast(act).expression(); if (trace_stream_->is_enabled()) { - *trace_stream_ << "--- step lvalue " << exp << " ." << act.pos() << "." + *trace_stream_ << "--- step location " << exp << " ." << act.pos() << "." << " (" << exp.source_loc() << ") --->\n"; } switch (exp.kind()) { @@ -421,19 +421,19 @@ auto Interpreter::StepLvalue() -> ErrorOr { Nonnull value, todo_.ValueOfNode(cast(exp).value_node(), exp.source_loc())); - CARBON_CHECK(isa(value)) << *value; + CARBON_CHECK(isa(value)) << *value; return todo_.FinishAction(value); } case ExpressionKind::SimpleMemberAccessExpression: { const auto& access = cast(exp); const auto constant_value = access.constant_value(); if (auto rewrite = access.rewritten_form()) { - return todo_.ReplaceWith(std::make_unique(*rewrite)); + return todo_.ReplaceWith(std::make_unique(*rewrite)); } if (act.pos() == 0) { // { {e.f :: C, E, F} :: S, H} // -> { e :: [].f :: C, E, F} :: S, H} - return todo_.Spawn(std::make_unique(&access.object())); + return todo_.Spawn(std::make_unique(&access.object())); } else if (act.pos() == 1 && constant_value) { return todo_.Spawn(std::make_unique( *constant_value, access.source_loc())); @@ -443,9 +443,9 @@ auto Interpreter::StepLvalue() -> ErrorOr { } else { // { v :: [].f :: C, E, F} :: S, H} // -> { { &v.f :: C, E, F} :: S, H } - Address object = cast(*act.results()[0]).address(); + Address object = cast(*act.results()[0]).address(); Address member = object.ElementAddress(&access.member()); - return todo_.FinishAction(arena_->New(member)); + return todo_.FinishAction(arena_->New(member)); } } } @@ -453,7 +453,7 @@ auto Interpreter::StepLvalue() -> ErrorOr { const auto& access = cast(exp); const auto constant_value = access.constant_value(); if (act.pos() == 0) { - return todo_.Spawn(std::make_unique(&access.object())); + return todo_.Spawn(std::make_unique(&access.object())); } if (act.pos() == 1 && constant_value) { return todo_.Spawn(std::make_unique( @@ -463,34 +463,35 @@ auto Interpreter::StepLvalue() -> ErrorOr { return todo_.FinishAction(act.results().back()); } CARBON_CHECK(!access.member().interface().has_value()) - << "unexpected lvalue interface member"; + << "unexpected location interface member"; CARBON_ASSIGN_OR_RETURN( Nonnull val, Convert(act.results()[0], *access.member().base_type(), exp.source_loc())); - Address object = cast(*val).address(); + Address object = cast(*val).address(); Address field = object.ElementAddress(&access.member().member()); - return todo_.FinishAction(arena_->New(field)); + return todo_.FinishAction(arena_->New(field)); } } case ExpressionKind::BaseAccessExpression: { const auto& access = cast(exp); if (act.pos() == 0) { - // Get LValue for expression. - return todo_.Spawn(std::make_unique(&access.object())); + // Get LocationValue for expression. + return todo_.Spawn(std::make_unique(&access.object())); } else { - // Append `.base` element to the address, and return the new LValue. - Address object = cast(*act.results()[0]).address(); + // Append `.base` element to the address, and return the new + // LocationValue. + Address object = cast(*act.results()[0]).address(); Address base = object.ElementAddress(&access.element()); - return todo_.FinishAction(arena_->New(base)); + return todo_.FinishAction(arena_->New(base)); } } case ExpressionKind::IndexExpression: { if (act.pos() == 0) { // { {e[i] :: C, E, F} :: S, H} // -> { e :: [][i] :: C, E, F} :: S, H} - return todo_.Spawn( - std::make_unique(&cast(exp).object())); + return todo_.Spawn(std::make_unique( + &cast(exp).object())); } else if (act.pos() == 1) { return todo_.Spawn(std::make_unique( @@ -498,28 +499,28 @@ auto Interpreter::StepLvalue() -> ErrorOr { } else { // { v :: [][i] :: C, E, F} :: S, H} // -> { { &v[i] :: C, E, F} :: S, H } - Address object = cast(*act.results()[0]).address(); + Address object = cast(*act.results()[0]).address(); const auto index = cast(*act.results()[1]).value(); Address field = object.ElementAddress( arena_->New(index, &exp.static_type())); - return todo_.FinishAction(arena_->New(field)); + return todo_.FinishAction(arena_->New(field)); } } case ExpressionKind::OperatorExpression: { const auto& op = cast(exp); if (auto rewrite = op.rewritten_form()) { - return todo_.ReplaceWith(std::make_unique(*rewrite)); + return todo_.ReplaceWith(std::make_unique(*rewrite)); } if (op.op() != Operator::Deref) { CARBON_FATAL() - << "Can't treat primitive operator expression as lvalue: " << exp; + << "Can't treat primitive operator expression as location: " << exp; } if (act.pos() == 0) { return todo_.Spawn( std::make_unique(op.arguments()[0])); } else { const auto& res = cast(*act.results()[0]); - return todo_.FinishAction(arena_->New(res.address())); + return todo_.FinishAction(arena_->New(res.address())); } break; } @@ -543,7 +544,7 @@ auto Interpreter::StepLvalue() -> ErrorOr { case ExpressionKind::DotSelfExpression: case ExpressionKind::ArrayTypeLiteral: case ExpressionKind::BuiltinConvertExpression: - CARBON_FATAL() << "Can't treat expression as lvalue: " << exp; + CARBON_FATAL() << "Can't treat expression as location: " << exp; case ExpressionKind::UnimplementedExpression: CARBON_FATAL() << "Unimplemented: " << exp; } @@ -624,9 +625,9 @@ auto Interpreter::InstantiateType(Nonnull type, CARBON_ASSIGN_OR_RETURN( Nonnull value, todo_.ValueOfNode(&cast(*type).binding(), source_loc)); - if (const auto* lvalue = dyn_cast(value)) { + if (const auto* location = dyn_cast(value)) { CARBON_ASSIGN_OR_RETURN(value, - heap_.Read(lvalue->address(), source_loc)); + heap_.Read(location->address(), source_loc)); } return value; } @@ -735,7 +736,7 @@ auto Interpreter::Convert(Nonnull value, case Value::Kind::FunctionValue: case Value::Kind::DestructorValue: case Value::Kind::BoundMethodValue: - case Value::Kind::LValue: + case Value::Kind::LocationValue: case Value::Kind::BoolValue: case Value::Kind::NominalClassValue: case Value::Kind::AlternativeValue: @@ -1169,7 +1170,8 @@ auto Interpreter::StepExp() -> ErrorOr { if (act.pos() == 0) { // First, evaluate the first operand. if (access.is_addr_me_method()) { - return todo_.Spawn(std::make_unique(&access.object())); + return todo_.Spawn( + std::make_unique(&access.object())); } else { return todo_.Spawn( std::make_unique(&access.object())); @@ -1247,11 +1249,11 @@ auto Interpreter::StepExp() -> ErrorOr { const Value* aggregate; if (access.is_type_access()) { aggregate = act.results().back(); - } else if (const auto* lvalue = - dyn_cast(act.results()[0])) { + } else if (const auto* location = + dyn_cast(act.results()[0])) { CARBON_ASSIGN_OR_RETURN( aggregate, - this->heap_.Read(lvalue->address(), exp.source_loc())); + this->heap_.Read(location->address(), exp.source_loc())); } else { aggregate = act.results()[0]; } @@ -1270,7 +1272,8 @@ auto Interpreter::StepExp() -> ErrorOr { if (act.pos() == 0) { // First, evaluate the first operand. if (access.is_addr_me_method()) { - return todo_.Spawn(std::make_unique(&access.object())); + return todo_.Spawn( + std::make_unique(&access.object())); } else { return todo_.Spawn( std::make_unique(&access.object())); @@ -1384,9 +1387,9 @@ auto Interpreter::StepExp() -> ErrorOr { CARBON_ASSIGN_OR_RETURN( Nonnull value, todo_.ValueOfNode(ident.value_node(), ident.source_loc())); - if (const auto* lvalue = dyn_cast(value)) { + if (const auto* location = dyn_cast(value)) { CARBON_ASSIGN_OR_RETURN( - value, heap_.Read(lvalue->address(), exp.source_loc())); + value, heap_.Read(location->address(), exp.source_loc())); } return todo_.FinishAction(value); } @@ -1415,7 +1418,7 @@ auto Interpreter::StepExp() -> ErrorOr { // -> { {e :: op(vs,v,[],es) :: C, E, F} :: S, H} Nonnull arg = op.arguments()[act.pos()]; if (op.op() == Operator::AddressOf) { - return todo_.Spawn(std::make_unique(arg)); + return todo_.Spawn(std::make_unique(arg)); } else if ((op.op() == Operator::And || op.op() == Operator::Or) && act.pos() == 1) { // Short-circuit evaluation for 'and' & 'or' @@ -1557,7 +1560,7 @@ auto Interpreter::StepExp() -> ErrorOr { : ptr->address(); if (act.pos() == 1) { return todo_.Spawn(std::make_unique( - arena_->New(obj_addr), child_class_value)); + arena_->New(obj_addr), child_class_value)); } else { heap_.Deallocate(obj_addr); return todo_.FinishAction(TupleValue::Empty()); @@ -1565,7 +1568,7 @@ auto Interpreter::StepExp() -> ErrorOr { } else { if (act.pos() == 1) { return todo_.Spawn(std::make_unique( - arena_->New(ptr->address()), pointee)); + arena_->New(ptr->address()), pointee)); } else { heap_.Deallocate(ptr->address()); return todo_.FinishAction(TupleValue::Empty()); @@ -1806,11 +1809,11 @@ auto Interpreter::StepWitness() -> ErrorOr { CARBON_ASSIGN_OR_RETURN( Nonnull value, todo_.ValueOfNode(binding, binding->type_var()->source_loc())); - if (const auto* lvalue = dyn_cast(value)) { + if (const auto* location = dyn_cast(value)) { // TODO: Why do we store values for impl bindings on the heap? CARBON_ASSIGN_OR_RETURN( value, - heap_.Read(lvalue->address(), binding->type_var()->source_loc())); + heap_.Read(location->address(), binding->type_var()->source_loc())); } return todo_.FinishAction(value); } @@ -1942,9 +1945,9 @@ auto Interpreter::StepStmt() -> ErrorOr { Nonnull assigned_array_element, todo_.ValueOfNode(*(loop_var->value_node()), stmt.source_loc())); - const auto* lvalue = cast(assigned_array_element); + const auto* location = cast(assigned_array_element); CARBON_RETURN_IF_ERROR(heap_.Write( - lvalue->address(), source_array->elements()[current_index], + location->address(), source_array->elements()[current_index], stmt.source_loc())); act.ReplaceResult(CurrentIndexPosInResult, @@ -2069,7 +2072,7 @@ auto Interpreter::StepStmt() -> ErrorOr { if (act.pos() == 0) { // { {(lv = e) :: C, E, F} :: S, H} // -> { {lv :: ([] = e) :: C, E, F} :: S, H} - return todo_.Spawn(std::make_unique(&assign.lhs())); + return todo_.Spawn(std::make_unique(&assign.lhs())); } else if (act.pos() == 1) { // { { a :: ([] = e) :: C, E, F} :: S, H} // -> { { e :: (a = []) :: C, E, F} :: S, H} @@ -2077,7 +2080,7 @@ auto Interpreter::StepStmt() -> ErrorOr { } else { // { { v :: (a = []) :: C, E, F} :: S, H} // -> { { C, E, F} :: S, H(a := v)} - const auto& lval = cast(*act.results()[0]); + const auto& lval = cast(*act.results()[0]); CARBON_ASSIGN_OR_RETURN( Nonnull rval, Convert(act.results()[1], &assign.lhs().static_type(), @@ -2136,9 +2139,9 @@ auto Interpreter::StepStmt() -> ErrorOr { } CARBON_ASSIGN_OR_RETURN(Nonnull value, todo_.ValueOfNode(value_node, stmt.source_loc())); - if (const auto* lvalue = dyn_cast(value)) { + if (const auto* location = dyn_cast(value)) { CARBON_ASSIGN_OR_RETURN( - value, heap_.Read(lvalue->address(), ret_var.source_loc())); + value, heap_.Read(location->address(), ret_var.source_loc())); } const CallableDeclaration& function = cast(stmt).function(); CARBON_ASSIGN_OR_RETURN( @@ -2267,7 +2270,7 @@ auto Interpreter::StepDestroy() -> ErrorOr { const int index = class_decl.members().size() - act.pos(); const auto& member = class_decl.members()[index]; if (const auto* var = dyn_cast(member)) { - const Address object = destroy_act.lvalue()->address(); + const Address object = destroy_act.location()->address(); const Address var_addr = object.ElementAddress(arena_->New(var)); const auto v = heap_.Read(var_addr, SourceLocation("destructor", 1)); @@ -2275,18 +2278,18 @@ auto Interpreter::StepDestroy() -> ErrorOr { << "Failed to read member `" << var->binding().name() << "` from class `" << class_decl.name() << "`"; return todo_.Spawn(std::make_unique( - arena_->New(var_addr), *v)); + arena_->New(var_addr), *v)); } else { return todo_.RunAgain(); } } else if (act.pos() == member_count + 1) { // Destroy the parent, if there is one. if (auto base = class_obj->base()) { - const Address obj_addr = destroy_act.lvalue()->address(); + const Address obj_addr = destroy_act.location()->address(); const Address base_addr = obj_addr.ElementAddress(arena_->New(class_obj)); return todo_.Spawn(std::make_unique( - arena_->New(base_addr), base.value())); + arena_->New(base_addr), base.value())); } else { return todo_.RunAgain(); } @@ -2301,13 +2304,13 @@ auto Interpreter::StepDestroy() -> ErrorOr { if (static_cast(act.pos()) < element_count) { const size_t index = element_count - act.pos() - 1; const auto& item = tuple->elements()[index]; - const auto object_addr = destroy_act.lvalue()->address(); + const auto object_addr = destroy_act.location()->address(); Address field_address = object_addr.ElementAddress( arena_->New(index, item)); if (item->kind() == Value::Kind::NominalClassValue || item->kind() == Value::Kind::TupleValue) { return todo_.Spawn(std::make_unique( - arena_->New(field_address), item)); + arena_->New(field_address), item)); } else { // The tuple element's type is an integral type (e.g., i32) // or the type doesn't support destruction. @@ -2333,12 +2336,12 @@ auto Interpreter::StepCleanUp() -> ErrorOr { const size_t alloc_index = cleanup.allocations_count() - act.pos() / 2 - 1; auto allocation = act.scope()->allocations()[alloc_index]; if (act.pos() % 2 == 0) { - auto* lvalue = arena_->New(Address(allocation)); + auto* location = arena_->New(Address(allocation)); auto value = - heap_.Read(lvalue->address(), SourceLocation("destructor", 1)); + heap_.Read(location->address(), SourceLocation("destructor", 1)); // Step over uninitialized values. if (value.ok()) { - return todo_.Spawn(std::make_unique(lvalue, *value)); + return todo_.Spawn(std::make_unique(location, *value)); } else { return todo_.RunAgain(); } @@ -2355,8 +2358,8 @@ auto Interpreter::StepCleanUp() -> ErrorOr { auto Interpreter::Step() -> ErrorOr { Action& act = todo_.CurrentAction(); switch (act.kind()) { - case Action::Kind::LValAction: - CARBON_RETURN_IF_ERROR(StepLvalue()); + case Action::Kind::LocationAction: + CARBON_RETURN_IF_ERROR(StepLocation()); break; case Action::Kind::ExpressionAction: CARBON_RETURN_IF_ERROR(StepExp()); diff --git a/explorer/interpreter/type_checker.cpp b/explorer/interpreter/type_checker.cpp index eeba1a593071..7da65ef6f266 100644 --- a/explorer/interpreter/type_checker.cpp +++ b/explorer/interpreter/type_checker.cpp @@ -88,7 +88,7 @@ static auto IsTypeOfType(Nonnull value) -> bool { case Value::Kind::FunctionValue: case Value::Kind::BoundMethodValue: case Value::Kind::PointerValue: - case Value::Kind::LValue: + case Value::Kind::LocationValue: case Value::Kind::BoolValue: case Value::Kind::TupleValue: case Value::Kind::StructValue: @@ -150,7 +150,7 @@ static auto IsType(Nonnull value) -> bool { case Value::Kind::DestructorValue: case Value::Kind::BoundMethodValue: case Value::Kind::PointerValue: - case Value::Kind::LValue: + case Value::Kind::LocationValue: case Value::Kind::BoolValue: case Value::Kind::TupleValue: case Value::Kind::StructValue: @@ -221,7 +221,7 @@ static auto ExpectCompleteType(SourceLocation source_loc, case Value::Kind::DestructorValue: case Value::Kind::BoundMethodValue: case Value::Kind::PointerValue: - case Value::Kind::LValue: + case Value::Kind::LocationValue: case Value::Kind::BoolValue: case Value::Kind::StructValue: case Value::Kind::TupleValue: @@ -320,7 +320,7 @@ static auto TypeContainsAuto(Nonnull type) -> bool { case Value::Kind::DestructorValue: case Value::Kind::BoundMethodValue: case Value::Kind::PointerValue: - case Value::Kind::LValue: + case Value::Kind::LocationValue: case Value::Kind::BoolValue: case Value::Kind::TupleValue: case Value::Kind::StructValue: @@ -773,7 +773,7 @@ auto TypeChecker::ImplicitlyConvert(std::string_view context, source->source_loc(), *this)); return arena_->New(source->source_loc(), converted_value, destination_constraint, - ValueCategory::Let); + ExpressionCategory::Value); } if (IsTypeOfType(source_type) && IsTypeOfType(destination)) { @@ -886,8 +886,9 @@ auto TypeChecker::BuildBuiltinMethodCall(const ImplScope& impl_scope, } // Build an expression to perform the call `source.(interface.method)(args)`. - Nonnull iface_expr = arena_->New( - source_loc, iface_type, arena_->New(), ValueCategory::Let); + Nonnull iface_expr = + arena_->New(source_loc, iface_type, arena_->New(), + ExpressionCategory::Value); Nonnull iface_member = arena_->New( source_loc, iface_expr, method.name); Nonnull method_access = @@ -1246,7 +1247,7 @@ auto TypeChecker::ArgumentDeduction::Deduce(Nonnull param, case Value::Kind::DestructorValue: case Value::Kind::BoundMethodValue: case Value::Kind::PointerValue: - case Value::Kind::LValue: + case Value::Kind::LocationValue: case Value::Kind::StructValue: case Value::Kind::TupleValue: case Value::Kind::NominalClassValue: @@ -2623,7 +2624,7 @@ auto TypeChecker::LookupRewriteInWitness( // Rewrites a member access expression to produce the given constant value. static void RewriteMemberAccess(Nonnull access, Nonnull value) { - access->set_value_category(ValueCategory::Let); + access->set_expression_category(ExpressionCategory::Value); access->set_static_type(value->unconverted_replacement_type); access->set_constant_value(value->unconverted_replacement); } @@ -2665,10 +2666,11 @@ auto TypeChecker::CheckAddrMeAccess( CARBON_RETURN_IF_ERROR( ExpectExactType(access->source_loc(), "method access, receiver type", me_type, &access->object().static_type(), impl_scope)); - if (access->object().value_category() != ValueCategory::Var) { + if (access->object().expression_category() != + ExpressionCategory::Reference) { return ProgramError(access->source_loc()) << "method " << *access - << " requires its receiver to be an lvalue"; + << " requires its receiver to be a reference expression"; } } return Success(); @@ -2716,7 +2718,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, << tuple_type; } index.set_static_type(tuple_type.elements()[i]); - index.set_value_category(index.object().value_category()); + index.set_expression_category(index.object().expression_category()); return Success(); } case Value::Kind::StaticArrayType: { @@ -2726,7 +2728,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, &index.offset().static_type(), impl_scope)); index.set_static_type( &cast(object_type).element_type()); - index.set_value_category(index.object().value_category()); + index.set_expression_category(index.object().expression_category()); return Success(); } default: @@ -2744,7 +2746,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, arg_types.push_back(&arg->static_type()); } e->set_static_type(arena_->New(std::move(arg_types))); - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); return Success(); } case ExpressionKind::StructLiteral: { @@ -2756,7 +2758,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, arg_types.push_back({arg.name(), &arg.expression().static_type()}); } e->set_static_type(arena_->New(std::move(arg_types))); - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); return Success(); } case ExpressionKind::StructTypeLiteral: { @@ -2769,7 +2771,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, fields.push_back({arg.name(), type}); } struct_type.set_static_type(arena_->New()); - struct_type.set_value_category(ValueCategory::Let); + struct_type.set_expression_category(ExpressionCategory::Value); struct_type.set_constant_value( arena_->New(std::move(fields))); return Success(); @@ -2799,7 +2801,8 @@ auto TypeChecker::TypeCheckExp(Nonnull e, if (access.member_name() == field.name) { access.set_member(arena_->New(&field)); access.set_static_type(field.value); - access.set_value_category(access.object().value_category()); + access.set_expression_category( + access.object().expression_category()); return Success(); } } @@ -2822,13 +2825,14 @@ auto TypeChecker::TypeCheckExp(Nonnull e, access.set_is_type_access(!IsInstanceMember(&access.member())); switch (member->kind()) { case DeclarationKind::VariableDeclaration: - access.set_value_category(access.object().value_category()); + access.set_expression_category( + access.object().expression_category()); break; case DeclarationKind::FunctionDeclaration: { const auto* func_decl = cast(member); CARBON_RETURN_IF_ERROR(CheckAddrMeAccess( &access, func_decl, t_class.bindings(), impl_scope)); - access.set_value_category(ValueCategory::Let); + access.set_expression_category(ExpressionCategory::Value); break; } default: @@ -2956,7 +2960,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, // member accesses that name them. access.set_static_type( arena_->New(NamedElement(result.member))); - access.set_value_category(ValueCategory::Let); + access.set_expression_category(ExpressionCategory::Value); } else { // This is a non-instance member whose value is found directly via // the witness table, such as a non-method function or an @@ -2967,7 +2971,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, CARBON_ASSIGN_OR_RETURN(Nonnull inst_member_type, Substitute(bindings, &member_type)); access.set_static_type(inst_member_type); - access.set_value_category(ValueCategory::Let); + access.set_expression_category(ExpressionCategory::Value); } return Success(); } @@ -2986,7 +2990,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, access.set_member(arena_->New(&field)); access.set_static_type( arena_->New(NamedElement(&field))); - access.set_value_category(ValueCategory::Let); + access.set_expression_category(ExpressionCategory::Value); return Success(); } } @@ -3011,7 +3015,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, arena_->New(arena_->New( NamedValue{access.member_name(), &choice}))); access.set_static_type(&choice); - access.set_value_category(ValueCategory::Let); + access.set_expression_category(ExpressionCategory::Value); return Success(); } @@ -3027,7 +3031,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, arena_->New(arena_->New( NamedValue{access.member_name(), type}))); access.set_static_type(type); - access.set_value_category(ValueCategory::Let); + access.set_expression_category(ExpressionCategory::Value); return Success(); } case Value::Kind::NominalClassType: { @@ -3050,7 +3054,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, Substitute(class_type.bindings(), &member->static_type())); access.set_static_type(field_type); - access.set_value_category(ValueCategory::Let); + access.set_expression_category(ExpressionCategory::Value); return Success(); } default: @@ -3058,7 +3062,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, } access.set_static_type( arena_->New(NamedElement(member))); - access.set_value_category(ValueCategory::Let); + access.set_expression_category(ExpressionCategory::Value); return Success(); } else { return ProgramError(access.source_loc()) @@ -3077,7 +3081,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, access.set_found_in_interface(result.interface); access.set_static_type( arena_->New(NamedElement(result.member))); - access.set_value_category(ValueCategory::Let); + access.set_expression_category(ExpressionCategory::Value); return Success(); } default: @@ -3206,7 +3210,8 @@ auto TypeChecker::TypeCheckExp(Nonnull e, case DeclarationKind::VariableDeclaration: if (has_instance) { CARBON_RETURN_IF_ERROR(set_static_type_as_member_type()); - access.set_value_category(access.object().value_category()); + access.set_expression_category( + access.object().expression_category()); return Success(); } break; @@ -3218,7 +3223,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, !member_name.base_type().has_value()) << "vacuous compound member access"; CARBON_RETURN_IF_ERROR(set_static_type_as_member_type()); - access.set_value_category(ValueCategory::Let); + access.set_expression_category(ExpressionCategory::Value); CARBON_RETURN_IF_ERROR( CheckAddrMeAccess(&access, cast(*decl), bindings_for_member(), impl_scope)); @@ -3228,7 +3233,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, } case DeclarationKind::AssociatedConstantDeclaration: CARBON_RETURN_IF_ERROR(set_static_type_as_member_type()); - access.set_value_category(access.object().value_category()); + access.set_expression_category(access.object().expression_category()); return Success(); default: CARBON_FATAL() << "member " << member_name @@ -3238,7 +3243,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, access.set_static_type( arena_->New(member_name.member())); - access.set_value_category(ValueCategory::Let); + access.set_expression_category(ExpressionCategory::Value); return Success(); } case ExpressionKind::IdentifierExpression: { @@ -3254,7 +3259,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, } } ident.set_static_type(&ident.value_node().static_type()); - ident.set_value_category(ident.value_node().value_category()); + ident.set_expression_category(ident.value_node().expression_category()); return Success(); } case ExpressionKind::DotSelfExpression: { @@ -3265,15 +3270,15 @@ auto TypeChecker::TypeCheckExp(Nonnull e, dot_self.set_static_type(arena_->New()); dot_self.self_binding().set_named_as_type_via_dot_self(); } - dot_self.set_value_category(ValueCategory::Let); + dot_self.set_expression_category(ExpressionCategory::Value); return Success(); } case ExpressionKind::IntLiteral: - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); e->set_static_type(arena_->New()); return Success(); case ExpressionKind::BoolLiteral: - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); e->set_static_type(arena_->New()); return Success(); case ExpressionKind::OperatorExpression: { @@ -3318,7 +3323,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, if (isa(ts[0]) && isa(ts[1]) && IsSameType(ts[0], ts[1], impl_scope)) { op.set_static_type(ts[0]); - op.set_value_category(ValueCategory::Let); + op.set_expression_category(ExpressionCategory::Value); return Success(); } @@ -3348,7 +3353,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, // TODO: Replace this with an intrinsic. if (isa(ts[0])) { op.set_static_type(arena_->New()); - op.set_value_category(ValueCategory::Let); + op.set_expression_category(ExpressionCategory::Value); return Success(); } // Now try an overloaded negation. @@ -3388,7 +3393,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, {lhs_constraint, rhs_constraint})); op.set_rewritten_form(arena_->New( op.source_loc(), result, arena_->New(), - ValueCategory::Let)); + ExpressionCategory::Value)); return Success(); } return handle_binary_operator(Builtin::BitAndWith); @@ -3410,7 +3415,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, arena_->New(), ts[1], impl_scope)); op.set_static_type(arena_->New()); - op.set_value_category(ValueCategory::Let); + op.set_expression_category(ExpressionCategory::Value); return Success(); case Operator::Or: CARBON_RETURN_IF_ERROR(ExpectExactType(e->source_loc(), "||(1)", @@ -3420,14 +3425,14 @@ auto TypeChecker::TypeCheckExp(Nonnull e, arena_->New(), ts[1], impl_scope)); op.set_static_type(arena_->New()); - op.set_value_category(ValueCategory::Let); + op.set_expression_category(ExpressionCategory::Value); return Success(); case Operator::Not: CARBON_RETURN_IF_ERROR(ExpectExactType(e->source_loc(), "!", arena_->New(), ts[0], impl_scope)); op.set_static_type(arena_->New()); - op.set_value_category(ValueCategory::Let); + op.set_expression_category(ExpressionCategory::Value); return Success(); case Operator::Eq: return handle_compare(Builtin::EqWith, "Equal", "equality"); @@ -3446,7 +3451,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, CARBON_RETURN_IF_ERROR( ExpectPointerType(e->source_loc(), "*", ts[0])); op.set_static_type(&cast(*ts[0]).pointee_type()); - op.set_value_category(ValueCategory::Var); + op.set_expression_category(ExpressionCategory::Reference); return Success(); case Operator::Ptr: { auto* type_type = arena_->New(); @@ -3456,17 +3461,18 @@ auto TypeChecker::TypeCheckExp(Nonnull e, type_type)); op.arguments()[0] = converted; op.set_static_type(arena_->New()); - op.set_value_category(ValueCategory::Let); + op.set_expression_category(ExpressionCategory::Value); return Success(); } case Operator::AddressOf: - if (op.arguments()[0]->value_category() != ValueCategory::Var) { + if (op.arguments()[0]->expression_category() != + ExpressionCategory::Reference) { return ProgramError(op.arguments()[0]->source_loc()) << "Argument to " << OperatorToString(op.op()) - << " should be an lvalue."; + << " should be a reference expression."; } op.set_static_type(arena_->New(ts[0])); - op.set_value_category(ValueCategory::Let); + op.set_expression_category(ExpressionCategory::Value); return Success(); case Operator::As: { CARBON_ASSIGN_OR_RETURN( @@ -3511,7 +3517,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, Nonnull return_type, Substitute(call.bindings(), &fun_t.return_type())); call.set_static_type(return_type); - call.set_value_category(ValueCategory::Let); + call.set_expression_category(ExpressionCategory::Value); return Success(); } case Value::Kind::TypeOfParameterizedEntityName: { @@ -3544,7 +3550,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, ChoiceDeclaration>(param_name.declaration())) << "unknown type of ParameterizedEntityName for " << param_name; call.set_static_type(arena_->New()); - call.set_value_category(ValueCategory::Let); + call.set_expression_category(ExpressionCategory::Value); return Success(); } case Value::Kind::ChoiceType: { @@ -3581,13 +3587,13 @@ auto TypeChecker::TypeCheckExp(Nonnull e, CARBON_ASSIGN_OR_RETURN(Nonnull ret, TypeCheckTypeExp(&fn.return_type(), impl_scope)); fn.set_static_type(arena_->New()); - fn.set_value_category(ValueCategory::Let); + fn.set_expression_category(ExpressionCategory::Value); fn.set_constant_value(arena_->New(param, ret)); return Success(); } case ExpressionKind::StringLiteral: e->set_static_type(arena_->New()); - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); return Success(); case ExpressionKind::IntrinsicExpression: { auto& intrinsic_exp = cast(*e); @@ -3611,7 +3617,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, &args[1]->static_type(), impl_scope)); } e->set_static_type(TupleType::Empty()); - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); return Success(); case IntrinsicExpression::Intrinsic::Assert: { if (args.size() != 2) { @@ -3625,7 +3631,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, e->source_loc(), "__intrinsic_assert argument 1", arena_->New(), &args[1]->static_type(), impl_scope)); e->set_static_type(TupleType::Empty()); - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); return Success(); } case IntrinsicExpression::Intrinsic::Alloc: { @@ -3635,7 +3641,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, } const auto* arg_type = &args[0]->static_type(); e->set_static_type(arena_->New(arg_type)); - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); return Success(); } case IntrinsicExpression::Intrinsic::Dealloc: { @@ -3647,7 +3653,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, CARBON_RETURN_IF_ERROR( ExpectPointerType(e->source_loc(), "*", arg_type)); e->set_static_type(TupleType::Empty()); - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); return Success(); } case IntrinsicExpression::Intrinsic::Rand: { @@ -3664,7 +3670,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, &args[1]->static_type(), impl_scope)); e->set_static_type(arena_->New()); - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); return Success(); } case IntrinsicExpression::Intrinsic::ImplicitAs: { @@ -3674,7 +3680,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, } CARBON_RETURN_IF_ERROR(TypeCheckTypeExp(args[0], impl_scope)); e->set_static_type(arena_->New()); - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); return Success(); } case IntrinsicExpression::Intrinsic::ImplicitAsConvert: { @@ -3687,7 +3693,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, // TODO: Check that the type of args[0] implicitly converts to // args[1]. e->set_static_type(result); - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); return Success(); } case IntrinsicExpression::Intrinsic::IntEq: { @@ -3702,7 +3708,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, e->source_loc(), "__intrinsic_int_eq argument 2", arena_->New(), &args[1]->static_type(), impl_scope)); e->set_static_type(arena_->New()); - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); return Success(); } case IntrinsicExpression::Intrinsic::IntCompare: { @@ -3717,7 +3723,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, e->source_loc(), "__intrinsic_int_compare argument 2", arena_->New(), &args[1]->static_type(), impl_scope)); e->set_static_type(arena_->New()); - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); return Success(); } case IntrinsicExpression::Intrinsic::StrEq: { @@ -3732,7 +3738,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, e->source_loc(), "__intrinsic_str_eq argument 2", arena_->New(), &args[1]->static_type(), impl_scope)); e->set_static_type(arena_->New()); - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); return Success(); } case IntrinsicExpression::Intrinsic::StrCompare: { @@ -3747,7 +3753,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, e->source_loc(), "__intrinsic_str_compare argument 2", arena_->New(), &args[1]->static_type(), impl_scope)); e->set_static_type(arena_->New()); - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); return Success(); } case IntrinsicExpression::Intrinsic::IntBitComplement: @@ -3759,7 +3765,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, e->source_loc(), "complement argument", arena_->New(), &args[0]->static_type(), impl_scope)); e->set_static_type(arena_->New()); - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); return Success(); case IntrinsicExpression::Intrinsic::IntBitAnd: case IntrinsicExpression::Intrinsic::IntBitOr: @@ -3777,7 +3783,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, e->source_loc(), "argument 2", arena_->New(), &args[1]->static_type(), impl_scope)); e->set_static_type(arena_->New()); - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); return Success(); } } @@ -3786,7 +3792,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, case ExpressionKind::StringTypeLiteral: case ExpressionKind::TypeTypeLiteral: case ExpressionKind::ContinuationTypeLiteral: - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); e->set_static_type(arena_->New()); return Success(); case ExpressionKind::IfExpression: { @@ -3808,7 +3814,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, &if_expr.then_expression().static_type(), &if_expr.else_expression().static_type(), impl_scope)); e->set_static_type(&if_expr.then_expression().static_type()); - e->set_value_category(ValueCategory::Let); + e->set_expression_category(ExpressionCategory::Value); return Success(); } case ExpressionKind::WhereExpression: { @@ -3938,7 +3944,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, auto* replacement_literal = arena_->New( rewrite_clause.source_loc(), replacement_value, - replacement_type, ValueCategory::Let); + replacement_type, ExpressionCategory::Value); // Convert the replacement value to the type of the associated // constant and find the converted value. This is the value that @@ -3967,7 +3973,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, where.set_rewritten_form(arena_->New( where.source_loc(), std::move(builder).Build(), - arena_->New(), ValueCategory::Let)); + arena_->New(), ExpressionCategory::Value)); return Success(); } case ExpressionKind::UnimplementedExpression: @@ -3992,7 +3998,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, << "Array size cannot be negative"; } array_literal.set_static_type(arena_->New()); - array_literal.set_value_category(ValueCategory::Let); + array_literal.set_expression_category(ExpressionCategory::Value); array_literal.set_constant_value(arena_->New( element_type, cast(size_value)->value())); return Success(); @@ -4128,7 +4134,7 @@ auto TypeChecker::TypeCheckWhereClause(Nonnull clause, auto TypeChecker::TypeCheckPattern( Nonnull p, std::optional> expected, - ImplScope& impl_scope, ValueCategory enclosing_value_category) + ImplScope& impl_scope, ExpressionCategory enclosing_expression_category) -> ErrorOr { if (trace_stream_->is_enabled()) { *trace_stream_ << "checking " << p->kind() << " " << *p; @@ -4151,8 +4157,9 @@ auto TypeChecker::TypeCheckPattern( return ProgramError(binding.type().source_loc()) << "the type of a binding pattern cannot contain bindings"; } - CARBON_RETURN_IF_ERROR(TypeCheckPattern( - &binding.type(), std::nullopt, impl_scope, enclosing_value_category)); + CARBON_RETURN_IF_ERROR(TypeCheckPattern(&binding.type(), std::nullopt, + impl_scope, + enclosing_expression_category)); Nonnull type = &binding.type().value(); // Convert to a type. // TODO: Convert the pattern before interpreting it rather than doing @@ -4160,7 +4167,7 @@ auto TypeChecker::TypeCheckPattern( if (!isa(binding.type().static_type())) { auto* literal = arena_->New(binding.source_loc(), type, &binding.type().static_type(), - ValueCategory::Let); + ExpressionCategory::Value); CARBON_ASSIGN_OR_RETURN( auto* converted, ImplicitlyConvert("type of name binding", impl_scope, literal, @@ -4198,8 +4205,8 @@ auto TypeChecker::TypeCheckPattern( ? arena_->New(&binding) : arena_->New()); - if (!binding.has_value_category()) { - binding.set_value_category(enclosing_value_category); + if (!binding.has_expression_category()) { + binding.set_expression_category(enclosing_expression_category); } return Success(); } @@ -4231,8 +4238,9 @@ auto TypeChecker::TypeCheckPattern( if (expected) { expected_field_type = cast(**expected).elements()[i]; } - CARBON_RETURN_IF_ERROR(TypeCheckPattern( - field, expected_field_type, impl_scope, enclosing_value_category)); + CARBON_RETURN_IF_ERROR(TypeCheckPattern(field, expected_field_type, + impl_scope, + enclosing_expression_category)); if (trace_stream_->is_enabled()) { *trace_stream_ << "finished checking tuple pattern field " << *field << "\n"; @@ -4277,7 +4285,7 @@ auto TypeChecker::TypeCheckPattern( *(*signature)->parameters_static_type())); CARBON_RETURN_IF_ERROR(TypeCheckPattern(&alternative.arguments(), parameter_type, impl_scope, - enclosing_value_category)); + enclosing_expression_category)); alternative.set_static_type(&choice_type); alternative.set_value(arena_->New( &choice_type, *signature, @@ -4297,9 +4305,9 @@ auto TypeChecker::TypeCheckPattern( case PatternKind::VarPattern: { auto& var_pattern = cast(*p); - CARBON_RETURN_IF_ERROR(TypeCheckPattern(&var_pattern.pattern(), expected, - impl_scope, - var_pattern.value_category())); + CARBON_RETURN_IF_ERROR( + TypeCheckPattern(&var_pattern.pattern(), expected, impl_scope, + var_pattern.expression_category())); var_pattern.set_static_type(&var_pattern.pattern().static_type()); var_pattern.set_value(&var_pattern.pattern().value()); return Success(); @@ -4312,7 +4320,7 @@ auto TypeChecker::TypeCheckPattern( } CARBON_RETURN_IF_ERROR(TypeCheckPattern(&addr_pattern.binding(), expected_ptr, impl_scope, - enclosing_value_category)); + enclosing_expression_category)); if (const auto* inner_binding_type = dyn_cast(&addr_pattern.binding().static_type())) { @@ -4432,7 +4440,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, // statements? When would we run them? See #1283. CARBON_RETURN_IF_ERROR(TypeCheckPattern( &clause.pattern(), &match.expression().static_type(), clause_scope, - ValueCategory::Let)); + ExpressionCategory::Value)); if (expected_type.has_value()) { // TODO: For now, we require all patterns to have the same type. If // that's not the same type as the scrutinee, we will convert the @@ -4486,7 +4494,7 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, CARBON_RETURN_IF_ERROR( TypeCheckPattern(&for_stmt.variable_declaration(), &cast(rhs).element_type(), - inner_impl_scope, ValueCategory::Var)); + inner_impl_scope, ExpressionCategory::Reference)); CARBON_RETURN_IF_ERROR(ExpectExactType( for_stmt.source_loc(), "`for` pattern", &cast(rhs).element_type(), @@ -4530,8 +4538,8 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, var.init().source_loc(), &var.init().static_type())); init_type = &var.init().static_type(); } - CARBON_RETURN_IF_ERROR(TypeCheckPattern(&var.pattern(), init_type, - var_scope, var.value_category())); + CARBON_RETURN_IF_ERROR(TypeCheckPattern( + &var.pattern(), init_type, var_scope, var.expression_category())); CARBON_RETURN_IF_ERROR(ExpectCompleteType( var.source_loc(), "type of variable", &var.pattern().static_type())); @@ -4548,9 +4556,11 @@ auto TypeChecker::TypeCheckStmt(Nonnull s, auto& assign = cast(*s); CARBON_RETURN_IF_ERROR(TypeCheckExp(&assign.rhs(), impl_scope)); CARBON_RETURN_IF_ERROR(TypeCheckExp(&assign.lhs(), impl_scope)); - if (assign.lhs().value_category() != ValueCategory::Var) { + if (assign.lhs().expression_category() != ExpressionCategory::Reference) { return ProgramError(assign.source_loc()) - << "Cannot assign to rvalue '" << assign.lhs() << "'"; + << "Only assign a reference expression can be assigned, but got " + "`'" + << assign.lhs() << "`'"; } if (assign.op() == AssignOperator::Plain && IsSameType(&assign.lhs().static_type(), &assign.rhs().static_type(), @@ -4759,20 +4769,22 @@ auto TypeChecker::DeclareCallableDeclaration(Nonnull f, // Bring the deduced parameters into scope. for (Nonnull deduced : f->deduced_parameters()) { CARBON_RETURN_IF_ERROR(TypeCheckPattern( - deduced, std::nullopt, function_scope, ValueCategory::Let)); + deduced, std::nullopt, function_scope, ExpressionCategory::Value)); CollectAndNumberGenericBindingsInPattern(deduced, all_bindings); CollectImplBindingsInPattern(deduced, impl_bindings); } // Type check the receiver pattern. if (f->is_method()) { - CARBON_RETURN_IF_ERROR(TypeCheckPattern( - &f->self_pattern(), std::nullopt, function_scope, ValueCategory::Let)); + CARBON_RETURN_IF_ERROR(TypeCheckPattern(&f->self_pattern(), std::nullopt, + function_scope, + ExpressionCategory::Value)); CollectAndNumberGenericBindingsInPattern(&f->self_pattern(), all_bindings); CollectImplBindingsInPattern(&f->self_pattern(), impl_bindings); } // Type check the parameter pattern. CARBON_RETURN_IF_ERROR(TypeCheckPattern(&f->param_pattern(), std::nullopt, - function_scope, ValueCategory::Let)); + function_scope, + ExpressionCategory::Value)); CollectImplBindingsInPattern(&f->param_pattern(), impl_bindings); // All bindings we've seen so far in this scope are our deduced bindings. @@ -4932,8 +4944,8 @@ auto TypeChecker::DeclareClassDeclaration(Nonnull class_decl, std::vector> bindings = scope_info.bindings; if (class_decl->type_params().has_value()) { Nonnull type_params = *class_decl->type_params(); - CARBON_RETURN_IF_ERROR(TypeCheckPattern(type_params, std::nullopt, - class_scope, ValueCategory::Let)); + CARBON_RETURN_IF_ERROR(TypeCheckPattern( + type_params, std::nullopt, class_scope, ExpressionCategory::Value)); CollectAndNumberGenericBindingsInPattern(type_params, bindings); if (trace_stream_->is_enabled()) { *trace_stream_ << class_scope; @@ -5102,7 +5114,8 @@ auto TypeChecker::DeclareMixinDeclaration(Nonnull mixin_decl, if (mixin_decl->params().has_value()) { CARBON_RETURN_IF_ERROR(TypeCheckPattern(*mixin_decl->params(), std::nullopt, - mixin_scope, ValueCategory::Let)); + mixin_scope, + ExpressionCategory::Value)); if (trace_stream_->is_enabled()) { *trace_stream_ << mixin_scope; } @@ -5121,7 +5134,8 @@ auto TypeChecker::DeclareMixinDeclaration(Nonnull mixin_decl, // Process the Self parameter. CARBON_RETURN_IF_ERROR(TypeCheckPattern(mixin_decl->self(), std::nullopt, - mixin_scope, ValueCategory::Let)); + mixin_scope, + ExpressionCategory::Value)); ScopeInfo mixin_scope_info = ScopeInfo::ForNonClassScope(&mixin_scope); for (Nonnull m : mixin_decl->members()) { @@ -5231,7 +5245,7 @@ auto TypeChecker::DeclareConstraintTypeDeclaration( if (constraint_decl->params().has_value()) { CARBON_RETURN_IF_ERROR(TypeCheckPattern(*constraint_decl->params(), std::nullopt, constraint_scope, - ValueCategory::Let)); + ExpressionCategory::Value)); if (trace_stream_->is_enabled()) { *trace_stream_ << constraint_scope; } @@ -5605,7 +5619,7 @@ auto TypeChecker::DeclareImplDeclaration(Nonnull impl_decl, for (Nonnull deduced : impl_decl->deduced_parameters()) { generic_bindings.push_back(deduced); CARBON_RETURN_IF_ERROR(TypeCheckPattern(deduced, std::nullopt, impl_scope, - ValueCategory::Let)); + ExpressionCategory::Value)); CollectImplBindingsInPattern(deduced, impl_bindings); } impl_decl->set_impl_bindings(impl_bindings); @@ -5798,8 +5812,8 @@ auto TypeChecker::DeclareChoiceDeclaration(Nonnull choice, std::vector> bindings = scope_info.bindings; if (choice->type_params().has_value()) { Nonnull type_params = *choice->type_params(); - CARBON_RETURN_IF_ERROR(TypeCheckPattern(type_params, std::nullopt, - choice_scope, ValueCategory::Let)); + CARBON_RETURN_IF_ERROR(TypeCheckPattern( + type_params, std::nullopt, choice_scope, ExpressionCategory::Value)); CollectAndNumberGenericBindingsInPattern(type_params, bindings); if (trace_stream_->is_enabled()) { *trace_stream_ << choice_scope; @@ -5845,7 +5859,7 @@ static auto IsValidTypeForAliasTarget(Nonnull type) -> bool { case Value::Kind::DestructorValue: case Value::Kind::BoundMethodValue: case Value::Kind::PointerValue: - case Value::Kind::LValue: + case Value::Kind::LocationValue: case Value::Kind::BoolValue: case Value::Kind::StructValue: case Value::Kind::NominalClassValue: @@ -6118,7 +6132,7 @@ auto TypeChecker::DeclareDeclaration(Nonnull d, } CARBON_RETURN_IF_ERROR(TypeCheckPattern(&var.binding(), std::nullopt, *scope_info.innermost_scope, - var.value_category())); + var.expression_category())); CARBON_RETURN_IF_ERROR(ExpectCompleteType( var.source_loc(), "type of variable", &var.binding().static_type())); var.set_static_type(&var.binding().static_type()); diff --git a/explorer/interpreter/type_checker.h b/explorer/interpreter/type_checker.h index 88ac6a418931..5e12dd6fdf46 100644 --- a/explorer/interpreter/type_checker.h +++ b/explorer/interpreter/type_checker.h @@ -161,7 +161,7 @@ class TypeChecker { // Checks a member access that might be accessing a function taking `addr // self: Self*`. If it does, this function marks the member access accordingly - // and ensures the object argument is an lvalue. + // and ensures the object argument is a reference expression. auto CheckAddrMeAccess(Nonnull access, Nonnull func_decl, const Bindings& bindings, const ImplScope& impl_scope) @@ -196,7 +196,7 @@ class TypeChecker { auto TypeCheckPattern(Nonnull p, std::optional> expected, ImplScope& impl_scope, - ValueCategory enclosing_value_category) + ExpressionCategory enclosing_expression_category) -> ErrorOr; // Type checks a generic binding. `symbolic_value` is the symbolic name by diff --git a/explorer/syntax/BUILD b/explorer/syntax/BUILD index d2d6c3f0847b..5baf65941bf1 100644 --- a/explorer/syntax/BUILD +++ b/explorer/syntax/BUILD @@ -82,8 +82,8 @@ cc_library( "//common:ostream", "//common:string_helpers", "//explorer/ast", + "//explorer/ast:expression_category", "//explorer/ast:paren_contents", - "//explorer/ast:value_category", "//explorer/common:arena", "//explorer/common:error_builders", "//explorer/common:nonnull", diff --git a/explorer/syntax/parser.ypp b/explorer/syntax/parser.ypp index 61e803db7536..8a1d2d3d863f 100644 --- a/explorer/syntax/parser.ypp +++ b/explorer/syntax/parser.ypp @@ -71,9 +71,9 @@ #include "explorer/ast/ast.h" #include "explorer/ast/declaration.h" #include "explorer/ast/expression.h" + #include "explorer/ast/expression_category.h" #include "explorer/ast/paren_contents.h" #include "explorer/ast/pattern.h" - #include "explorer/ast/value_category.h" #include "explorer/common/arena.h" #include "explorer/common/nonnull.h" #include "explorer/syntax/bison_wrap.h" @@ -941,7 +941,7 @@ clause: $$ = Match::Clause(arena->New( context.source_loc(), std::string(AnonymousName), arena->New(context.source_loc()), - ValueCategory::Let), + ExpressionCategory::Value), $3); } ; @@ -959,31 +959,31 @@ statement: | VAR pattern SEMICOLON { $$ = arena->New( - context.source_loc(), $2, std::nullopt, ValueCategory::Var, + context.source_loc(), $2, std::nullopt, ExpressionCategory::Reference, VariableDefinition::DefinitionType::Var); } | VAR pattern EQUAL expression SEMICOLON { $$ = arena->New( - context.source_loc(), $2, $4, ValueCategory::Var, + context.source_loc(), $2, $4, ExpressionCategory::Reference, VariableDefinition::DefinitionType::Var); } | RETURNED VAR variable_declaration SEMICOLON { $$ = arena->New( - context.source_loc(), $3, std::nullopt, ValueCategory::Var, + context.source_loc(), $3, std::nullopt, ExpressionCategory::Reference, VariableDefinition::DefinitionType::Returned); } | RETURNED VAR variable_declaration EQUAL expression SEMICOLON { $$ = arena->New( - context.source_loc(), $3, $5, ValueCategory::Var, + context.source_loc(), $3, $5, ExpressionCategory::Reference, VariableDefinition::DefinitionType::Returned); } | LET pattern EQUAL expression SEMICOLON { $$ = arena->New( - context.source_loc(), $2, $4, ValueCategory::Let, + context.source_loc(), $2, $4, ExpressionCategory::Value, VariableDefinition::DefinitionType::Var); } | statement_expression SEMICOLON @@ -1280,17 +1280,18 @@ declaration: | VAR variable_declaration SEMICOLON { $$ = arena->New(context.source_loc(), $2, - std::nullopt, ValueCategory::Var); + std::nullopt, + ExpressionCategory::Reference); } | VAR variable_declaration EQUAL expression SEMICOLON { $$ = arena->New(context.source_loc(), $2, $4, - ValueCategory::Var); + ExpressionCategory::Reference); } | LET variable_declaration EQUAL expression SEMICOLON { $$ = arena->New(context.source_loc(), $2, $4, - ValueCategory::Let); + ExpressionCategory::Value); } | INTERFACE declared_name type_params LEFT_CURLY_BRACE interface_body RIGHT_CURLY_BRACE { diff --git a/explorer/testdata/addr/fail_method_let.carbon b/explorer/testdata/addr/fail_method_let.carbon index 527720e9fd10..417bc6683173 100644 --- a/explorer/testdata/addr/fail_method_let.carbon +++ b/explorer/testdata/addr/fail_method_let.carbon @@ -26,7 +26,7 @@ class Point { fn Main() -> i32 { let p: Point = Point.Origin(); - // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/addr/fail_method_let.carbon:[[@LINE+1]]: method p.GetSetX requires its receiver to be an lvalue + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/addr/fail_method_let.carbon:[[@LINE+1]]: method p.GetSetX requires its receiver to be a reference expression var x: auto = p.GetSetX(42); if (p.x == 42) { return x; diff --git a/explorer/testdata/basic_syntax/fail_assign_to_function.carbon b/explorer/testdata/basic_syntax/fail_assign_to_function.carbon index 32bfaf6420e2..2b1ffb4f0dfb 100644 --- a/explorer/testdata/basic_syntax/fail_assign_to_function.carbon +++ b/explorer/testdata/basic_syntax/fail_assign_to_function.carbon @@ -12,7 +12,7 @@ fn F() {} fn G() {} fn Main() -> i32 { - // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/basic_syntax/fail_assign_to_function.carbon:[[@LINE+1]]: Cannot assign to rvalue 'F' + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/basic_syntax/fail_assign_to_function.carbon:[[@LINE+1]]: Only assign a reference expression can be assigned, but got `'F`' F = G; return 0; } diff --git a/explorer/testdata/basic_syntax/fail_assign_to_rval.carbon b/explorer/testdata/basic_syntax/fail_assign_to_rval.carbon index 88e7e6036e34..d431606f2152 100644 --- a/explorer/testdata/basic_syntax/fail_assign_to_rval.carbon +++ b/explorer/testdata/basic_syntax/fail_assign_to_rval.carbon @@ -9,7 +9,7 @@ package ExplorerTest api; fn Main() -> i32 { - // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/basic_syntax/fail_assign_to_rval.carbon:[[@LINE+1]]: Cannot assign to rvalue '1' + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/basic_syntax/fail_assign_to_rval.carbon:[[@LINE+1]]: Only assign a reference expression can be assigned, but got `'1`' 1 = 0; return 0; } diff --git a/explorer/testdata/let/fail_function_args.carbon b/explorer/testdata/let/fail_function_args.carbon index fedc6c179d75..fc8e2101106e 100644 --- a/explorer/testdata/let/fail_function_args.carbon +++ b/explorer/testdata/let/fail_function_args.carbon @@ -10,7 +10,7 @@ package ExplorerTest api; fn f((var x: i32, y: i32)) -> i32 { x = 0; - // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/let/fail_function_args.carbon:[[@LINE+1]]: Cannot assign to rvalue 'y' + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/let/fail_function_args.carbon:[[@LINE+1]]: Only assign a reference expression can be assigned, but got `'y`' y = 0; return x - 1; } diff --git a/explorer/testdata/let/fail_global_assign.carbon b/explorer/testdata/let/fail_global_assign.carbon index b5fa4a038473..5fdf379708bc 100644 --- a/explorer/testdata/let/fail_global_assign.carbon +++ b/explorer/testdata/let/fail_global_assign.carbon @@ -11,7 +11,7 @@ package ExplorerTest api; let x: i32 = 10; fn Main() -> i32 { - // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/let/fail_global_assign.carbon:[[@LINE+1]]: Cannot assign to rvalue 'x' + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/let/fail_global_assign.carbon:[[@LINE+1]]: Only assign a reference expression can be assigned, but got `'x`' x = 0; return 0; } diff --git a/explorer/testdata/let/fail_local_assign.carbon b/explorer/testdata/let/fail_local_assign.carbon index 36a565ae9b18..2b600651b456 100644 --- a/explorer/testdata/let/fail_local_assign.carbon +++ b/explorer/testdata/let/fail_local_assign.carbon @@ -10,7 +10,7 @@ package ExplorerTest api; fn Main() -> i32 { let x: auto = 10; - // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/let/fail_local_assign.carbon:[[@LINE+1]]: Cannot assign to rvalue 'x' + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/let/fail_local_assign.carbon:[[@LINE+1]]: Only assign a reference expression can be assigned, but got `'x`' x = 0; return 0; } diff --git a/explorer/testdata/let/fail_match_choice.carbon b/explorer/testdata/let/fail_match_choice.carbon index ec98b8d502a7..35021b6dd069 100644 --- a/explorer/testdata/let/fail_match_choice.carbon +++ b/explorer/testdata/let/fail_match_choice.carbon @@ -25,7 +25,7 @@ fn Main() -> i32 { n = n - 1; } case Ints.Two(x: auto, y: auto) => { - // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/let/fail_match_choice.carbon:[[@LINE+1]]: Cannot assign to rvalue 'x' + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/let/fail_match_choice.carbon:[[@LINE+1]]: Only assign a reference expression can be assigned, but got `'x`' x = 0; } } diff --git a/explorer/testdata/let/fail_method_args.carbon b/explorer/testdata/let/fail_method_args.carbon index d446a3b231ed..b4e2169c93cf 100644 --- a/explorer/testdata/let/fail_method_args.carbon +++ b/explorer/testdata/let/fail_method_args.carbon @@ -14,7 +14,7 @@ class Point { } fn SetX[self: Point](x: i32) { - // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/let/fail_method_args.carbon:[[@LINE+1]]: Cannot assign to rvalue 'x' + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/let/fail_method_args.carbon:[[@LINE+1]]: Only assign a reference expression can be assigned, but got `'x`' x = 10; } diff --git a/explorer/testdata/let/fail_tuple_pattern_let_context.carbon b/explorer/testdata/let/fail_tuple_pattern_let_context.carbon index 56a79ce2924e..d5b877353e03 100644 --- a/explorer/testdata/let/fail_tuple_pattern_let_context.carbon +++ b/explorer/testdata/let/fail_tuple_pattern_let_context.carbon @@ -12,7 +12,7 @@ fn Main() -> i32 { let (var a: auto, b: auto, c: auto, d: auto) = (1, 2, 3, 4); a = 0; // should fail - // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/let/fail_tuple_pattern_let_context.carbon:[[@LINE+1]]: Cannot assign to rvalue 'c' + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/let/fail_tuple_pattern_let_context.carbon:[[@LINE+1]]: Only assign a reference expression can be assigned, but got `'c`' c = 0; return 0; } diff --git a/explorer/testdata/pointer/fail_rvalue_addressof.carbon b/explorer/testdata/pointer/fail_rvalue_addressof.carbon index 245e7c47affc..39ee940b1c14 100644 --- a/explorer/testdata/pointer/fail_rvalue_addressof.carbon +++ b/explorer/testdata/pointer/fail_rvalue_addressof.carbon @@ -10,7 +10,7 @@ package ExplorerTest api; fn Main() -> i32 { var x: i32 = 5; - // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/pointer/fail_rvalue_addressof.carbon:[[@LINE+1]]: Argument to & should be an lvalue. + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/pointer/fail_rvalue_addressof.carbon:[[@LINE+1]]: Argument to & should be a reference expression. var p: i32* = &5; return 0; }