@@ -126,8 +126,9 @@ static auto GetGenericArgsWithSelfType(Context& context,
126126
127127auto GetSelfSpecificForInterfaceMemberWithSelfType (
128128 Context& context, SemIRLoc loc, SemIR::SpecificId interface_specific_id,
129- SemIR::GenericId generic_id, SemIR::TypeId self_type_id,
130- SemIR::InstId witness_inst_id) -> SemIR::SpecificId {
129+ SemIR::GenericId generic_id, SemIR::SpecificId enclosing_specific_id,
130+ SemIR::TypeId self_type_id, SemIR::InstId witness_inst_id)
131+ -> SemIR::SpecificId {
131132 const auto & generic = context.generics ().Get (generic_id);
132133 auto self_specific_args = context.inst_blocks ().Get (
133134 context.specifics ().Get (generic.self_specific_id ).args_id );
@@ -136,11 +137,36 @@ auto GetSelfSpecificForInterfaceMemberWithSelfType(
136137 context, interface_specific_id, generic_id, self_type_id, witness_inst_id,
137138 self_specific_args.size ());
138139
140+ // Determine the number of specific arguments that enclose the point where
141+ // this self specific will be used from. In an impl, this will be the number
142+ // of parameters that the impl has.
143+ int num_enclosing_specific_args =
144+ context.inst_blocks ()
145+ .Get (context.specifics ().GetArgsOrEmpty (enclosing_specific_id))
146+ .size ();
147+ // The index of each remaining generic parameter is adjusted to match the
148+ // numbering at the point where the self specific is used.
149+ int index_delta = num_enclosing_specific_args - arg_ids.size ();
150+
139151 // Take any trailing argument values from the self specific.
140152 // TODO: If these refer to outer arguments, for example in their types, we may
141153 // need to perform extra substitutions here.
142154 for (auto arg_id : self_specific_args.drop_front (arg_ids.size ())) {
143- arg_ids.push_back (context.constant_values ().GetConstantInstId (arg_id));
155+ auto new_arg_id = context.constant_values ().GetConstantInstId (arg_id);
156+ if (index_delta) {
157+ // If this parameter would have a new index in the context described by
158+ // `enclosing_specific_id`, form a new binding with an adjusted index.
159+ auto bind_name = context.insts ().GetAs <SemIR::BindSymbolicName>(
160+ context.constant_values ().GetConstantInstId (arg_id));
161+ auto entity_name = context.entity_names ().Get (bind_name.entity_name_id );
162+ entity_name.bind_index_value += index_delta;
163+ CARBON_CHECK (entity_name.bind_index_value >= 0 );
164+ bind_name.entity_name_id =
165+ context.entity_names ().AddCanonical (entity_name);
166+ new_arg_id = context.constant_values ().GetInstId (
167+ TryEvalInst (context, arg_id, bind_name));
168+ }
169+ arg_ids.push_back (new_arg_id);
144170 }
145171
146172 return MakeSpecific (context, loc, generic_id, arg_ids);
0 commit comments