@@ -206,31 +206,20 @@ static auto GetWitnessIdForImpl(Context& context, SemIR::LocId loc_id,
206206 SemIR::ConstantId query_self_const_id,
207207 const SemIR::SpecificInterface& interface,
208208 SemIR::ImplId impl_id) -> EvalImplLookupResult {
209+ const SemIR::Impl& impl = context.impls ().Get (impl_id);
210+
209211 // The impl may have generic arguments, in which case we need to deduce them
210212 // to find what they are given the specific type and interface query. We use
211213 // that specific to map values in the impl to the deduced values.
212214 auto specific_id = SemIR::SpecificId::None;
213- {
214- // DeduceImplArguments can import new impls which can invalidate any
215- // pointers into `context.impls()`.
216- const SemIR::Impl& impl = context.impls ().Get (impl_id);
217-
218- if (impl.generic_id .has_value ()) {
219- specific_id =
220- DeduceImplArguments (context, loc_id,
221- {.self_id = impl.self_id ,
222- .generic_id = impl.generic_id ,
223- .specific_id = impl.interface .specific_id },
224- query_self_const_id, interface.specific_id );
225- if (!specific_id.has_value ()) {
226- return EvalImplLookupResult::MakeNone ();
227- }
215+ if (impl.generic_id .has_value ()) {
216+ specific_id = DeduceImplArguments (
217+ context, loc_id, impl, query_self_const_id, interface.specific_id );
218+ if (!specific_id.has_value ()) {
219+ return EvalImplLookupResult::MakeNone ();
228220 }
229221 }
230222
231- // Get a pointer again after DeduceImplArguments() is complete.
232- const SemIR::Impl& impl = context.impls ().Get (impl_id);
233-
234223 // The self type of the impl must match the type in the query, or this is an
235224 // `impl T as ...` for some other type `T` and should not be considered.
236225 auto deduced_self_const_id = SemIR::GetConstantValueInSpecific (
@@ -279,28 +268,22 @@ static auto GetWitnessIdForImpl(Context& context, SemIR::LocId loc_id,
279268 return EvalImplLookupResult::MakeNone ();
280269 }
281270
282- bool is_effectively_final = query_is_concrete || impl.is_final ;
283- auto witness_id = impl.witness_id ;
284-
285- // Note that this invalidates our `impl` reference. Don't use it again after
286- // this point.
287- LoadImportRef (context, witness_id);
288-
271+ LoadImportRef (context, impl.witness_id );
289272 if (specific_id.has_value ()) {
290273 // We need a definition of the specific `impl` so we can access its
291274 // witness.
292275 ResolveSpecificDefinition (context, loc_id, specific_id);
293276 }
294277
295- if (is_effectively_final ) {
278+ if (query_is_concrete || impl. is_final ) {
296279 // TODO: These final results should be cached somehow. Positive (non-None)
297280 // results could be cached globally, as they can not change. But
298281 // negative results can change after a final impl is written, so
299282 // they can only be cached in a limited way, or the cache needs to
300283 // be invalidated by writing a final impl that would match.
301284 return EvalImplLookupResult::MakeFinal (
302285 context.constant_values ().GetInstId (SemIR::GetConstantValueInSpecific (
303- context.sem_ir (), specific_id, witness_id)));
286+ context.sem_ir (), specific_id, impl. witness_id )));
304287 } else {
305288 return EvalImplLookupResult::MakeNonFinal ();
306289 }
@@ -583,11 +566,6 @@ auto EvalLookupSingleImplWitness(Context& context, SemIR::LocId loc_id,
583566 SemIR::InstId non_canonical_query_self_inst_id,
584567 bool poison_concrete_results)
585568 -> EvalImplLookupResult {
586- // NOTE: Do not retain this reference to the SpecificInterface obtained from a
587- // value store by SpecificInterfaceId. Doing impl lookup does deduce which can
588- // do more impl lookups, and impl lookup can add a new SpecificInterface to
589- // the store which can reallocate and invalidate any references held here into
590- // the store.
591569 auto query_specific_interface =
592570 context.specific_interfaces ().Get (eval_query.query_specific_interface_id );
593571
@@ -656,8 +634,6 @@ auto EvalLookupSingleImplWitness(Context& context, SemIR::LocId loc_id,
656634 context.impl_lookup_stack ().back ().impl_loc = candidate.loc_inst_id ;
657635 }
658636
659- // NOTE: GetWitnessIdForImpl() does deduction, which can cause new impls
660- // to be imported, invalidating any pointer into `context.impls()`.
661637 auto result = GetWitnessIdForImpl (
662638 context, loc_id, query_is_concrete, query_self_const_id,
663639 query_specific_interface, candidate.impl_id );
0 commit comments