1010#include " toolchain/check/generic.h"
1111#include " toolchain/check/handle.h"
1212#include " toolchain/check/inst.h"
13+ #include " toolchain/check/interface.h"
1314#include " toolchain/check/merge.h"
1415#include " toolchain/check/modifiers.h"
1516#include " toolchain/check/name_component.h"
1617#include " toolchain/check/name_lookup.h"
1718#include " toolchain/check/type.h"
19+ #include " toolchain/sem_ir/entity_with_params_base.h"
20+ #include " toolchain/sem_ir/ids.h"
21+ #include " toolchain/sem_ir/interface.h"
1822#include " toolchain/sem_ir/typed_insts.h"
1923
2024namespace Carbon ::Check {
@@ -26,11 +30,12 @@ auto HandleParseNode(Context& context, Parse::InterfaceIntroducerId node_id)
2630 // Create an instruction block to hold the instructions created as part of the
2731 // interface signature, such as generic parameters.
2832 context.inst_block_stack ().Push ();
29- // Push the bracketing node.
30- context.node_stack ().Push (node_id);
3133 // Optional modifiers and the name follow.
3234 context.decl_introducer_state_stack ().Push <Lex::TokenKind::Interface>();
3335 context.decl_name_stack ().PushScopeAndStartName ();
36+
37+ // Push the bracketing node.
38+ context.node_stack ().Push (node_id);
3439 return true ;
3540}
3641
@@ -56,87 +61,44 @@ static auto BuildInterfaceDecl(Context& context,
5661 // Add the interface declaration.
5762 auto interface_decl = SemIR::InterfaceDecl{
5863 SemIR::TypeType::TypeId, SemIR::InterfaceId::None, decl_block_id};
59- auto interface_decl_id = AddPlaceholderInst (context, node_id, interface_decl);
64+ auto decl_inst_id = AddPlaceholderInst (context, node_id, interface_decl);
6065
6166 SemIR::Interface interface_info = {name_context.MakeEntityWithParamsBase (
62- name, interface_decl_id, /* is_extern=*/ false ,
63- SemIR::LibraryNameId::None)};
67+ name, decl_inst_id, /* is_extern=*/ false , SemIR::LibraryNameId::None)};
6468
6569 DiagnoseIfGenericMissingExplicitParameters (context, interface_info);
6670
6771 // Check whether this is a redeclaration.
6872 SemIR::ScopeLookupResult lookup_result =
6973 context.decl_name_stack ().LookupOrAddName (
70- name_context, interface_decl_id,
71- introducer.modifier_set .GetAccessKind ());
72- if (lookup_result.is_poisoned ()) {
73- // This is a declaration of a poisoned name.
74- DiagnosePoisonedName (context, name_context.name_id_for_new_inst (),
75- lookup_result.poisoning_loc_id (), name_context.loc_id );
76- } else if (lookup_result.is_found ()) {
77- SemIR::InstId existing_id = lookup_result.target_inst_id ();
78- if (auto existing_interface_decl =
79- context.insts ().Get (existing_id).TryAs <SemIR::InterfaceDecl>()) {
80- auto existing_interface =
81- context.interfaces ().Get (existing_interface_decl->interface_id );
82- if (CheckRedeclParamsMatch (
83- context,
84- DeclParams (SemIR::LocId (interface_decl_id),
85- name.first_param_node_id , name.last_param_node_id ,
86- name.implicit_param_patterns_id ,
87- name.param_patterns_id ),
88- DeclParams (existing_interface))) {
89- // TODO: This should be refactored a little, particularly for
90- // prev_import_ir_id. See similar logic for classes and functions, which
91- // might also be refactored to merge.
92- DiagnoseIfInvalidRedecl (
93- context, Lex::TokenKind::Interface, existing_interface.name_id ,
94- RedeclInfo (interface_info, node_id, is_definition),
95- RedeclInfo (existing_interface,
96- SemIR::LocId (existing_interface.latest_decl_id ()),
97- existing_interface.has_definition_started ()),
98- /* prev_import_ir_id=*/ SemIR::ImportIRId::None);
99-
100- // Can't merge interface definitions due to the generic requirements.
101- if (!is_definition || !existing_interface.has_definition_started ()) {
102- // This is a redeclaration of an existing interface.
103- interface_decl.interface_id = existing_interface_decl->interface_id ;
104- interface_decl.type_id = existing_interface_decl->type_id ;
105- // TODO: If the new declaration is a definition, keep its parameter
106- // and implicit parameter lists rather than the ones from the
107- // previous declaration.
108- }
109- }
110- } else {
111- // This is a redeclaration of something other than a interface.
112- DiagnoseDuplicateName (context, name_context.name_id , name_context.loc_id ,
113- SemIR::LocId (existing_id));
114- }
115- }
74+ name_context, decl_inst_id, introducer.modifier_set .GetAccessKind ());
75+ if (auto existing_decl = TryGetExistingDecl (context, name, lookup_result,
76+ interface_info, is_definition)) {
77+ auto existing_interface_decl = existing_decl->As <SemIR::InterfaceDecl>();
78+ interface_decl.interface_id = existing_interface_decl.interface_id ;
79+ interface_decl.type_id = existing_interface_decl.type_id ;
80+ // TODO: If the new declaration is a definition, keep its parameter
81+ // and implicit parameter lists rather than the ones from the
82+ // previous declaration.
11683
117- // Create a new interface if this isn't a valid redeclaration.
118- if (!interface_decl.interface_id .has_value ()) {
119- // TODO: If this is an invalid redeclaration of a non-interface entity or
120- // there was an error in the qualifier, we will have lost track of the
121- // interface name here. We should keep track of it even if the name is
122- // invalid.
123- interface_info.generic_id = BuildGenericDecl (context, interface_decl_id);
84+ auto prev_decl_generic_id =
85+ context.interfaces ().Get (interface_decl.interface_id ).generic_id ;
86+ FinishGenericRedecl (context, prev_decl_generic_id);
87+ } else {
88+ // Create a new interface if this isn't a valid redeclaration.
89+ interface_info.generic_id = BuildGenericDecl (context, decl_inst_id);
12490 interface_decl.interface_id = context.interfaces ().Add (interface_info);
12591 if (interface_info.has_parameters ()) {
12692 interface_decl.type_id =
12793 GetGenericInterfaceType (context, interface_decl.interface_id ,
12894 context.scope_stack ().PeekSpecificId ());
12995 }
130- } else {
131- auto prev_decl_generic_id =
132- context.interfaces ().Get (interface_decl.interface_id ).generic_id ;
133- FinishGenericRedecl (context, prev_decl_generic_id);
13496 }
13597
13698 // Write the interface ID into the InterfaceDecl.
137- ReplaceInstBeforeConstantUse (context, interface_decl_id , interface_decl);
99+ ReplaceInstBeforeConstantUse (context, decl_inst_id , interface_decl);
138100
139- return {interface_decl.interface_id , interface_decl_id };
101+ return {interface_decl.interface_id , decl_inst_id };
140102}
141103
142104auto HandleParseNode (Context& context, Parse::InterfaceDeclId node_id) -> bool {
@@ -147,16 +109,16 @@ auto HandleParseNode(Context& context, Parse::InterfaceDeclId node_id) -> bool {
147109
148110auto HandleParseNode (Context& context,
149111 Parse::InterfaceDefinitionStartId node_id) -> bool {
150- auto [interface_id, interface_decl_id ] =
112+ auto [interface_id, decl_inst_id ] =
151113 BuildInterfaceDecl (context, node_id, /* is_definition=*/ true );
152114 auto & interface_info = context.interfaces ().Get (interface_id);
153115
154116 // Track that this declaration is the definition.
155117 CARBON_CHECK (!interface_info.has_definition_started (),
156118 " Can't merge with defined interfaces." );
157- interface_info.definition_id = interface_decl_id ;
119+ interface_info.definition_id = decl_inst_id ;
158120 interface_info.scope_id = context.name_scopes ().Add (
159- interface_decl_id , SemIR::NameId::None, interface_info.parent_scope_id );
121+ decl_inst_id , SemIR::NameId::None, interface_info.parent_scope_id );
160122 context.name_scopes ()
161123 .Get (interface_info.scope_id )
162124 .set_is_interface_definition ();
@@ -167,35 +129,21 @@ auto HandleParseNode(Context& context,
167129 StartGenericDefinition (context, interface_info.generic_id );
168130
169131 context.inst_block_stack ().Push ();
170- context.node_stack ().Push (node_id, interface_id);
171132
172133 // We use the arg stack to build the witness table type.
173134 context.args_type_info_stack ().Push ();
174135
175- // Declare and introduce `Self`.
136+ // Declare and introduce `Self`. We model `Self` as a symbolic binding whose
137+ // type is the interface, excluding any other interfaces mentioned by
138+ // `require` declarations.
176139 SemIR::TypeId self_type_id =
177140 GetInterfaceType (context, interface_id, self_specific_id);
178-
179- // We model `Self` as a symbolic binding whose type is the interface.
180- // Because there is no equivalent non-symbolic value, we use `None` as
181- // the `value_id` on the `BindSymbolicName`.
182- auto entity_name_id = context.entity_names ().AddSymbolicBindingName (
183- SemIR::NameId::SelfType, interface_info.scope_id ,
184- context.scope_stack ().AddCompileTimeBinding (),
185- /* is_template=*/ false );
186- interface_info.self_param_id =
187- AddInst (context, SemIR::LocIdAndInst::NoLoc<SemIR::BindSymbolicName>(
188- {.type_id = self_type_id,
189- .entity_name_id = entity_name_id,
190- .value_id = SemIR::InstId::None}));
191- context.scope_stack ().PushCompileTimeBinding (interface_info.self_param_id );
192- context.name_scopes ().AddRequiredName (interface_info.scope_id ,
193- SemIR::NameId::SelfType,
194- interface_info.self_param_id );
141+ interface_info.self_param_id = AddSelfGenericParameter (
142+ context, self_type_id, interface_info.scope_id , /* is_template=*/ false );
195143
196144 // Enter the interface scope.
197- context.scope_stack ().PushForEntity (
198- interface_decl_id, interface_info. scope_id , self_specific_id);
145+ context.scope_stack ().PushForEntity (decl_inst_id, interface_info. scope_id ,
146+ self_specific_id);
199147
200148 // TODO: Handle the case where there's control flow in the interface body. For
201149 // example:
@@ -207,6 +155,8 @@ auto HandleParseNode(Context& context,
207155 // We may need to track a list of instruction blocks here, as we do for a
208156 // function.
209157 interface_info.body_block_id = context.inst_block_stack ().PeekOrAdd ();
158+
159+ context.node_stack ().Push (node_id, interface_id);
210160 return true ;
211161}
212162
0 commit comments