Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change tuple indexing #4186

Closed
Closed
Changes from 1 commit
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
0babda5
docs: add a note on setting up `clangd`
brymer-meneses Jul 15, 2024
db6b327
docs: add a note on setting up `clangd`
brymer-meneses Jul 15, 2024
8aa7919
apply suggestions
brymer-meneses Jul 24, 2024
67b6fd3
forgot a semicolon
brymer-meneses Jul 24, 2024
d2f8972
Compute specific constant values. (#4128)
zygoloid Jul 15, 2024
e946c68
Build an evaluation block for the definition region of a generic. (#4…
zygoloid Jul 16, 2024
ccf1275
Rebuild the type of constants during evaluation. (#4138)
zygoloid Jul 16, 2024
d2c1ae1
Add basic output of where memory is stored after a compile. (#4136)
jonmeow Jul 16, 2024
dc64f41
Do not query interface's self_param_id unless defined when importing …
gysddn Jul 16, 2024
0ca907f
Substitute into generic class and interface definitions when we requi…
zygoloid Jul 17, 2024
e0a8d38
Enable the more effective version of `-Wnon-virtual-dtor`. (#4142)
chandlerc Jul 17, 2024
9689e8d
Directly use TCMalloc rather than the system malloc on Linux. (#4133)
chandlerc Jul 17, 2024
f7b1793
Mark some leaf classes `final` to suppress `-Wnon-virtual-dtor`. (#4141)
zygoloid Jul 17, 2024
b296b1d
Use verbose formatting of instructions on crash messages. (#4125)
jonmeow Jul 17, 2024
0dd2294
Change TypeId to be a thin wrapper around ConstantId. (#4140)
zygoloid Jul 17, 2024
74b52e4
Move `GetTypeInInstance` from `Check` to `SemIR`. (#4144)
zygoloid Jul 17, 2024
950e614
Basic testing for generic methods using `Self`. (#4143)
zygoloid Jul 17, 2024
f14a639
Reserve memory for the identifiers hashtable. (#4107)
chandlerc Jul 18, 2024
edf8d8e
Abbreviate instruction as inst in formatter. (#4146)
jonmeow Jul 18, 2024
ff8c302
Try some crash recovery in autoupdate threads. (#4147)
jonmeow Jul 18, 2024
842f226
Remove irregular digit placement check from NumericLiteral. (#4150)
jonmeow Jul 19, 2024
bad5230
Rename BindNameInfo to EntityName (#4090)
geoffromer Jul 19, 2024
ad15a59
Remove declaration of function deleted in #4150. (#4151)
zygoloid Jul 22, 2024
f83be0f
Remove already-done no_prelude todo. (#4148)
jonmeow Jul 22, 2024
2ccab8d
Use the package/library name in ImportIRId formatting. (#4154)
jonmeow Jul 22, 2024
daf818b
Implement syntactic merge checks for parameters. (#4149)
jonmeow Jul 23, 2024
83840c4
Rebuild all constants in the eval block. (#4155)
zygoloid Jul 23, 2024
fc9b02f
Remove overeager CHECK. (#4159)
zygoloid Jul 23, 2024
bd7e739
Convert `EvalContext` into a class. (#4160)
zygoloid Jul 24, 2024
1ca3a1d
Add a mention of our nightly builds to our `README.md`. (#4158)
chandlerc Jul 24, 2024
e62c509
Improve namespace handling in imports. (#4153)
jonmeow Jul 24, 2024
a4501ad
Support for calling non-generic methods in a specific class. (#4156)
zygoloid Jul 24, 2024
45d2adf
When reentering an interface scope, reintroduce the `Self` parameter.…
zygoloid Jul 24, 2024
0285842
Move common entity fields to a 'base' struct. (#4161)
jonmeow Jul 24, 2024
67a26f3
Rename "generic instance" to "specific" throughout the toolchain. (#4…
zygoloid Jul 25, 2024
bd793e5
fix: `clangd: -32001: invalid AST` (#4164)
brymer-meneses Jul 25, 2024
e0f5e68
Remove caching of return slot usage. (#4163)
zygoloid Jul 25, 2024
59aa658
Improve notes on MODULE.bazel.lock changes (#4167)
jonmeow Jul 25, 2024
b09343b
Only produce a name scope for a namespace when not merged (#4168)
jonmeow Jul 25, 2024
a71d033
Move definition of member of Function to function.cpp where it belong…
zygoloid Jul 25, 2024
5b96d7e
Refactor `ReturnTypeInfo` and `InitRepr`. (#4169)
zygoloid Jul 25, 2024
e8545fa
Add initial parsing for 'extern library' (#4173)
jonmeow Jul 26, 2024
123cbc2
Refactor some commonality in formatter. (#4171)
jonmeow Jul 26, 2024
e231a56
Refactor some check-phase postorder iterator use. (#4175)
jonmeow Jul 27, 2024
657f16b
Temporarily disable tcmalloc due to compiler-explorer crash (#4177)
jonmeow Jul 29, 2024
08b1fd8
Fix incorrect `value_id` and location in imported `BindSymbolicName`.…
zygoloid Jul 31, 2024
b54e1a2
Separate subtree size information from parse nodes. (#4174)
jonmeow Jul 31, 2024
65fc345
Import support for generics and specifics (#4179)
zygoloid Jul 31, 2024
5700d1d
When importing symbolic constants and types, also import the associat…
zygoloid Aug 1, 2024
11e3c77
Remove supurfluous/confusing {} around a temporary (#4183)
dwblaikie Aug 1, 2024
32f3191
Initial rough support for deducing generic arguments in a call to a g…
zygoloid Aug 2, 2024
da45ace
change tuple indexing
brymer-meneses Aug 3, 2024
3ec9382
remove unused header
brymer-meneses Aug 3, 2024
07c96f4
update forgotten tests
brymer-meneses Aug 3, 2024
53e7902
Update toolchain/check/handle_name.cpp
brymer-meneses Aug 6, 2024
8626e5d
Update toolchain/check/handle_name.cpp
brymer-meneses Aug 6, 2024
1332dd2
Update toolchain/check/member_access.cpp
brymer-meneses Aug 6, 2024
c5884f3
Update toolchain/parse/handle_period.cpp
brymer-meneses Aug 6, 2024
8bd014d
Update toolchain/check/member_access.cpp
brymer-meneses Aug 6, 2024
e83f6cf
Update toolchain/lower/testdata/index/tuple_return_value_access.carbon
brymer-meneses Aug 6, 2024
2575124
handle tuple indexing of paren expressions
brymer-meneses Aug 6, 2024
3dcaff0
update tests
brymer-meneses Aug 6, 2024
d4ebcb4
add `fail_non_tuple_index.carbon`
brymer-meneses Aug 6, 2024
f9247c3
add comment to `PerformTupleIndex`
brymer-meneses Aug 8, 2024
a52081b
add missing comments
brymer-meneses Aug 8, 2024
ab7d674
refactor toolchain/check/member_access.cpp
brymer-meneses Aug 8, 2024
eae1ba0
move `IntLiteral`
brymer-meneses Aug 8, 2024
c2e773d
Update toolchain/check/member_access.cpp
brymer-meneses Aug 8, 2024
28e9114
apply suggestion
brymer-meneses Aug 8, 2024
a8a4c6a
apply suggestion
brymer-meneses Aug 14, 2024
91ceae5
consolidate `tuples/fail_non_tuple_index.carbon` with `tuples/index/f…
brymer-meneses Aug 14, 2024
ec26bec
Update toolchain/lower/testdata/index/array_element_access.carbon
brymer-meneses Aug 14, 2024
e54d9e1
apply test changes
brymer-meneses Aug 14, 2024
4209a32
add tuple negative indexing
brymer-meneses Aug 14, 2024
ad13f30
testdata changes
brymer-meneses Aug 14, 2024
56ec41f
testdata changes
brymer-meneses Aug 14, 2024
91d3545
testdata changes
brymer-meneses Aug 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Implement syntactic merge checks for parameters. (#4149)
Note this isn't implementing checking through imports. The parse node
there is harder to access through the context, so would require
examining the entity in order to get the import declaration, to get at
the ImportIR. We also don't have a parse tree attached in that case, and
would need to add one to SemIR::File. But I believe we do want to add
that, so it's explicitly a TODO.

Note GetTokenText re-lexes literal values, so there's a bit of potential
overhead there. Not sure if we want a more efficient manner for
comparing in cases like this.
  • Loading branch information
jonmeow authored and brymer-meneses committed Aug 15, 2024
commit daf818b68cf065f1cf575f00f6fec937e9cc232a
14 changes: 8 additions & 6 deletions toolchain/check/decl_name_stack.cpp
Original file line number Diff line number Diff line change
@@ -366,8 +366,9 @@ auto DeclNameStack::ResolveAsScope(const NameContext& name_context,
return InvalidResult;
}

auto new_params =
DeclParams(name.name_loc_id, name.implicit_params_id, name.params_id);
auto new_params = DeclParams(name.name_loc_id, name.first_param_node_id,
name.last_param_node_id, name.implicit_params_id,
name.params_id);

// Find the scope corresponding to the resolved instruction.
CARBON_KIND_SWITCH(context_->insts().Get(name_context.resolved_inst_id)) {
@@ -404,10 +405,11 @@ auto DeclNameStack::ResolveAsScope(const NameContext& name_context,
case CARBON_KIND(SemIR::Namespace resolved_inst): {
auto scope_id = resolved_inst.name_scope_id;
auto& scope = context_->name_scopes().Get(scope_id);
if (!CheckRedeclParamsMatch(*context_, new_params,
DeclParams(name_context.resolved_inst_id,
SemIR::InstBlockId::Invalid,
SemIR::InstBlockId::Invalid))) {
if (!CheckRedeclParamsMatch(
*context_, new_params,
DeclParams(name_context.resolved_inst_id, Parse::NodeId::Invalid,
Parse::NodeId::Invalid, SemIR::InstBlockId::Invalid,
SemIR::InstBlockId::Invalid))) {
return InvalidResult;
}
if (scope.is_closed_import) {
6 changes: 4 additions & 2 deletions toolchain/check/function.cpp
Original file line number Diff line number Diff line change
@@ -13,9 +13,11 @@ namespace Carbon::Check {
auto CheckFunctionTypeMatches(Context& context,
const SemIR::Function& new_function,
const SemIR::Function& prev_function,
Substitutions substitutions) -> bool {
Substitutions substitutions, bool check_syntax)
-> bool {
if (!CheckRedeclParamsMatch(context, DeclParams(new_function),
DeclParams(prev_function), substitutions)) {
DeclParams(prev_function), substitutions,
check_syntax)) {
return false;
}

5 changes: 2 additions & 3 deletions toolchain/check/function.h
Original file line number Diff line number Diff line change
@@ -29,12 +29,11 @@ struct SuspendedFunction {
// Checks that `new_function` has the same parameter types and return type as
// `prev_function`, applying the specified set of substitutions to the
// previous function. Prints a suitable diagnostic and returns false if not.
// Note that this doesn't include the syntactic check that's performed for
// redeclarations.
auto CheckFunctionTypeMatches(Context& context,
const SemIR::Function& new_function,
const SemIR::Function& prev_function,
Substitutions substitutions) -> bool;
Substitutions substitutions, bool check_syntax)
-> bool;

// Checks that the return type of the specified function is complete, issuing an
// error if not. This computes the return slot usage for the function if
2 changes: 2 additions & 0 deletions toolchain/check/global_init.cpp
Original file line number Diff line number Diff line change
@@ -39,6 +39,8 @@ auto GlobalInit::Finalize() -> void {
.parent_scope_id = SemIR::NameScopeId::Package,
.decl_id = SemIR::InstId::Invalid,
.generic_id = SemIR::GenericId::Invalid,
.first_param_node_id = Parse::NodeId::Invalid,
.last_param_node_id = Parse::NodeId::Invalid,
.implicit_param_refs_id = SemIR::InstBlockId::Invalid,
.param_refs_id = SemIR::InstBlockId::Empty,
.return_storage_id = SemIR::InstId::Invalid,
4 changes: 4 additions & 0 deletions toolchain/check/handle_class.cpp
Original file line number Diff line number Diff line change
@@ -93,6 +93,8 @@ static auto MergeClassRedecl(Context& context, SemIRLoc new_loc,
}

if (new_is_definition) {
prev_class.first_param_node_id = new_class.first_param_node_id;
prev_class.last_param_node_id = new_class.last_param_node_id;
prev_class.implicit_param_refs_id = new_class.implicit_param_refs_id;
prev_class.param_refs_id = new_class.param_refs_id;
prev_class.definition_id = new_class.definition_id;
@@ -225,6 +227,8 @@ static auto BuildClassDecl(Context& context, Parse::AnyClassDeclId node_id,
.name_id = name_context.name_id_for_new_inst(),
.parent_scope_id = name_context.parent_scope_id_for_new_inst(),
.generic_id = SemIR::GenericId::Invalid,
.first_param_node_id = name.first_param_node_id,
.last_param_node_id = name.last_param_node_id,
.implicit_param_refs_id = name.implicit_params_id,
.param_refs_id = name.params_id,
// `.self_type_id` depends on the ClassType, so is set below.
7 changes: 6 additions & 1 deletion toolchain/check/handle_function.cpp
Original file line number Diff line number Diff line change
@@ -99,7 +99,8 @@ static auto MergeFunctionRedecl(Context& context, SemIRLoc new_loc,
SemIR::ImportIRId prev_import_ir_id) -> bool {
auto& prev_function = context.functions().Get(prev_function_id);

if (!CheckFunctionTypeMatches(context, new_function, prev_function, {})) {
if (!CheckFunctionTypeMatches(context, new_function, prev_function, {},
/*check_syntax=*/true)) {
return false;
}

@@ -118,6 +119,8 @@ static auto MergeFunctionRedecl(Context& context, SemIRLoc new_loc,
// Track the signature from the definition, so that IDs in the body
// match IDs in the signature.
prev_function.definition_id = new_function.definition_id;
prev_function.first_param_node_id = new_function.first_param_node_id;
prev_function.last_param_node_id = new_function.last_param_node_id;
prev_function.implicit_param_refs_id = new_function.implicit_param_refs_id;
prev_function.param_refs_id = new_function.param_refs_id;
prev_function.return_storage_id = new_function.return_storage_id;
@@ -252,6 +255,8 @@ static auto BuildFunctionDecl(Context& context,
.parent_scope_id = name_context.parent_scope_id_for_new_inst(),
.decl_id = decl_id,
.generic_id = SemIR::GenericId::Invalid,
.first_param_node_id = name.first_param_node_id,
.last_param_node_id = name.last_param_node_id,
.implicit_param_refs_id = name.implicit_params_id,
.param_refs_id = name.params_id,
.return_storage_id = return_storage_id,
2 changes: 2 additions & 0 deletions toolchain/check/handle_impl.cpp
Original file line number Diff line number Diff line change
@@ -36,6 +36,8 @@ auto HandleParseNode(Context& context, Parse::ImplIntroducerId node_id)
auto HandleParseNode(Context& context, Parse::ImplForallId node_id) -> bool {
auto params_id =
context.node_stack().Pop<Parse::NodeKind::ImplicitParamList>();
context.node_stack()
.PopAndDiscardSoloNodeId<Parse::NodeKind::ImplicitParamListStart>();
context.node_stack().Push(node_id, params_id);
return true;
}
5 changes: 4 additions & 1 deletion toolchain/check/handle_interface.cpp
Original file line number Diff line number Diff line change
@@ -62,7 +62,8 @@ static auto BuildInterfaceDecl(Context& context,
// now we just check the generic parameters match.
if (CheckRedeclParamsMatch(
context,
DeclParams(interface_decl_id, name.implicit_params_id,
DeclParams(interface_decl_id, name.first_param_node_id,
name.last_param_node_id, name.implicit_params_id,
name.params_id),
DeclParams(context.interfaces().Get(
existing_interface_decl->interface_id)))) {
@@ -90,6 +91,8 @@ static auto BuildInterfaceDecl(Context& context,
.name_id = name_context.name_id_for_new_inst(),
.parent_scope_id = name_context.parent_scope_id_for_new_inst(),
.generic_id = generic_id,
.first_param_node_id = name.first_param_node_id,
.last_param_node_id = name.last_param_node_id,
.implicit_param_refs_id = name.implicit_params_id,
.param_refs_id = name.params_id,
.decl_id = interface_decl_id};
8 changes: 4 additions & 4 deletions toolchain/check/handle_pattern_list.cpp
Original file line number Diff line number Diff line change
@@ -16,10 +16,10 @@ auto HandleParseNode(Context& context, Parse::ImplicitParamListStartId node_id)

auto HandleParseNode(Context& context, Parse::ImplicitParamListId node_id)
-> bool {
// Note the Start node remains on the stack, where the param list handler can
// make use of it.
auto refs_id = context.param_and_arg_refs_stack().EndAndPop(
Parse::NodeKind::ImplicitParamListStart);
context.node_stack()
.PopAndDiscardSoloNodeId<Parse::NodeKind::ImplicitParamListStart>();
context.node_stack().Push(node_id, refs_id);
// The implicit parameter list's scope extends to the end of the following
// parameter list.
@@ -40,10 +40,10 @@ auto HandleParseNode(Context& context, Parse::PatternListCommaId /*node_id*/)
}

auto HandleParseNode(Context& context, Parse::TuplePatternId node_id) -> bool {
// Note the Start node remains on the stack, where the param list handler can
// make use of it.
auto refs_id = context.param_and_arg_refs_stack().EndAndPop(
Parse::NodeKind::TuplePatternStart);
context.node_stack()
.PopAndDiscardSoloNodeId<Parse::NodeKind::TuplePatternStart>();
context.node_stack().Push(node_id, refs_id);
return true;
}
3 changes: 2 additions & 1 deletion toolchain/check/impl.cpp
Original file line number Diff line number Diff line change
@@ -54,7 +54,8 @@ static auto CheckAssociatedFunctionImplementation(
// synthesize a suitable thunk.
if (!CheckFunctionTypeMatches(
context, context.functions().Get(impl_function_decl->function_id),
context.functions().Get(interface_function_id), substitutions)) {
context.functions().Get(interface_function_id), substitutions,
/*check_syntax=*/false)) {
return SemIR::InstId::BuiltinError;
}
return impl_decl_id;
6 changes: 6 additions & 0 deletions toolchain/check/import_ref.cpp
Original file line number Diff line number Diff line change
@@ -909,6 +909,8 @@ class ImportRefResolver {
// importing the parameters.
.parent_scope_id = SemIR::NameScopeId::Invalid,
.generic_id = generic_id,
.first_param_node_id = Parse::NodeId::Invalid,
.last_param_node_id = Parse::NodeId::Invalid,
.implicit_param_refs_id = import_class.implicit_param_refs_id.is_valid()
? SemIR::InstBlockId::Empty
: SemIR::InstBlockId::Invalid,
@@ -1143,6 +1145,8 @@ class ImportRefResolver {
.parent_scope_id = parent_scope_id,
.decl_id = function_decl_id,
.generic_id = generic_id,
.first_param_node_id = Parse::NodeId::Invalid,
.last_param_node_id = Parse::NodeId::Invalid,
.implicit_param_refs_id = GetLocalParamRefsId(
function.implicit_param_refs_id, implicit_param_const_ids),
.param_refs_id =
@@ -1249,6 +1253,8 @@ class ImportRefResolver {
// importing the parameters.
.parent_scope_id = SemIR::NameScopeId::Invalid,
.generic_id = generic_id,
.first_param_node_id = Parse::NodeId::Invalid,
.last_param_node_id = Parse::NodeId::Invalid,
.implicit_param_refs_id =
import_interface.implicit_param_refs_id.is_valid()
? SemIR::InstBlockId::Empty
85 changes: 82 additions & 3 deletions toolchain/check/merge.cpp
Original file line number Diff line number Diff line change
@@ -268,22 +268,101 @@ static auto CheckRedeclParams(Context& context, SemIRLoc new_decl_loc,
return true;
}

// Returns true if the two nodes represent the same syntax.
// TODO: Detect raw identifiers (will require token changes).
static auto IsNodeSyntaxEqual(Context& context, Parse::NodeId new_node_id,
Parse::NodeId prev_node_id) -> bool {
if (context.parse_tree().node_kind(new_node_id) !=
context.parse_tree().node_kind(prev_node_id)) {
return false;
}

// TODO: Should there be a trivial way to check if we need to check spellings?
// Identifiers and literals need their text checked for cross-file matching,
// but not intra-file. Keywords and operators shouldn't need the token text
// examined at all.
auto new_spelling = context.tokens().GetTokenText(
context.parse_tree().node_token(new_node_id));
auto prev_spelling = context.tokens().GetTokenText(
context.parse_tree().node_token(prev_node_id));
return new_spelling == prev_spelling;
}

// Returns false if redeclaration parameter syntax doesn't match.
static auto CheckRedeclParamSyntax(Context& context,
Parse::NodeId new_first_param_node_id,
Parse::NodeId new_last_param_node_id,
Parse::NodeId prev_first_param_node_id,
Parse::NodeId prev_last_param_node_id)
-> bool {
// Parse nodes may not always be available to compare.
// TODO: Support cross-file syntax checks. Right now imports provide invalid
// nodes, and we'll need to follow the declaration to its original file to
// get the parse tree.
if (!new_first_param_node_id.is_valid() ||
!prev_first_param_node_id.is_valid()) {
return true;
}
CARBON_CHECK(new_last_param_node_id.is_valid())
<< "new_last_param_node_id.is_valid should match "
"new_first_param_node_id.is_valid";
CARBON_CHECK(prev_last_param_node_id.is_valid())
<< "prev_last_param_node_id.is_valid should match "
"prev_first_param_node_id.is_valid";

auto new_range = context.parse_tree().postorder(new_first_param_node_id,
new_last_param_node_id);
auto prev_range = context.parse_tree().postorder(prev_first_param_node_id,
prev_last_param_node_id);

// zip is using the shortest range. If they differ in length, there should be
// some difference inside the range because the range includes parameter
// brackets. As a consequence, we don't explicitly handle different range
// sizes here.
for (auto [new_node_id, prev_node_id] : llvm::zip(new_range, prev_range)) {
if (!IsNodeSyntaxEqual(context, new_node_id, prev_node_id)) {
CARBON_DIAGNOSTIC(RedeclParamSyntaxDiffers, Error,
"Redeclaration syntax differs here.");
CARBON_DIAGNOSTIC(RedeclParamSyntaxPrevious, Note,
"Comparing with previous declaration here.");
context.emitter()
.Build(new_node_id, RedeclParamSyntaxDiffers)
.Note(prev_node_id, RedeclParamSyntaxPrevious)
.Emit();

return false;
}
}

return true;
}

auto CheckRedeclParamsMatch(Context& context, const DeclParams& new_entity,
const DeclParams& prev_entity,
Substitutions substitutions) -> bool {
Substitutions substitutions, bool check_syntax)
-> bool {
if (EntityHasParamError(context, new_entity) ||
EntityHasParamError(context, prev_entity)) {
return false;
}
if (!CheckRedeclParams(context, new_entity.loc,
new_entity.implicit_param_refs_id, prev_entity.loc,
prev_entity.implicit_param_refs_id, "implicit ",
substitutions) ||
!CheckRedeclParams(context, new_entity.loc, new_entity.param_refs_id,
substitutions)) {
return false;
}
if (!CheckRedeclParams(context, new_entity.loc, new_entity.param_refs_id,
prev_entity.loc, prev_entity.param_refs_id, "",
substitutions)) {
return false;
}
if (check_syntax &&
!CheckRedeclParamSyntax(context, new_entity.first_param_node_id,
new_entity.last_param_node_id,
prev_entity.first_param_node_id,
prev_entity.last_param_node_id)) {
return false;
}
return true;
}

19 changes: 16 additions & 3 deletions toolchain/check/merge.h
Original file line number Diff line number Diff line change
@@ -47,17 +47,30 @@ struct DeclParams {
template <typename Entity>
explicit DeclParams(const Entity& entity)
: loc(entity.decl_id),
first_param_node_id(entity.first_param_node_id),
last_param_node_id(entity.last_param_node_id),
implicit_param_refs_id(entity.implicit_param_refs_id),
param_refs_id(entity.param_refs_id) {}

DeclParams(SemIRLoc loc, SemIR::InstBlockId implicit_params_id,
DeclParams(SemIRLoc loc, Parse::NodeId first_param_node_id,
Parse::NodeId last_param_node_id,
SemIR::InstBlockId implicit_params_id,
SemIR::InstBlockId params_id)
: loc(loc),
first_param_node_id(first_param_node_id),
last_param_node_id(last_param_node_id),
implicit_param_refs_id(implicit_params_id),
param_refs_id(params_id) {}

// The location of the declaration of the entity.
SemIRLoc loc;

// Parse tree bounds for the parameters, including both implicit and explicit
// parameters. These will be compared to match between declaration and
// definition.
Parse::NodeId first_param_node_id;
Parse::NodeId last_param_node_id;

// The implicit parameters of the entity. Can be Invalid if there is no
// implicit parameter list.
SemIR::InstBlockId implicit_param_refs_id;
@@ -71,8 +84,8 @@ struct DeclParams {
// returns false.
auto CheckRedeclParamsMatch(Context& context, const DeclParams& new_entity,
const DeclParams& prev_entity,
Substitutions substitutions = Substitutions())
-> bool;
Substitutions substitutions = Substitutions(),
bool check_syntax = true) -> bool;

} // namespace Carbon::Check

25 changes: 25 additions & 0 deletions toolchain/check/name_component.cpp
Original file line number Diff line number Diff line change
@@ -9,15 +9,40 @@
namespace Carbon::Check {

auto PopNameComponent(Context& context) -> NameComponent {
Parse::NodeId first_param_node_id = Parse::InvalidNodeId();
Parse::NodeId last_param_node_id = Parse::InvalidNodeId();

// Explicit params.
auto [params_loc_id, params_id] =
context.node_stack().PopWithNodeIdIf<Parse::NodeKind::TuplePattern>();
if (params_id) {
first_param_node_id =
context.node_stack()
.PopForSoloNodeId<Parse::NodeKind::TuplePatternStart>();
last_param_node_id = params_loc_id;
}

// Implicit params.
auto [implicit_params_loc_id, implicit_params_id] =
context.node_stack()
.PopWithNodeIdIf<Parse::NodeKind::ImplicitParamList>();
if (implicit_params_id) {
// Implicit params always come before explicit params.
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;
}
}

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_params_id =
implicit_params_id.value_or(SemIR::InstBlockId::Invalid),
Loading