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
+9
View File
@@ -408,6 +408,7 @@ auto Interpreter::StepLvalue() -> ErrorOr<Success> {
case ExpressionKind::IntrinsicExpression:
case ExpressionKind::IfExpression:
case ExpressionKind::WhereExpression:
case ExpressionKind::DotSelfExpression:
case ExpressionKind::ArrayTypeLiteral:
case ExpressionKind::InstantiateImpl:
CARBON_FATAL() << "Can't treat expression as lvalue: " << exp;
@@ -927,6 +928,14 @@ auto Interpreter::StepExp() -> ErrorOr<Success> {
}
return todo_.FinishAction(value);
}
case ExpressionKind::DotSelfExpression: {
// `.Self` always symbolically resolves to the self binding, even if it's
// not yet been type-checked.
CARBON_CHECK(act.pos() == 0);
const auto& dot_self = cast<DotSelfExpression>(exp);
return todo_.FinishAction(
arena_->New<VariableType>(&dot_self.self_binding()));
}
case ExpressionKind::IntLiteral:
CARBON_CHECK(act.pos() == 0);
// { {n :: C, E, F} :: S, H} -> { {n' :: C, E, F} :: S, H}