Basic support for .Self within :! bindings and where expressions. (#1311)

`.Self` is modeled as a new kind of expression, `DotSelfExpression`. Name resolution associates each occurrence of a `DotSelfExpression` with a generic binding, much like for an `IdentifierExpression`.

Both `:!` bindings and `where` expressions bring `.Self` into scope. The tentative intent is that if there are multiple `.Self`s in scope and they refer to different bindings, the result of using a `.Self` expression is an ambiguity error, but that is not implemented in this patch. Instead, like for `IdentifierExpression`s, we find the innermost enclosing definition of `.Self`.

`.Foo` expressions are rewritten to `.Self.Foo`, but this isn't enough to make them do anything useful, because associated constants aren't supported in general yet.
This commit is contained in:
Richard Smith
2022-06-14 21:49:01 -07:00
committed by GitHub
parent b83f5c3fc7
commit 2fef76e58c
26 changed files with 418 additions and 67 deletions
+6 -1
View File
@@ -7,6 +7,7 @@
#include <map>
#include <optional>
#include "explorer/ast/pattern.h"
#include "explorer/common/arena.h"
#include "explorer/common/error_builders.h"
#include "llvm/ADT/StringExtras.h"
@@ -184,7 +185,7 @@ void Expression::Print(llvm::raw_ostream& out) const {
}
case ExpressionKind::WhereExpression: {
const auto& where = cast<WhereExpression>(*this);
out << where.base() << " where ";
out << where.self_binding().type() << " where ";
llvm::ListSeparator sep(" and ");
for (const WhereClause* clause : where.clauses()) {
out << sep << *clause;
@@ -213,6 +214,7 @@ void Expression::Print(llvm::raw_ostream& out) const {
break;
}
case ExpressionKind::IdentifierExpression:
case ExpressionKind::DotSelfExpression:
case ExpressionKind::IntLiteral:
case ExpressionKind::BoolLiteral:
case ExpressionKind::BoolTypeLiteral:
@@ -232,6 +234,9 @@ void Expression::PrintID(llvm::raw_ostream& out) const {
case ExpressionKind::IdentifierExpression:
out << cast<IdentifierExpression>(*this).name();
break;
case ExpressionKind::DotSelfExpression:
out << ".Self";
break;
case ExpressionKind::IntLiteral:
out << cast<IntLiteral>(*this).value();
break;