Rework name lookup to handle non-lexical scoping. (#3354)

When declaring a name such as `fn Ns.Class.F() { ... }`, enter the
scopes of `Ns` and `Ns.Class` as we form the name, and remain in those
non-lexical scopes until the end of the declaration.

When performing an unqualified lookup, look in any enclosing non-lexical
scopes in addition to looking into the lexical name table.

We now track a scope index with each lookup result in the lexical name
lookup table. This is used to determine whether a lexical or non-lexcial
result is the innermost result and whether a declared name is in the
same scope as some previous introduction of that name or in a nested
scope. For now, this could just be the index into the scope_stack, but
the intent is to also use this to detect names being declared after they
are first looked up, which requires the indexes to outlive their scopes,
so we use a persistent numbering of all scopes instead. The persistent
numbering also permits more invariant checking.
This commit is contained in:
Richard Smith
2023-11-06 19:48:41 +00:00
committed by GitHub
parent a4c0febc0f
commit 3bee8932a9
18 changed files with 766 additions and 150 deletions
+4 -2
View File
@@ -55,7 +55,7 @@ static auto BuildFunctionDeclaration(Context& context, bool is_definition)
context.node_stack()
.PopIf<Parse::NodeKind::ImplicitParameterList>()
.value_or(SemIR::InstBlockId::Empty);
auto name_context = context.declaration_name_stack().Pop();
auto name_context = context.declaration_name_stack().FinishName();
auto fn_node =
context.node_stack()
.PopForSoloParseNode<Parse::NodeKind::FunctionIntroducer>();
@@ -132,6 +132,7 @@ static auto BuildFunctionDeclaration(Context& context, bool is_definition)
auto HandleFunctionDeclaration(Context& context, Parse::Node /*parse_node*/)
-> bool {
BuildFunctionDeclaration(context, /*is_definition=*/false);
context.declaration_name_stack().PopScope();
return true;
}
@@ -156,6 +157,7 @@ auto HandleFunctionDefinition(Context& context, Parse::Node parse_node)
context.PopScope();
context.inst_block_stack().Pop();
context.return_scope_stack().pop_back();
context.declaration_name_stack().PopScope();
return true;
}
@@ -233,7 +235,7 @@ auto HandleFunctionIntroducer(Context& context, Parse::Node parse_node)
// Push the bracketing node.
context.node_stack().Push(parse_node);
// A name should always follow.
context.declaration_name_stack().Push();
context.declaration_name_stack().PushScopeAndStartName();
return true;
}