Skip to content

Commit 4edd860

Browse files
committed
test
1 parent f64b088 commit 4edd860

File tree

11 files changed

+432
-6
lines changed

11 files changed

+432
-6
lines changed

toolchain/check/check_unit.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,8 @@ auto CheckUnit::CheckRequiredDefinitions() -> void {
499499

500500
for (auto [loc, specific_id] :
501501
GrowingRange(context_.definitions_required_by_use())) {
502+
// FIXME
503+
continue;
502504
// This is using the location for the use. We could track the
503505
// list of enclosing locations if this was used from a generic.
504506
if (!ResolveSpecificDefinition(context_, loc, specific_id)) {

toolchain/check/eval_inst.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,11 @@ auto EvalConstantInst(Context& context, SemIR::InstId inst_id,
492492
return ConstantEvalResult::NewSamePhase(inst);
493493
}
494494

495+
auto EvalConstantInst(Context& /*context*/, SemIR::RequireImplDefinition inst)
496+
-> ConstantEvalResult {
497+
return ConstantEvalResult::NewSamePhase(inst);
498+
}
499+
495500
auto EvalConstantInst(Context& context, SemIR::SpecificConstant inst)
496501
-> ConstantEvalResult {
497502
// Pull the constant value out of the specific.

toolchain/check/generic.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,7 @@ auto MakeSelfSpecific(Context& context, SemIR::LocId loc_id,
709709
return specific_id;
710710
}
711711

712+
// NOLINT(misc-no-recursion): FIXME
712713
auto ResolveSpecificDefinition(Context& context, SemIR::LocId loc_id,
713714
SemIR::SpecificId specific_id) -> bool {
714715
// TODO: Handle recursive resolution of the same generic definition.
@@ -723,6 +724,22 @@ auto ResolveSpecificDefinition(Context& context, SemIR::LocId loc_id,
723724
// The generic is not defined yet.
724725
return false;
725726
}
727+
for (auto inst_id :
728+
context.inst_blocks().Get(generic.definition_block_id)) {
729+
auto req_impl =
730+
context.insts().TryGetAs<SemIR::RequireImplDefinition>(inst_id);
731+
if (!req_impl) {
732+
continue;
733+
}
734+
auto def_id = req_impl->specific_id;
735+
const auto& def_specific = context.specifics().Get(def_id);
736+
if (const auto& def_generic =
737+
context.generics().Get(def_specific.generic_id);
738+
def_generic.self_specific_id.has_value()) {
739+
def_id = def_generic.self_specific_id;
740+
}
741+
ResolveSpecificDefinition(context, loc_id, def_id);
742+
}
726743
specific.definition_block_id = TryEvalBlockForSpecific(
727744
context, loc_id, specific_id, SemIR::GenericInstIndex::Definition);
728745
}

toolchain/check/impl_lookup.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,18 +232,30 @@ static auto GetWitnessIdForImpl(Context& context, SemIR::LocId loc_id,
232232

233233
// The self type of the impl must match the type in the query, or this is an
234234
// `impl T as ...` for some other type `T` and should not be considered.
235-
auto deduced_self_const_id = SemIR::GetConstantValueInSpecific(
235+
auto noncanonical_deduced_self_const_id = SemIR::GetConstantValueInSpecific(
236236
context.sem_ir(), specific_id, impl.self_id);
237+
237238
// In a generic `impl forall` the self type can be a FacetAccessType, which
238239
// will not be the same constant value as a query facet value. We move through
239240
// to the facet value here, and if the query was a FacetAccessType we did the
240241
// same there so they still match.
241-
deduced_self_const_id =
242-
GetCanonicalFacetOrTypeValue(context, deduced_self_const_id);
242+
auto deduced_self_const_id =
243+
GetCanonicalFacetOrTypeValue(context, noncanonical_deduced_self_const_id);
243244
if (query_self_const_id != deduced_self_const_id) {
244245
return EvalImplLookupResult::MakeNone();
245246
}
246247

248+
// When working with a symbolic constant and a `final` impl, add an
249+
// instruction to support requiring an impl definition which may not
250+
// otherwise be generated.
251+
if (impl.is_final && deduced_self_const_id.is_symbolic()) {
252+
AddInstInNoBlock(context, loc_id,
253+
SemIR::RequireImplDefinition{
254+
.type_id = GetSingletonType(
255+
context, SemIR::WitnessType::TypeInstId),
256+
.specific_id = specific_id});
257+
}
258+
247259
// The impl's constraint is a facet type which it is implementing for the self
248260
// type: the `I` in `impl ... as I`. The deduction step may be unable to be
249261
// fully applied to the types in the constraint and result in an error here,

toolchain/check/import_ref.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2884,6 +2884,27 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
28842884
.complete_type_inst_id = complete_type_inst_id});
28852885
}
28862886

2887+
static auto TryResolveTypedInst(ImportRefResolver& resolver,
2888+
SemIR::RequireImplDefinition inst)
2889+
-> ResolveResult {
2890+
CARBON_CHECK(resolver.import_types().GetInstId(inst.type_id) ==
2891+
SemIR::WitnessType::TypeInstId);
2892+
2893+
auto specific_data = GetLocalSpecificData(resolver, inst.specific_id);
2894+
2895+
if (resolver.HasNewWork()) {
2896+
return ResolveResult::Retry();
2897+
}
2898+
2899+
auto specific_id =
2900+
GetOrAddLocalSpecific(resolver, inst.specific_id, specific_data);
2901+
2902+
return ResolveAsDeduplicated<SemIR::RequireImplDefinition>(
2903+
resolver, {.type_id = GetSingletonType(resolver.local_context(),
2904+
SemIR::WitnessType::TypeInstId),
2905+
.specific_id = specific_id});
2906+
}
2907+
28872908
static auto TryResolveTypedInst(ImportRefResolver& resolver,
28882909
SemIR::ReturnSlotPattern inst,
28892910
SemIR::InstId import_inst_id) -> ResolveResult {
@@ -3349,6 +3370,9 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
33493370
case CARBON_KIND(SemIR::RequireCompleteType inst): {
33503371
return TryResolveTypedInst(resolver, inst);
33513372
}
3373+
case CARBON_KIND(SemIR::RequireImplDefinition inst): {
3374+
return TryResolveTypedInst(resolver, inst);
3375+
}
33523376
case CARBON_KIND(SemIR::ReturnSlotPattern inst): {
33533377
return TryResolveTypedInst(resolver, inst, constant_inst_id);
33543378
}

0 commit comments

Comments
 (0)