mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Generic classes (#1124)
* start of generic classes * fix regressions * class functions in interfaces * access to class function on interface from class parameter * more stuff working for generic classes * fixing bugs * update TypeEqual for generic classes * fixing bugs and finding new ones * disable unqualified access to members from other members for now * minor edits * bug fixes * introduce compile_time_value to use in type checker instead of constant_value * cleanup * put a CHECK back in * failure test cases for the new FATAL_COMPILATION_ERROR * change a runtime FATAL into a FATAL_COMPILATION_ERROR * Update executable_semantics/ast/declaration.h Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/action_stack.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/interpreter.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/value.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/value.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/interpreter.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/value.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/value.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/resolve_names.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * responses to reviews * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * rename compile_time_value to symbolic_identity * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/type_checker.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/value.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/value.cpp Co-authored-by: Jon Meow <jperkins@google.com> * Update executable_semantics/interpreter/value.cpp Co-authored-by: Jon Meow <jperkins@google.com> * more edits from review * Apply suggestions from code review Co-authored-by: Geoff Romer <gromer@google.com> * review responses * Update executable_semantics/interpreter/interpreter.cpp Co-authored-by: Geoff Romer <gromer@google.com> * const impl_scope for TypeCheckChoiceDeclaration * add some const Co-authored-by: Jon Meow <jperkins@google.com> Co-authored-by: Geoff Romer <gromer@google.com>
This commit is contained in:
committed by
GitHub
co-authored by
Jon Meow
Geoff Romer
parent
37a0e35b31
commit
210856dd57
@@ -129,6 +129,15 @@ class FunctionValue : public Value {
|
||||
explicit FunctionValue(Nonnull<const FunctionDeclaration*> declaration)
|
||||
: Value(Kind::FunctionValue), declaration_(declaration) {}
|
||||
|
||||
explicit FunctionValue(Nonnull<const FunctionDeclaration*> declaration,
|
||||
const BindingMap& type_args,
|
||||
const std::map<Nonnull<const ImplBinding*>,
|
||||
Nonnull<const Witness*>>& wits)
|
||||
: Value(Kind::FunctionValue),
|
||||
declaration_(declaration),
|
||||
type_args_(type_args),
|
||||
witnesses_(wits) {}
|
||||
|
||||
static auto classof(const Value* value) -> bool {
|
||||
return value->kind() == Kind::FunctionValue;
|
||||
}
|
||||
@@ -137,8 +146,17 @@ class FunctionValue : public Value {
|
||||
return *declaration_;
|
||||
}
|
||||
|
||||
auto type_args() const -> const BindingMap& { return type_args_; }
|
||||
|
||||
auto witnesses() const
|
||||
-> const std::map<Nonnull<const ImplBinding*>, const Witness*>& {
|
||||
return witnesses_;
|
||||
}
|
||||
|
||||
private:
|
||||
Nonnull<const FunctionDeclaration*> declaration_;
|
||||
BindingMap type_args_;
|
||||
std::map<Nonnull<const ImplBinding*>, Nonnull<const Witness*>> witnesses_;
|
||||
};
|
||||
|
||||
// A bound method value. It includes the receiver object.
|
||||
@@ -150,6 +168,17 @@ class BoundMethodValue : public Value {
|
||||
declaration_(declaration),
|
||||
receiver_(receiver) {}
|
||||
|
||||
explicit BoundMethodValue(Nonnull<const FunctionDeclaration*> declaration,
|
||||
Nonnull<const Value*> receiver,
|
||||
const BindingMap& type_args,
|
||||
const std::map<Nonnull<const ImplBinding*>,
|
||||
Nonnull<const Witness*>>& wits)
|
||||
: Value(Kind::BoundMethodValue),
|
||||
declaration_(declaration),
|
||||
receiver_(receiver),
|
||||
type_args_(type_args),
|
||||
witnesses_(wits) {}
|
||||
|
||||
static auto classof(const Value* value) -> bool {
|
||||
return value->kind() == Kind::BoundMethodValue;
|
||||
}
|
||||
@@ -160,9 +189,18 @@ class BoundMethodValue : public Value {
|
||||
|
||||
auto receiver() const -> Nonnull<const Value*> { return receiver_; }
|
||||
|
||||
auto type_args() const -> const BindingMap& { return type_args_; }
|
||||
|
||||
auto witnesses() const
|
||||
-> const std::map<Nonnull<const ImplBinding*>, Nonnull<const Witness*>>& {
|
||||
return witnesses_;
|
||||
}
|
||||
|
||||
private:
|
||||
Nonnull<const FunctionDeclaration*> declaration_;
|
||||
Nonnull<const Value*> receiver_;
|
||||
BindingMap type_args_;
|
||||
std::map<Nonnull<const ImplBinding*>, Nonnull<const Witness*>> witnesses_;
|
||||
};
|
||||
|
||||
// The value of a location in memory.
|
||||
@@ -465,16 +503,68 @@ class StructType : public Value {
|
||||
};
|
||||
|
||||
// A class type.
|
||||
// TODO: Consider splitting this class into several classes.
|
||||
class NominalClassType : public Value {
|
||||
public:
|
||||
// Construct a non-generic class type or a generic class type that has
|
||||
// not yet been applied to type arguments.
|
||||
explicit NominalClassType(Nonnull<const ClassDeclaration*> declaration)
|
||||
: Value(Kind::NominalClassType), declaration_(declaration) {}
|
||||
|
||||
// Construct a class type that represents the result of applying the
|
||||
// given generic class to the `type_args`.
|
||||
explicit NominalClassType(Nonnull<const ClassDeclaration*> declaration,
|
||||
const BindingMap& type_args)
|
||||
: Value(Kind::NominalClassType),
|
||||
declaration_(declaration),
|
||||
type_args_(type_args) {}
|
||||
|
||||
// Construct a class type that represents the result of applying the
|
||||
// given generic class to the `type_args` and that records the result of the
|
||||
// compile-time search for any required impls.
|
||||
explicit NominalClassType(
|
||||
Nonnull<const ClassDeclaration*> declaration, const BindingMap& type_args,
|
||||
const std::map<Nonnull<const ImplBinding*>, ValueNodeView>& impls)
|
||||
: Value(Kind::NominalClassType),
|
||||
declaration_(declaration),
|
||||
type_args_(type_args),
|
||||
impls_(impls) {}
|
||||
|
||||
// Construct a fully instantiated generic class type to represent the
|
||||
// run-time type of an object.
|
||||
explicit NominalClassType(Nonnull<const ClassDeclaration*> declaration,
|
||||
const BindingMap& type_args,
|
||||
const std::map<Nonnull<const ImplBinding*>,
|
||||
Nonnull<const Witness*>>& wits)
|
||||
: Value(Kind::NominalClassType),
|
||||
declaration_(declaration),
|
||||
type_args_(type_args),
|
||||
witnesses_(wits) {}
|
||||
|
||||
static auto classof(const Value* value) -> bool {
|
||||
return value->kind() == Kind::NominalClassType;
|
||||
}
|
||||
|
||||
auto declaration() const -> const ClassDeclaration& { return *declaration_; }
|
||||
auto type_args() const -> const BindingMap& { return type_args_; }
|
||||
|
||||
// Maps each of the class's generic parameters to the AST node that
|
||||
// identifies the witness table for the corresponding argument.
|
||||
// Should not be called on 1) a non-generic class, 2) a generic-class
|
||||
// that is not instantiated, or 3) a fully instantiated runtime type
|
||||
// of a generic class.
|
||||
auto impls() const
|
||||
-> const std::map<Nonnull<const ImplBinding*>, ValueNodeView>& {
|
||||
return impls_;
|
||||
}
|
||||
|
||||
// Maps each of the class's generic parameters to the witness table
|
||||
// for the corresponding argument. Should only be called on a fully
|
||||
// instantiated runtime type of a generic class.
|
||||
auto witnesses() const
|
||||
-> const std::map<Nonnull<const ImplBinding*>, Nonnull<const Witness*>>& {
|
||||
return witnesses_;
|
||||
}
|
||||
|
||||
// Returns the value of the function named `name` in this class, or
|
||||
// nullopt if there is no such function.
|
||||
@@ -483,9 +573,11 @@ class NominalClassType : public Value {
|
||||
|
||||
private:
|
||||
Nonnull<const ClassDeclaration*> declaration_;
|
||||
BindingMap type_args_;
|
||||
std::map<Nonnull<const ImplBinding*>, ValueNodeView> impls_;
|
||||
std::map<Nonnull<const ImplBinding*>, Nonnull<const Witness*>> witnesses_;
|
||||
};
|
||||
|
||||
auto FieldTypes(const NominalClassType&) -> std::vector<NamedValue>;
|
||||
// Return the declaration of the member with the given name.
|
||||
auto FindMember(const std::string& name,
|
||||
llvm::ArrayRef<Nonnull<Declaration*>> members)
|
||||
|
||||
Reference in New Issue
Block a user