interfaces, impls, and constrained generics (basics) (#1073)

* interfaces, impls, and constrained generics (basics)

* separate type checking into declare vs. type check, removing redundancy

* external impls

* added impl scopes to handle generics calling generics

* cleanup

* more cleanup

* Update executable_semantics/testdata/interface/external_impl_point_vector.carbon

Co-authored-by: josh11b <josh11b@users.noreply.github.com>

* Update executable_semantics/testdata/interface/generic_call_generic.carbon

Co-authored-by: josh11b <josh11b@users.noreply.github.com>

* Update executable_semantics/testdata/interface/tuple_vector_add_scale.carbon

Co-authored-by: josh11b <josh11b@users.noreply.github.com>

* Update executable_semantics/testdata/interface/vector_point_add_scale.carbon

Co-authored-by: josh11b <josh11b@users.noreply.github.com>

* change ImplementationDeclaration to ImplDeclaration

* remove impl_type_value

* split NamedEntity into two

* changed GetName to be a free function

* adding comments

* more edits to respond to review

* introduce ImplBinding, remove punning on GenericBinding

* new test case and some minor edits

* refactor GetMember and GetField to move impl logic to interpreter

* remove commennt

* change EntityView to ImplBinding in FieldAccess...

* move ImplBinding

* review response

* added example to impl_scope.h

* minor edits

* Update executable_semantics/interpreter/field_path.h

Co-authored-by: Geoff Romer <gromer@google.com>

* Update executable_semantics/interpreter/value.cpp

Co-authored-by: Geoff Romer <gromer@google.com>

* Update executable_semantics/interpreter/interpreter.cpp

Co-authored-by: Geoff Romer <gromer@google.com>

* Update executable_semantics/ast/expression.h

Co-authored-by: Geoff Romer <gromer@google.com>

* Update executable_semantics/ast/expression.h

Co-authored-by: Geoff Romer <gromer@google.com>

* Update executable_semantics/ast/generic_binding.h

Co-authored-by: Geoff Romer <gromer@google.com>

* more edits from review

* review response

* Update executable_semantics/ast/static_scope.h

Co-authored-by: Geoff Romer <gromer@google.com>

* remove ImplType, renamed node_view to value_node

Co-authored-by: josh11b <josh11b@users.noreply.github.com>
Co-authored-by: Geoff Romer <gromer@google.com>
This commit is contained in:
Jeremy G. Siek
2022-03-02 15:58:45 -05:00
committed by GitHub
co-authored by josh11b Geoff Romer
parent 8f6e42d866
commit 7cce1bd124
43 changed files with 1722 additions and 441 deletions
+73 -11
View File
@@ -44,6 +44,7 @@ class Value {
NominalClassValue,
AlternativeValue,
TupleValue,
Witness,
IntType,
BoolType,
TypeType,
@@ -52,6 +53,7 @@ class Value {
AutoType,
StructType,
NominalClassType,
InterfaceType,
ChoiceType,
ContinuationType, // The type of a continuation.
VariableType, // e.g., generic type parameters.
@@ -61,6 +63,7 @@ class Value {
StringType,
StringValue,
TypeOfClassType,
TypeOfInterfaceType,
TypeOfChoiceType,
};
@@ -331,20 +334,20 @@ class BindingPlaceholderValue : public Value {
explicit BindingPlaceholderValue() : Value(Kind::BindingPlaceholderValue) {}
// Represents a named placeholder.
explicit BindingPlaceholderValue(NamedEntityView named_entity)
explicit BindingPlaceholderValue(ValueNodeView value_node)
: Value(Kind::BindingPlaceholderValue),
named_entity_(std::move(named_entity)) {}
value_node_(std::move(value_node)) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::BindingPlaceholderValue;
}
auto named_entity() const -> const std::optional<NamedEntityView>& {
return named_entity_;
auto value_node() const -> const std::optional<ValueNodeView>& {
return value_node_;
}
private:
std::optional<NamedEntityView> named_entity_;
std::optional<ValueNodeView> value_node_;
};
// The int type.
@@ -382,11 +385,13 @@ class FunctionType : public Value {
public:
FunctionType(llvm::ArrayRef<Nonnull<const GenericBinding*>> deduced,
Nonnull<const Value*> parameters,
Nonnull<const Value*> return_type)
Nonnull<const Value*> return_type,
llvm::ArrayRef<Nonnull<const ImplBinding*>> impl_bindings)
: Value(Kind::FunctionType),
deduced_(deduced),
parameters_(parameters),
return_type_(return_type) {}
return_type_(return_type),
impl_bindings_(impl_bindings) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::FunctionType;
@@ -397,11 +402,17 @@ class FunctionType : public Value {
}
auto parameters() const -> const Value& { return *parameters_; }
auto return_type() const -> const Value& { return *return_type_; }
// The bindings for the witness tables (impls) required by the
// bounds on the type parameters of the generic function.
auto impl_bindings() const -> llvm::ArrayRef<Nonnull<const ImplBinding*>> {
return impl_bindings_;
}
private:
std::vector<Nonnull<const GenericBinding*>> deduced_;
Nonnull<const Value*> parameters_;
Nonnull<const Value*> return_type_;
std::vector<Nonnull<const ImplBinding*>> impl_bindings_;
};
// A pointer type.
@@ -463,10 +474,6 @@ class NominalClassType : public Value {
auto declaration() const -> const ClassDeclaration& { return *declaration_; }
// Return the declaration of the member with the given name.
auto FindMember(const std::string& name) const
-> std::optional<Nonnull<const Declaration*>>;
// Returns the value of the function named `name` in this class, or
// nullopt if there is no such function.
auto FindFunction(const std::string& name) const
@@ -476,6 +483,46 @@ class NominalClassType : public Value {
Nonnull<const ClassDeclaration*> declaration_;
};
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)
-> std::optional<Nonnull<const Declaration*>>;
// An interface type.
class InterfaceType : public Value {
public:
InterfaceType(Nonnull<const InterfaceDeclaration*> declaration)
: Value(Kind::InterfaceType), declaration_(declaration) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::InterfaceType;
}
auto declaration() const -> const InterfaceDeclaration& {
return *declaration_;
}
private:
Nonnull<const InterfaceDeclaration*> declaration_;
};
// The witness table for an impl.
class Witness : public Value {
public:
Witness(Nonnull<const ImplDeclaration*> declaration)
: Value(Kind::Witness), declaration_(declaration) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::Witness;
}
auto declaration() const -> const ImplDeclaration& { return *declaration_; }
private:
Nonnull<const ImplDeclaration*> declaration_;
};
auto FieldTypes(const NominalClassType&) -> std::vector<NamedValue>;
// A choice type.
@@ -627,6 +674,21 @@ class TypeOfClassType : public Value {
Nonnull<const NominalClassType*> class_type_;
};
class TypeOfInterfaceType : public Value {
public:
explicit TypeOfInterfaceType(Nonnull<const InterfaceType*> iface_type)
: Value(Kind::TypeOfInterfaceType), iface_type_(iface_type) {}
static auto classof(const Value* value) -> bool {
return value->kind() == Kind::TypeOfInterfaceType;
}
auto interface_type() const -> const InterfaceType& { return *iface_type_; }
private:
Nonnull<const InterfaceType*> iface_type_;
};
// The type of an expression whose value is a choice type. Currently there is no
// way to explicitly name such a type in Carbon code, but we are tentatively
// using `typeof(ChoiceName)` as the debug-printing format, in anticipation of