forked from carbon-language/carbon-lang
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathimpl_binding.h
102 lines (85 loc) · 3.34 KB
/
impl_binding.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// 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_IMPL_BINDING_H_
#define CARBON_EXPLORER_AST_IMPL_BINDING_H_
#include <map>
#include "common/check.h"
#include "common/ostream.h"
#include "explorer/ast/ast_node.h"
#include "explorer/ast/pattern.h"
#include "explorer/ast/value_category.h"
namespace Carbon {
class Value;
class Expression;
class ImplBinding;
// `ImplBinding` plays the role of the parameter for passing witness
// tables to a generic. However, unlike regular parameters
// (`BindingPattern`) there is no explicit syntax that corresponds to
// an `ImplBinding`, so they are not created during parsing. Instances
// of `ImplBinding` are created during type checking, when processing
// a type parameter (a `GenericBinding`), or an `is` requirement in
// a `where` clause.
class ImplBinding : public AstNode {
public:
using ImplementsCarbonValueNode = void;
ImplBinding(SourceLocation source_loc,
Nonnull<const GenericBinding*> type_var,
std::optional<Nonnull<const Value*>> iface)
: AstNode(AstNodeKind::ImplBinding, source_loc),
type_var_(type_var),
iface_(iface) {}
static auto classof(const AstNode* node) -> bool {
return InheritsFromImplBinding(node->kind());
}
void Print(llvm::raw_ostream& out) const override;
void PrintID(llvm::raw_ostream& out) const override;
// The binding for the type variable.
auto type_var() const -> Nonnull<const GenericBinding*> { return type_var_; }
// The constraint being implemented.
// TODO: Rename this to `constraint`.
auto interface() const -> Nonnull<const Value*> {
CARBON_CHECK(iface_) << "interface has not been set yet";
return *iface_;
}
// Set the interface being implemented, if not set by the constructor. Should
// only be called by typechecking.
void set_interface(Nonnull<const Value*> iface) {
CARBON_CHECK(!iface_) << "interface set twice";
iface_ = iface;
}
// Required for the ValueNode interface
auto constant_value() const -> std::optional<Nonnull<const Value*>> {
return std::nullopt;
}
auto symbolic_identity() const -> std::optional<Nonnull<const Value*>> {
return symbolic_identity_;
}
void set_symbolic_identity(Nonnull<const Value*> value) {
CARBON_CHECK(!symbolic_identity_.has_value());
symbolic_identity_ = value;
}
// These functions exist only so that an `ImplBinding` can be used as a
// `ValueNodeView` as a key in a `StaticScope`.
auto static_type() const -> const Value& {
CARBON_FATAL() << "an ImplBinding has no type";
}
auto value_category() const -> ValueCategory { return ValueCategory::Let; }
// Return the original impl binding.
auto original() const -> Nonnull<const ImplBinding*> {
if (original_.has_value()) {
return *original_;
} else {
return this;
}
}
// Set the original impl binding.
void set_original(Nonnull<const ImplBinding*> orig) { original_ = orig; }
private:
Nonnull<const GenericBinding*> type_var_;
std::optional<Nonnull<const Value*>> iface_;
std::optional<Nonnull<const Value*>> symbolic_identity_;
std::optional<Nonnull<const ImplBinding*>> original_;
};
} // namespace Carbon
#endif // CARBON_EXPLORER_AST_IMPL_BINDING_H_