Skip to content

Commit 9ba8d90

Browse files
committed
MakeCopyOfSpecificAndAppendSelf
1 parent 024eb8f commit 9ba8d90

File tree

1 file changed

+33
-23
lines changed

1 file changed

+33
-23
lines changed

toolchain/check/type_completion.cpp

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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

112120
static 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

Comments
 (0)