@@ -84,29 +84,37 @@ static auto ForEachRequireImpls(
8484 }
8585}
8686
87- static auto MakeSpecificForRequireDecl (Context& context, SemIR::LocId loc_id,
88- SemIR::SpecificId entity_specific_id,
89- SemIR::GenericId require_generic_id)
90- -> SemIR::SpecificId {
91- auto entity_specific_args_id =
92- context.specifics ().GetArgsOrEmpty (entity_specific_id);
93- auto entity_specific_args =
94- context.inst_blocks ().Get (entity_specific_args_id);
95-
96- const auto & require_generic = context.generics ().Get (require_generic_id);
87+ // Makes a copy of a Specific from one generic to apply to another given
88+ // `generic_id`, with a given `Self` argument appended to the end.
89+ static auto MakeCopyOfSpecificAndAppendSelf (
90+ Context& context, SemIR::LocId loc_id, SemIR::SpecificId specific_id,
91+ SemIR::GenericId generic_id, SemIR::InstId self_id) -> SemIR::SpecificId {
92+ auto source_specific_args_id =
93+ context.specifics ().GetArgsOrEmpty (specific_id);
94+ auto source_specific_args =
95+ context.inst_blocks ().Get (source_specific_args_id);
96+
97+ llvm::SmallVector<SemIR::InstId> arg_ids;
98+ arg_ids.reserve (source_specific_args.size () + 1 );
99+ // Start with the enclosing arguments from the source Specific.
100+ llvm::append_range (arg_ids, source_specific_args);
101+ // Add the new `Self` argument.
102+ arg_ids.push_back (self_id);
103+
104+ return MakeSpecific (context, loc_id, generic_id, arg_ids);
105+ }
106+
107+ static auto GetRequireImplsSpecificSelf (Context& context,
108+ const SemIR::RequireImpls& require)
109+ -> SemIR::InstId {
110+ const auto & require_generic = context.generics ().Get (require.generic_id );
97111 const auto & require_self_specific =
98112 context.specifics ().Get (require_generic.self_specific_id );
99113 auto require_self_specific_args =
100114 context.inst_blocks ().Get (require_self_specific.args_id );
101-
102- llvm::SmallVector<SemIR::InstId> arg_ids;
103- arg_ids.reserve (entity_specific_args.size () + 1 );
104- // Start with the enclosing arguments from the entity.
105- llvm::append_range (arg_ids, entity_specific_args);
106- // Add the `Self` argument from the require decl.
107- arg_ids.push_back (require_self_specific_args.back ());
108-
109- return MakeSpecific (context, loc_id, require_generic_id, arg_ids);
115+ // The last argument of a `require` generic is always `Self`, as require can
116+ // not have any parameters of its own, only enclosing parameters.
117+ return require_self_specific_args.back ();
110118}
111119
112120static auto GetFacetTypeInSpecific (Context& context, SemIR::InstId facet_type,
@@ -146,8 +154,9 @@ static auto RequireCompleteFacetType(Context& context, SemIR::LocId loc_id,
146154 ForEachRequireImpls (
147155 context, interface, [&](const SemIR::RequireImpls& require) {
148156 if (require.extend_self ) {
149- auto require_specific_id = MakeSpecificForRequireDecl (
150- context, loc_id, extends.specific_id , require.generic_id );
157+ auto require_specific_id = MakeCopyOfSpecificAndAppendSelf (
158+ context, loc_id, extends.specific_id , require.generic_id ,
159+ GetRequireImplsSpecificSelf (context, require));
151160 auto facet_type_id = GetFacetTypeInSpecific (
152161 context, require.facet_type_inst_id , require_specific_id);
153162 if (facet_type_id.has_value ()) {
@@ -176,8 +185,9 @@ static auto RequireCompleteFacetType(Context& context, SemIR::LocId loc_id,
176185 ForEachRequireImpls (
177186 context, constraint, [&](const SemIR::RequireImpls& require) {
178187 if (require.extend_self ) {
179- auto require_specific_id = MakeSpecificForRequireDecl (
180- context, loc_id, extends.specific_id , require.generic_id );
188+ auto require_specific_id = MakeCopyOfSpecificAndAppendSelf (
189+ context, loc_id, extends.specific_id , require.generic_id ,
190+ GetRequireImplsSpecificSelf (context, require));
181191 auto facet_type_id = GetFacetTypeInSpecific (
182192 context, require.facet_type_inst_id , require_specific_id);
183193 if (facet_type_id.has_value ()) {
0 commit comments