mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 22:02:52 +01:00
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:
committed by
GitHub
co-authored by
josh11b
Geoff Romer
parent
8f6e42d866
commit
7cce1bd124
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user