Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
9 changes: 2 additions & 7 deletions toolchain/check/handle_alias.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ auto HandleParseNode(Context& context, Parse::AliasIntroducerId /*node_id*/)
-> bool {
context.decl_introducer_state_stack().Push<Lex::TokenKind::Alias>();
context.decl_name_stack().PushScopeAndStartName();

// Push a pattern block to handle parameters of the alias declaration.
// TODO: Disallow these in parse, instead of check, so we don't have to do
// this.
context.pattern_block_stack().Push();
return true;
}

Expand All @@ -32,8 +27,8 @@ auto HandleParseNode(Context& /*context*/,
auto HandleParseNode(Context& context, Parse::AliasId /*node_id*/) -> bool {
auto [expr_node, expr_id] = context.node_stack().PopExprWithNodeId();

auto name_context = context.decl_name_stack().FinishName(
PopNameComponentWithoutParams(context, Lex::TokenKind::Alias));
auto name_context =
context.decl_name_stack().FinishName(PopNameComponent(context));

auto introducer =
context.decl_introducer_state_stack().Pop<Lex::TokenKind::Alias>();
Expand Down
4 changes: 0 additions & 4 deletions toolchain/check/handle_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ auto HandleParseNode(Context& context, Parse::ClassIntroducerId node_id)
context.decl_name_stack().PushScopeAndStartName();
// This class is potentially generic.
StartGenericDecl(context);
// Push a pattern block for the signature (if any) of the first NameComponent.
// TODO: Instead use a separate parse node kind for an identifier that's
// followed by a pattern, and push a pattern block when handling it.
context.pattern_block_stack().Push();
return true;
}

Expand Down
7 changes: 2 additions & 5 deletions toolchain/check/handle_export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,12 @@ auto HandleParseNode(Context& context, Parse::ExportIntroducerId /*node_id*/)
context.decl_introducer_state_stack().Push<Lex::TokenKind::Export>();
// TODO: Probably need to update DeclNameStack to restrict to only namespaces.
context.decl_name_stack().PushScopeAndStartName();
// The parser supports patterns after `export`, so we need a pattern block
// to handle them.
context.pattern_block_stack().Push();
return true;
}

auto HandleParseNode(Context& context, Parse::ExportDeclId node_id) -> bool {
auto name_context = context.decl_name_stack().FinishName(
PopNameComponentWithoutParams(context, Lex::TokenKind::Export));
auto name_context =
context.decl_name_stack().FinishName(PopNameComponent(context));
context.decl_name_stack().PopScope();

auto introducer =
Expand Down
2 changes: 0 additions & 2 deletions toolchain/check/handle_function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ auto HandleParseNode(Context& context, Parse::FunctionIntroducerId node_id)
context.decl_name_stack().PushScopeAndStartName();
// The function is potentially generic.
StartGenericDecl(context);
// Start a new pattern block for the signature.
context.pattern_block_stack().Push();
return true;
}

Expand Down
4 changes: 0 additions & 4 deletions toolchain/check/handle_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ auto HandleParseNode(Context& context, Parse::InterfaceIntroducerId node_id)
context.decl_name_stack().PushScopeAndStartName();
// This interface is potentially generic.
StartGenericDecl(context);
// Push a pattern block for the signature (if any) of the first NameComponent.
// TODO: Instead use a separate parse node kind for an identifier that's
// followed by a pattern, and push a pattern block when handling it.
context.pattern_block_stack().Push();
return true;
}

Expand Down
29 changes: 22 additions & 7 deletions toolchain/check/handle_name.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ static auto HandleNameAsExpr(Context& context, Parse::NodeId node_id,
{.type_id = type_id, .name_id = name_id, .value_id = result.inst_id});
}

auto HandleParseNode(Context& context, Parse::IdentifierNameId node_id)
static auto HandleIdentifierName(Context& context,
Parse::AnyNonExprIdentifierNameId node_id)
-> bool {
// The parent is responsible for binding the name.
auto name_id = GetIdentifierAsName(context, node_id);
Expand All @@ -133,6 +134,18 @@ auto HandleParseNode(Context& context, Parse::IdentifierNameId node_id)
return true;
}

auto HandleParseNode(Context& context,
Parse::IdentifierNameNotBeforeParamsId node_id) -> bool {
return HandleIdentifierName(context, node_id);
}

auto HandleParseNode(Context& context,
Parse::IdentifierNameBeforeParamsId node_id) -> bool {
// Push a pattern block stack entry to handle the parameter pattern.
context.pattern_block_stack().Push();
return HandleIdentifierName(context, node_id);
}

auto HandleParseNode(Context& context, Parse::IdentifierNameExprId node_id)
-> bool {
auto name_id = GetIdentifierAsName(context, node_id);
Expand Down Expand Up @@ -172,13 +185,15 @@ auto HandleParseNode(Context& context, Parse::SelfValueNameExprId node_id)
return true;
}

auto HandleParseNode(Context& context, Parse::NameQualifierId /*node_id*/)
-> bool {
auto HandleParseNode(Context& context,
Parse::NameQualifierWithParamsId /*node_id*/) -> bool {
context.decl_name_stack().ApplyNameQualifier(PopNameComponent(context));
return true;
}

auto HandleParseNode(Context& context,
Parse::NameQualifierWithoutParamsId /*node_id*/) -> bool {
context.decl_name_stack().ApplyNameQualifier(PopNameComponent(context));
// Push a pattern block for the signature (if any) of the next NameComponent.
// TODO: Instead use a separate parse node kind for an identifier that's
// followed by a pattern, and push a pattern block when handling it.
context.pattern_block_stack().Push();
return true;
}

Expand Down
9 changes: 2 additions & 7 deletions toolchain/check/handle_namespace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,12 @@ auto HandleParseNode(Context& context, Parse::NamespaceStartId /*node_id*/)
// Optional modifiers and the name follow.
context.decl_introducer_state_stack().Push<Lex::TokenKind::Namespace>();
context.decl_name_stack().PushScopeAndStartName();

// Push a pattern block to handle parameters of the namespace declaration.
// TODO: Disallow these in parse, instead of check, so we don't have to do
// this.
context.pattern_block_stack().Push();
return true;
}

auto HandleParseNode(Context& context, Parse::NamespaceId node_id) -> bool {
auto name_context = context.decl_name_stack().FinishName(
PopNameComponentWithoutParams(context, Lex::TokenKind::Namespace));
auto name_context =
context.decl_name_stack().FinishName(PopNameComponent(context));

auto introducer =
context.decl_introducer_state_stack().Pop<Lex::TokenKind::Namespace>();
Expand Down
2 changes: 1 addition & 1 deletion toolchain/check/inst_block_stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class InstBlockStack {

// Runs verification that the processing cleanly finished.
auto VerifyOnFinish() const -> void {
CARBON_CHECK(empty(), "{0}", id_stack_.size());
CARBON_CHECK(empty(), "{0} still has {1} entries", name_, id_stack_.size());
}

auto empty() const -> bool { return id_stack_.empty(); }
Expand Down
97 changes: 42 additions & 55 deletions toolchain/check/name_component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,76 +11,63 @@ namespace Carbon::Check {

auto PopNameComponent(Context& context, SemIR::InstId return_slot_pattern_id)
-> NameComponent {
Parse::NodeId first_param_node_id = Parse::InvalidNodeId();
Parse::NodeId last_param_node_id = Parse::InvalidNodeId();
NameComponent name_component = {
.name_loc_id = Parse::NodeId::Invalid,
.name_id = SemIR::NameId::Invalid,
.first_param_node_id = Parse::NodeId::Invalid,
.last_param_node_id = Parse::NodeId::Invalid,
.implicit_params_loc_id = Parse::NodeId::Invalid,
.implicit_param_patterns_id = SemIR::InstBlockId::Invalid,
.params_loc_id = Parse::NodeId::Invalid,
.param_patterns_id = SemIR::InstBlockId::Invalid,
.call_params_id = SemIR::InstBlockId::Invalid,
.return_slot_pattern_id = return_slot_pattern_id,
.pattern_block_id = SemIR::InstBlockId::Invalid,
};

// Explicit params.
auto [params_loc_id, param_patterns_id] =
context.node_stack().PopWithNodeIdIf<Parse::NodeKind::TuplePattern>();
if (param_patterns_id) {
first_param_node_id =
if (auto [params_loc_id, param_patterns_id] =
context.node_stack().PopWithNodeIdIf<Parse::NodeKind::TuplePattern>();
param_patterns_id) {
name_component.first_param_node_id =
context.node_stack()
.PopForSoloNodeId<Parse::NodeKind::TuplePatternStart>();
last_param_node_id = params_loc_id;
} else {
param_patterns_id = SemIR::InstBlockId::Invalid;
name_component.last_param_node_id = params_loc_id;
name_component.param_patterns_id = *param_patterns_id;
}

// Implicit params.
auto [implicit_params_loc_id, implicit_param_patterns_id] =
context.node_stack()
.PopWithNodeIdIf<Parse::NodeKind::ImplicitParamList>();
if (implicit_param_patterns_id) {
if (auto [implicit_params_loc_id, implicit_param_patterns_id] =
context.node_stack()
.PopWithNodeIdIf<Parse::NodeKind::ImplicitParamList>();
implicit_param_patterns_id) {
// Implicit params always come before explicit params.
first_param_node_id =
name_component.first_param_node_id =
context.node_stack()
.PopForSoloNodeId<Parse::NodeKind::ImplicitParamListStart>();
// Only use the end of implicit params if there weren't explicit params.
if (last_param_node_id.is_valid()) {
last_param_node_id = params_loc_id;
if (!name_component.last_param_node_id.is_valid()) {
name_component.last_param_node_id = implicit_params_loc_id;
}
} else {
implicit_param_patterns_id = SemIR::InstBlockId::Invalid;
name_component.implicit_param_patterns_id = *implicit_param_patterns_id;
}

auto call_params_id =
CalleePatternMatch(context, *implicit_param_patterns_id,
*param_patterns_id, return_slot_pattern_id);

auto [name_loc_id, name_id] = context.node_stack().PopNameWithNodeId();
return {
.name_loc_id = name_loc_id,
.name_id = name_id,
.first_param_node_id = first_param_node_id,
.last_param_node_id = last_param_node_id,
.implicit_params_loc_id = implicit_params_loc_id,
.implicit_param_patterns_id = *implicit_param_patterns_id,
.params_loc_id = params_loc_id,
.param_patterns_id = *param_patterns_id,
.call_params_id = call_params_id,
.return_slot_pattern_id = return_slot_pattern_id,
.pattern_block_id = context.pattern_block_stack().Pop(),
};
}

// Pop the name of a declaration from the node stack, and diagnose if it has
// parameters.
auto PopNameComponentWithoutParams(Context& context, Lex::TokenKind introducer)
-> NameComponent {
NameComponent name = PopNameComponent(context);
if (name.call_params_id.is_valid()) {
CARBON_DIAGNOSTIC(UnexpectedDeclNameParams, Error,
"`{0}` declaration cannot have parameters",
Lex::TokenKind);
// Point to the lexically first parameter list in the diagnostic.
context.emitter().Emit(name.implicit_param_patterns_id.is_valid()
? name.implicit_params_loc_id
: name.params_loc_id,
UnexpectedDeclNameParams, introducer);

name.call_params_id = SemIR::InstBlockId::Invalid;
if (name_component.param_patterns_id.is_valid() ||
name_component.implicit_param_patterns_id.is_valid()) {
std::tie(name_component.name_loc_id, name_component.name_id) =
context.node_stack()
.PopWithNodeId<Parse::NodeKind::IdentifierNameBeforeParams>();
name_component.call_params_id = CalleePatternMatch(
context, name_component.implicit_param_patterns_id,
name_component.param_patterns_id, return_slot_pattern_id);
name_component.pattern_block_id = context.pattern_block_stack().Pop();
} else {
std::tie(name_component.name_loc_id, name_component.name_id) =
context.node_stack()
.PopWithNodeId<Parse::NodeKind::IdentifierNameNotBeforeParams>();
}
return name;

return name_component;
}

} // namespace Carbon::Check
8 changes: 2 additions & 6 deletions toolchain/check/name_component.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,12 @@ struct NameComponent {
SemIR::InstBlockId pattern_block_id;
};

// Pop a name component from the node stack and pattern block stack.
// Pop a name component from the node stack (and pattern block stack, if it has
// parameters).
auto PopNameComponent(Context& context, SemIR::InstId return_slot_pattern_id =
SemIR::InstId::Invalid)
-> NameComponent;

// Pop the name of a declaration from the node stack and pattern block stack,
// and diagnose if it has parameters.
auto PopNameComponentWithoutParams(Context& context, Lex::TokenKind introducer)
-> NameComponent;

} // namespace Carbon::Check

#endif // CARBON_TOOLCHAIN_CHECK_NAME_COMPONENT_H_
6 changes: 4 additions & 2 deletions toolchain/check/node_stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,8 @@ class NodeStack {
case Parse::NodeKind::ForStatement:
case Parse::NodeKind::FunctionDecl:
case Parse::NodeKind::FunctionDefinition:
case Parse::NodeKind::IdentifierName:
case Parse::NodeKind::IdentifierNameNotBeforeParams:
case Parse::NodeKind::IdentifierNameBeforeParams:
case Parse::NodeKind::IdentifierNameExpr:
case Parse::NodeKind::IfConditionStart:
case Parse::NodeKind::IfExprElse:
Expand Down Expand Up @@ -594,7 +595,8 @@ class NodeStack {
case Parse::NodeKind::NamedConstraintDefinition:
case Parse::NodeKind::NamedConstraintDefinitionStart:
case Parse::NodeKind::NamedConstraintIntroducer:
case Parse::NodeKind::NameQualifier:
case Parse::NodeKind::NameQualifierWithParams:
case Parse::NodeKind::NameQualifierWithoutParams:
case Parse::NodeKind::Namespace:
case Parse::NodeKind::NamespaceStart:
case Parse::NodeKind::PackageDecl:
Expand Down
37 changes: 0 additions & 37 deletions toolchain/check/testdata/alias/no_prelude/fail_params.carbon

This file was deleted.

Loading
Loading