mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 22:02:52 +01:00
Add the .Self name for the type expression of a compile time binding (#5937)
We add a virtual node (`CompileTimeBindingPatternStart`) as the first child of `CompileTimeBindingPattern` which holds the identifier underneath it, so that it is checked just before the type expression of the `CompileTimeBindingPattern`. When we reach this virtual node during check, we add `.Self` as a name in the current scope, and when we reach `CompileTimeBindingPattern` we remove it from scope, which ensures it's present during only the checking of the type expression for the compile time pattern. At the moment the `.Self` has a different type (it's a `TypeType`) than other `.Self` in the facet type (which are a single `FacetType`), but the intention is to immediately substitute it out of the facet type entirely, replacing it with a reference to the compile time binding (a `BindSymbolicName`) itself. A TODO has been added for this. --------- Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
co-authored by
Jon Ross-Perkins
parent
2e509e9103
commit
4b0e2b03b6
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "toolchain/check/context.h"
|
||||
#include "toolchain/check/convert.h"
|
||||
#include "toolchain/check/facet_type.h"
|
||||
#include "toolchain/check/handle.h"
|
||||
#include "toolchain/check/inst.h"
|
||||
#include "toolchain/check/interface.h"
|
||||
@@ -57,6 +58,12 @@ static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id,
|
||||
AddBindingPattern(context, name_node, name_id, cast_type_id,
|
||||
type_expr_region_id, is_generic, is_template);
|
||||
|
||||
// TODO: If `is_generic`, then `binding.bind_id is a BindSymbolicName. Subst
|
||||
// the `.Self` of type `type` in the `cast_type_id` type (a `FacetType`)
|
||||
// with the `binding.bind_id` itself, and build a new pattern with that.
|
||||
// This is kind of cyclical. So we need to reuse the EntityNameId, which
|
||||
// will also reuse the CompileTimeBinding for the new BindSymbolicName.
|
||||
|
||||
if (name_id != SemIR::NameId::Underscore) {
|
||||
// Add name to lookup immediately, so it can be used in the rest of the
|
||||
// enclosing pattern.
|
||||
@@ -273,11 +280,28 @@ auto HandleParseNode(Context& context, Parse::VarBindingPatternId node_id)
|
||||
Parse::NodeKind::VarBindingPattern);
|
||||
}
|
||||
|
||||
auto HandleParseNode(Context& context,
|
||||
Parse::CompileTimeBindingPatternStartId /*node_id*/)
|
||||
-> bool {
|
||||
// Make a scope to contain the `.Self` facet value for use in the type of the
|
||||
// compile time binding. This is popped when handling the
|
||||
// CompileTimeBindingPatternId.
|
||||
context.scope_stack().PushForSameRegion();
|
||||
MakePeriodSelfFacetValue(context, SemIR::TypeType::TypeId);
|
||||
return true;
|
||||
}
|
||||
|
||||
auto HandleParseNode(Context& context,
|
||||
Parse::CompileTimeBindingPatternId node_id) -> bool {
|
||||
// Pop the `.Self` facet value name introduced by the
|
||||
// CompileTimeBindingPatternStart.
|
||||
context.scope_stack().Pop();
|
||||
|
||||
auto node_kind = Parse::NodeKind::CompileTimeBindingPattern;
|
||||
if (context.decl_introducer_state_stack().innermost().kind ==
|
||||
Lex::TokenKind::Let) {
|
||||
|
||||
const DeclIntroducerState& introducer =
|
||||
context.decl_introducer_state_stack().innermost();
|
||||
if (introducer.kind == Lex::TokenKind::Let) {
|
||||
// Disallow `let` outside of function and interface definitions.
|
||||
// TODO: Find a less brittle way of doing this. A `scope_inst_id` of `None`
|
||||
// can represent a block scope, but is also used for other kinds of scopes
|
||||
|
||||
Reference in New Issue
Block a user