pattern.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef CARBON_EXPLORER_AST_PATTERN_H_
  5. #define CARBON_EXPLORER_AST_PATTERN_H_
  6. #include <optional>
  7. #include <string>
  8. #include <vector>
  9. #include "common/check.h"
  10. #include "common/ostream.h"
  11. #include "explorer/ast/ast_node.h"
  12. #include "explorer/ast/ast_rtti.h"
  13. #include "explorer/ast/clone_context.h"
  14. #include "explorer/ast/expression.h"
  15. #include "explorer/ast/expression_category.h"
  16. #include "explorer/ast/value_node.h"
  17. #include "explorer/base/source_location.h"
  18. #include "llvm/ADT/ArrayRef.h"
  19. #include "llvm/ADT/STLFunctionalExtras.h"
  20. namespace Carbon {
  21. class Value;
  22. // Abstract base class of all AST nodes representing patterns.
  23. //
  24. // Pattern and its derived classes support LLVM-style RTTI, including
  25. // llvm::isa, llvm::cast, and llvm::dyn_cast. To support this, every
  26. // class derived from Pattern must provide a `classof` operation, and
  27. // every concrete derived class must have a corresponding enumerator
  28. // in `Kind`; see https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html for
  29. // details.
  30. class Pattern : public AstNode {
  31. public:
  32. explicit Pattern(CloneContext& context, const Pattern& other)
  33. : AstNode(context, other),
  34. static_type_(context.Clone(other.static_type_)),
  35. value_(context.Clone(other.value_)) {}
  36. Pattern(const Pattern&) = delete;
  37. auto operator=(const Pattern&) -> Pattern& = delete;
  38. ~Pattern() override = 0;
  39. void Print(llvm::raw_ostream& out) const override;
  40. void PrintID(llvm::raw_ostream& out) const override;
  41. static auto classof(const AstNode* node) -> bool {
  42. return InheritsFromPattern(node->kind());
  43. }
  44. // Returns the enumerator corresponding to the most-derived type of this
  45. // object.
  46. auto kind() const -> PatternKind {
  47. return static_cast<PatternKind>(root_kind());
  48. }
  49. // The static type of this pattern. Cannot be called before typechecking.
  50. auto static_type() const -> const Value& {
  51. CARBON_CHECK(static_type_.has_value());
  52. return **static_type_;
  53. }
  54. auto has_static_type() const -> bool { return static_type_.has_value(); }
  55. // Sets the static type of this expression. Can only be called once, during
  56. // typechecking.
  57. void set_static_type(Nonnull<const Value*> type) {
  58. CARBON_CHECK(!static_type_.has_value());
  59. static_type_ = type;
  60. }
  61. // The value of this pattern. Cannot be called before typechecking.
  62. // TODO: Rename to avoid confusion with BindingPattern::constant_value
  63. auto value() const -> const Value& { return **value_; }
  64. // Sets the value of this pattern. Can only be called once, during
  65. // typechecking.
  66. void set_value(Nonnull<const Value*> value) {
  67. CARBON_CHECK(!value_, "set_value called more than once");
  68. value_ = value;
  69. }
  70. // Returns whether the value has been set. Should only be called
  71. // during typechecking: before typechecking it's guaranteed to be false,
  72. // and after typechecking it's guaranteed to be true.
  73. auto has_value() const -> bool { return value_.has_value(); }
  74. // Determines whether the pattern has already been type-checked. Should
  75. // only be used by type-checking.
  76. auto is_type_checked() const -> bool {
  77. return static_type_.has_value() && value_.has_value();
  78. }
  79. protected:
  80. // Constructs a Pattern representing syntax at the given line number.
  81. // `kind` must be the enumerator corresponding to the most-derived type being
  82. // constructed.
  83. Pattern(AstNodeKind kind, SourceLocation source_loc)
  84. : AstNode(kind, source_loc) {}
  85. private:
  86. std::optional<Nonnull<const Value*>> static_type_;
  87. std::optional<Nonnull<const Value*>> value_;
  88. };
  89. // Call the given `visitor` on all patterns nested within the given pattern,
  90. // including `pattern` itself, in a preorder traversal. Aborts and returns
  91. // `false` if `visitor` returns `false`, otherwise returns `true`.
  92. auto VisitNestedPatterns(const Pattern& pattern,
  93. llvm::function_ref<bool(const Pattern&)> visitor)
  94. -> bool;
  95. inline auto VisitNestedPatterns(Pattern& pattern,
  96. llvm::function_ref<bool(Pattern&)> visitor)
  97. -> bool {
  98. // The non-const version is implemented in terms of the const version. The
  99. // const_cast is safe because every pattern reachable through a non-const
  100. // pattern is also non-const.
  101. const Pattern& const_pattern = pattern;
  102. return VisitNestedPatterns(const_pattern, [&](const Pattern& inner) {
  103. return visitor(const_cast<Pattern&>(inner));
  104. });
  105. }
  106. // A pattern consisting of the `auto` keyword.
  107. class AutoPattern : public Pattern {
  108. public:
  109. explicit AutoPattern(SourceLocation source_loc)
  110. : Pattern(AstNodeKind::AutoPattern, source_loc) {}
  111. explicit AutoPattern(CloneContext& context, const AutoPattern& other)
  112. : Pattern(context, other) {}
  113. static auto classof(const AstNode* node) -> bool {
  114. return InheritsFromAutoPattern(node->kind());
  115. }
  116. };
  117. class VarPattern : public Pattern {
  118. public:
  119. explicit VarPattern(SourceLocation source_loc, Nonnull<Pattern*> pattern)
  120. : Pattern(AstNodeKind::VarPattern, source_loc), pattern_(pattern) {}
  121. explicit VarPattern(CloneContext& context, const VarPattern& other)
  122. : Pattern(context, other), pattern_(context.Clone(other.pattern_)) {}
  123. static auto classof(const AstNode* node) -> bool {
  124. return InheritsFromVarPattern(node->kind());
  125. }
  126. auto pattern() const -> const Pattern& { return *pattern_; }
  127. auto pattern() -> Pattern& { return *pattern_; }
  128. auto expression_category() const -> ExpressionCategory {
  129. return ExpressionCategory::Reference;
  130. }
  131. private:
  132. Nonnull<Pattern*> pattern_;
  133. };
  134. // A pattern that matches a value of a specified type, and optionally binds
  135. // a name to it.
  136. class BindingPattern : public Pattern {
  137. public:
  138. using ImplementsCarbonValueNode = void;
  139. BindingPattern(SourceLocation source_loc, std::string name,
  140. Nonnull<Pattern*> type,
  141. std::optional<ExpressionCategory> expression_category)
  142. : Pattern(AstNodeKind::BindingPattern, source_loc),
  143. name_(std::move(name)),
  144. type_(type),
  145. expression_category_(expression_category) {}
  146. explicit BindingPattern(CloneContext& context, const BindingPattern& other)
  147. : Pattern(context, other),
  148. name_(other.name_),
  149. type_(context.Clone(other.type_)),
  150. expression_category_(other.expression_category_) {}
  151. static auto classof(const AstNode* node) -> bool {
  152. return InheritsFromBindingPattern(node->kind());
  153. }
  154. // The name this pattern binds, if any. If equal to AnonymousName, indicates
  155. // that this BindingPattern does not bind a name, which in turn means it
  156. // should not be used as a ValueNode.
  157. auto name() const -> const std::string& { return name_; }
  158. // The pattern specifying the type of values that this pattern matches.
  159. auto type() const -> const Pattern& { return *type_; }
  160. auto type() -> Pattern& { return *type_; }
  161. // Returns the value category of this pattern. Can only be called after
  162. // typechecking.
  163. auto expression_category() const -> ExpressionCategory {
  164. return expression_category_.value();
  165. }
  166. // Returns whether the value category has been set. Should only be called
  167. // during typechecking.
  168. auto has_expression_category() const -> bool {
  169. return expression_category_.has_value();
  170. }
  171. // Sets the value category of the variable being bound. Can only be called
  172. // once during typechecking
  173. void set_expression_category(ExpressionCategory vc) {
  174. CARBON_CHECK(!expression_category_.has_value());
  175. expression_category_ = vc;
  176. }
  177. auto constant_value() const -> std::optional<Nonnull<const Value*>> {
  178. return std::nullopt;
  179. }
  180. auto symbolic_identity() const -> std::optional<Nonnull<const Value*>> {
  181. return std::nullopt;
  182. }
  183. private:
  184. std::string name_;
  185. Nonnull<Pattern*> type_;
  186. std::optional<ExpressionCategory> expression_category_;
  187. };
  188. class AddrPattern : public Pattern {
  189. public:
  190. explicit AddrPattern(SourceLocation source_loc,
  191. Nonnull<BindingPattern*> binding)
  192. : Pattern(AstNodeKind::AddrPattern, source_loc), binding_(binding) {}
  193. explicit AddrPattern(CloneContext& context, const AddrPattern& other)
  194. : Pattern(context, other), binding_(context.Clone(other.binding_)) {}
  195. static auto classof(const AstNode* node) -> bool {
  196. return InheritsFromAddrPattern(node->kind());
  197. }
  198. auto binding() const -> const BindingPattern& { return *binding_; }
  199. auto binding() -> BindingPattern& { return *binding_; }
  200. private:
  201. Nonnull<BindingPattern*> binding_;
  202. };
  203. // A pattern that matches a tuple value field-wise.
  204. class TuplePattern : public Pattern {
  205. public:
  206. TuplePattern(SourceLocation source_loc, std::vector<Nonnull<Pattern*>> fields)
  207. : Pattern(AstNodeKind::TuplePattern, source_loc),
  208. fields_(std::move(fields)) {}
  209. explicit TuplePattern(CloneContext& context, const TuplePattern& other)
  210. : Pattern(context, other), fields_(context.Clone(other.fields_)) {}
  211. static auto classof(const AstNode* node) -> bool {
  212. return InheritsFromTuplePattern(node->kind());
  213. }
  214. auto fields() const -> llvm::ArrayRef<Nonnull<const Pattern*>> {
  215. return fields_;
  216. }
  217. auto fields() -> llvm::ArrayRef<Nonnull<Pattern*>> { return fields_; }
  218. private:
  219. std::vector<Nonnull<Pattern*>> fields_;
  220. };
  221. class GenericBinding : public Pattern {
  222. public:
  223. using ImplementsCarbonValueNode = void;
  224. enum class BindingKind {
  225. // A checked generic binding, `T:! type`.
  226. Checked,
  227. // A template generic binding, `template T:! type`.
  228. Template,
  229. };
  230. explicit GenericBinding(SourceLocation source_loc, std::string name,
  231. Nonnull<Expression*> type, BindingKind binding_kind)
  232. : Pattern(AstNodeKind::GenericBinding, source_loc),
  233. name_(std::move(name)),
  234. type_(type),
  235. binding_kind_(binding_kind) {}
  236. explicit GenericBinding(CloneContext& context, const GenericBinding& other);
  237. static auto classof(const AstNode* node) -> bool {
  238. return InheritsFromGenericBinding(node->kind());
  239. }
  240. auto name() const -> const std::string& { return name_; }
  241. auto type() const -> const Expression& { return *type_; }
  242. auto type() -> Expression& { return *type_; }
  243. auto binding_kind() const -> BindingKind { return binding_kind_; }
  244. // The index of this binding, which is the number of bindings that are in
  245. // scope at the point where this binding is declared.
  246. auto index() const -> int {
  247. CARBON_CHECK(index_);
  248. return *index_;
  249. }
  250. // Set the index of this binding. Should be called only during type-checking.
  251. void set_index(int index) {
  252. CARBON_CHECK(!index_, "should only set depth and index once");
  253. index_ = index;
  254. }
  255. auto expression_category() const -> ExpressionCategory {
  256. return ExpressionCategory::Value;
  257. }
  258. auto constant_value() const -> std::optional<Nonnull<const Value*>> {
  259. return template_value_;
  260. }
  261. auto symbolic_identity() const -> std::optional<Nonnull<const Value*>> {
  262. return symbolic_identity_;
  263. }
  264. void set_symbolic_identity(Nonnull<const Value*> value) {
  265. CARBON_CHECK(!symbolic_identity_.has_value());
  266. symbolic_identity_ = value;
  267. }
  268. void set_template_value(Nonnull<const Value*> template_value) {
  269. CARBON_CHECK(binding_kind_ == BindingKind::Template);
  270. template_value_ = template_value;
  271. }
  272. auto has_template_value() const -> bool {
  273. CARBON_CHECK(binding_kind_ == BindingKind::Template);
  274. return template_value_.has_value();
  275. }
  276. // The impl binding associated with this type variable.
  277. auto impl_binding() const -> std::optional<Nonnull<const ImplBinding*>> {
  278. return impl_binding_;
  279. }
  280. // Set the impl binding.
  281. void set_impl_binding(Nonnull<const ImplBinding*> binding) {
  282. CARBON_CHECK(!impl_binding_.has_value());
  283. impl_binding_ = binding;
  284. }
  285. // Return the original generic binding.
  286. auto original() const -> Nonnull<const GenericBinding*> {
  287. if (original_.has_value()) {
  288. return *original_;
  289. } else {
  290. return this;
  291. }
  292. }
  293. // Set the original generic binding.
  294. void set_original(Nonnull<const GenericBinding*> orig) { original_ = orig; }
  295. // Returns whether this binding has been named as a type within its own type
  296. // expression via `.Self`. Set by type-checking.
  297. auto named_as_type_via_dot_self() const -> bool {
  298. return named_as_type_via_dot_self_;
  299. }
  300. // Set that this binding was named as a type within its own type expression
  301. // via `.Self`. May only be called during type-checking.
  302. void set_named_as_type_via_dot_self() { named_as_type_via_dot_self_ = true; }
  303. private:
  304. std::string name_;
  305. Nonnull<Expression*> type_;
  306. BindingKind binding_kind_;
  307. std::optional<int> index_;
  308. std::optional<Nonnull<const Value*>> template_value_;
  309. std::optional<Nonnull<const Value*>> symbolic_identity_;
  310. std::optional<Nonnull<const ImplBinding*>> impl_binding_;
  311. std::optional<Nonnull<const GenericBinding*>> original_;
  312. bool named_as_type_via_dot_self_ = false;
  313. };
  314. // Converts paren_contents to a Pattern, interpreting the parentheses as
  315. // grouping if their contents permit that interpretation, or as forming a
  316. // tuple otherwise.
  317. auto PatternFromParenContents(Nonnull<Arena*> arena, SourceLocation source_loc,
  318. const ParenContents<Pattern>& paren_contents)
  319. -> Nonnull<Pattern*>;
  320. // Converts paren_contents to a TuplePattern, interpreting the parentheses as
  321. // forming a tuple.
  322. auto TuplePatternFromParenContents(Nonnull<Arena*> arena,
  323. SourceLocation source_loc,
  324. const ParenContents<Pattern>& paren_contents)
  325. -> Nonnull<TuplePattern*>;
  326. // Converts `contents` to ParenContents<Pattern> by replacing each Expression
  327. // with an ExpressionPattern.
  328. auto ParenExpressionToParenPattern(Nonnull<Arena*> arena,
  329. const ParenContents<Expression>& contents)
  330. -> ParenContents<Pattern>;
  331. // A pattern that matches an alternative of a choice type.
  332. class AlternativePattern : public Pattern {
  333. public:
  334. // Constructs an AlternativePattern that matches the alternative specified
  335. // by `alternative`, if its arguments match `arguments`.
  336. static auto Create(Nonnull<Arena*> arena, SourceLocation source_loc,
  337. Nonnull<Expression*> alternative,
  338. Nonnull<TuplePattern*> arguments)
  339. -> ErrorOr<Nonnull<AlternativePattern*>> {
  340. CARBON_ASSIGN_OR_RETURN(
  341. Nonnull<SimpleMemberAccessExpression*> member_access,
  342. RequireSimpleMemberAccess(alternative));
  343. return arena->New<AlternativePattern>(source_loc, &member_access->object(),
  344. member_access->member_name(),
  345. arguments);
  346. }
  347. // Constructs an AlternativePattern that matches a value of the type
  348. // specified by choice_type if it represents an alternative named
  349. // alternative_name, and its arguments match `arguments`.
  350. AlternativePattern(SourceLocation source_loc,
  351. Nonnull<Expression*> choice_type,
  352. std::string alternative_name,
  353. Nonnull<TuplePattern*> arguments)
  354. : Pattern(AstNodeKind::AlternativePattern, source_loc),
  355. choice_type_(choice_type),
  356. alternative_name_(std::move(alternative_name)),
  357. arguments_(arguments) {}
  358. explicit AlternativePattern(CloneContext& context,
  359. const AlternativePattern& other)
  360. : Pattern(context, other),
  361. choice_type_(context.Clone(other.choice_type_)),
  362. alternative_name_(other.alternative_name_),
  363. arguments_(context.Clone(other.arguments_)) {}
  364. static auto classof(const AstNode* node) -> bool {
  365. return InheritsFromAlternativePattern(node->kind());
  366. }
  367. auto choice_type() const -> const Expression& { return *choice_type_; }
  368. auto choice_type() -> Expression& { return *choice_type_; }
  369. auto alternative_name() const -> const std::string& {
  370. return alternative_name_;
  371. }
  372. auto arguments() const -> const TuplePattern& { return *arguments_; }
  373. auto arguments() -> TuplePattern& { return *arguments_; }
  374. private:
  375. static auto RequireSimpleMemberAccess(Nonnull<Expression*> alternative)
  376. -> ErrorOr<Nonnull<SimpleMemberAccessExpression*>>;
  377. Nonnull<Expression*> choice_type_;
  378. std::string alternative_name_;
  379. Nonnull<TuplePattern*> arguments_;
  380. };
  381. // A pattern that matches a value if it is equal to the value of a given
  382. // expression.
  383. class ExpressionPattern : public Pattern {
  384. public:
  385. explicit ExpressionPattern(Nonnull<Expression*> expression)
  386. : Pattern(AstNodeKind::ExpressionPattern, expression->source_loc()),
  387. expression_(expression) {}
  388. explicit ExpressionPattern(CloneContext& context,
  389. const ExpressionPattern& other)
  390. : Pattern(context, other),
  391. expression_(context.Clone(other.expression_)) {}
  392. static auto classof(const AstNode* node) -> bool {
  393. return InheritsFromExpressionPattern(node->kind());
  394. }
  395. auto expression() const -> const Expression& { return *expression_; }
  396. auto expression() -> Expression& { return *expression_; }
  397. private:
  398. Nonnull<Expression*> expression_;
  399. };
  400. } // namespace Carbon
  401. #endif // CARBON_EXPLORER_AST_PATTERN_H_