Move value-category checking to compile time (#960)

This commit is contained in:
Geoff Romer
2021-11-29 17:07:50 -08:00
committed by GitHub
parent 3e188c8562
commit be0c1e9da6
5 changed files with 94 additions and 2 deletions
+22
View File
@@ -24,6 +24,16 @@ class Value;
class Expression : public virtual AstNode {
public:
// 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/C++ lvalue.
Var,
// A value. This roughly corresponds to a C/C++ rvalue.
Let,
};
~Expression() override = 0;
void Print(llvm::raw_ostream& out) const;
@@ -51,6 +61,17 @@ class Expression : public virtual AstNode {
// and after typechecking it's guaranteed to be true.
auto has_static_type() const -> bool { return static_type_.has_value(); }
// The value category of this expression. Cannot be called before
// typechecking.
auto value_category() const -> ValueCategory { return *value_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) {
CHECK(!value_category_.has_value() || value_category == *value_category_);
value_category_ = value_category;
}
protected:
// Constructs an Expression representing syntax at the given line number.
// `kind` must be the enumerator corresponding to the most-derived type being
@@ -59,6 +80,7 @@ class Expression : public virtual AstNode {
private:
std::optional<Nonnull<const Value*>> static_type_;
std::optional<ValueCategory> value_category_;
};
// A FieldInitializer represents the initialization of a single struct field.