Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions toolchain/check/eval_inst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,12 @@ auto EvalConstantInst(Context& context, SemIR::InstId inst_id,
return ConstantEvalResult::NewSamePhase(inst);
}

auto EvalConstantInst(Context& context, SemIR::RequireSpecificDefinition inst)
-> ConstantEvalResult {
ResolveSpecificDefinition(context, SemIR::LocId::None, inst.specific_id);
return ConstantEvalResult::NewSamePhase(inst);
}

auto EvalConstantInst(Context& context, SemIR::SpecificConstant inst)
-> ConstantEvalResult {
// Pull the constant value out of the specific.
Expand Down
1 change: 1 addition & 0 deletions toolchain/check/generic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,7 @@ auto ResolveSpecificDefinition(Context& context, SemIR::LocId loc_id,
if (!specific.definition_block_id.has_value()) {
// Evaluate the eval block for the definition of the generic.
auto& generic = context.generics().Get(generic_id);
CARBON_CHECK(generic.decl_block_id.has_value(), "missing declaration");
if (!generic.definition_block_id.has_value()) {
// The generic is not defined yet.
return false;
Expand Down
17 changes: 14 additions & 3 deletions toolchain/check/impl_lookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,14 +240,15 @@ static auto GetWitnessIdForImpl(Context& context, SemIR::LocId loc_id,

// The self type of the impl must match the type in the query, or this is an
// `impl T as ...` for some other type `T` and should not be considered.
auto deduced_self_const_id = SemIR::GetConstantValueInSpecific(
auto noncanonical_deduced_self_const_id = SemIR::GetConstantValueInSpecific(
context.sem_ir(), specific_id, impl.self_id);

// In a generic `impl forall` the self type can be a FacetAccessType, which
// will not be the same constant value as a query facet value. We move through
// to the facet value here, and if the query was a FacetAccessType we did the
// same there so they still match.
deduced_self_const_id =
GetCanonicalFacetOrTypeValue(context, deduced_self_const_id);
auto deduced_self_const_id =
GetCanonicalFacetOrTypeValue(context, noncanonical_deduced_self_const_id);
if (query_self_const_id != deduced_self_const_id) {
return EvalImplLookupResult::MakeNone();
}
Expand Down Expand Up @@ -288,6 +289,16 @@ static auto GetWitnessIdForImpl(Context& context, SemIR::LocId loc_id,

LoadImportRef(context, impl.witness_id);
if (specific_id.has_value()) {
// When working with a symbolic constant and a `final` impl, add an
// instruction to support requiring an impl definition which may not
// otherwise be generated.
AddInstInNoBlock(
context, loc_id,
SemIR::RequireSpecificDefinition{
.type_id = GetSingletonType(
context, SemIR::RequireSpecificDefinitionType::TypeInstId),
.specific_id = specific_id});

// We need a definition of the specific `impl` so we can access its
// witness.
ResolveSpecificDefinition(context, loc_id, specific_id);
Expand Down
28 changes: 28 additions & 0 deletions toolchain/check/import_ref.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3054,6 +3054,31 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
.complete_type_inst_id = complete_type_inst_id});
}

static auto TryResolveTypedInst(ImportRefResolver& resolver,
SemIR::RequireSpecificDefinition inst)
-> ResolveResult {
return ResolveResult::Done(SemIR::ErrorInst::ConstantId,
SemIR::ErrorInst::InstId);

CARBON_CHECK(resolver.import_types().GetInstId(inst.type_id) ==
SemIR::RequireSpecificDefinitionType::TypeInstId);

auto specific_data = GetLocalSpecificData(resolver, inst.specific_id);

if (resolver.HasNewWork()) {
return ResolveResult::Retry();
}

auto specific_id =
GetOrAddLocalSpecific(resolver, inst.specific_id, specific_data);

return ResolveAsDeduplicated<SemIR::RequireSpecificDefinition>(
resolver, {.type_id = GetSingletonType(
resolver.local_context(),
SemIR::RequireSpecificDefinitionType::TypeInstId),
.specific_id = specific_id});
}

static auto TryResolveTypedInst(ImportRefResolver& resolver,
SemIR::ReturnSlotPattern inst,
SemIR::InstId import_inst_id) -> ResolveResult {
Expand Down Expand Up @@ -3522,6 +3547,9 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
case CARBON_KIND(SemIR::RequireCompleteType inst): {
return TryResolveTypedInst(resolver, inst);
}
case CARBON_KIND(SemIR::RequireSpecificDefinition inst): {
return TryResolveTypedInst(resolver, inst);
}
case CARBON_KIND(SemIR::ReturnSlotPattern inst): {
return TryResolveTypedInst(resolver, inst, constant_inst_id);
}
Expand Down
16 changes: 10 additions & 6 deletions toolchain/check/testdata/array/init_dependent_bound.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ fn H() { G(3); }
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.cc4: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.30f) [symbolic]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.44f: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.cc4 = struct_value () [symbolic]
// CHECK:STDOUT: %require_complete.2e8: <witness> = require_complete_type %ptr.a86 [symbolic]
// CHECK:STDOUT: %.019: require_specific_def_type = require_specific_def @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.30f) [symbolic]
// CHECK:STDOUT: %Destroy.facet.49e: %Destroy.type = facet_value %array_type.512, (%Destroy.impl_witness.aa0) [symbolic]
// CHECK:STDOUT: %.fb1: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.49e [symbolic]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.91d: <specific function> = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op.44f, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value.30f) [symbolic]
Expand All @@ -89,12 +90,13 @@ fn H() { G(3); }
// CHECK:STDOUT: %array.2e5: %array_type.6f1 = tuple_value () [concrete]
// CHECK:STDOUT: %facet_value.cba: %type_where = facet_value %array_type.6f1, () [concrete]
// CHECK:STDOUT: %Destroy.impl_witness.dff: <witness> = impl_witness imports.%Destroy.impl_witness_table, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.cba) [concrete]
// CHECK:STDOUT: %Destroy.facet.105: %Destroy.type = facet_value %array_type.6f1, (%Destroy.impl_witness.dff) [concrete]
// CHECK:STDOUT: %.0c7: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.105 [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.cc8: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.cba) [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.dcd: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.cc8 = struct_value () [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.bf3: <specific function> = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op.dcd, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value.cba) [concrete]
// CHECK:STDOUT: %complete_type.3e1: <witness> = complete_type_witness %ptr.cf4 [concrete]
// CHECK:STDOUT: %.793: require_specific_def_type = require_specific_def @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.cba) [concrete]
// CHECK:STDOUT: %Destroy.facet.105: %Destroy.type = facet_value %array_type.6f1, (%Destroy.impl_witness.dff) [concrete]
// CHECK:STDOUT: %.0c7: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.105 [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.bf3: <specific function> = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op.dcd, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value.cba) [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
Expand All @@ -111,9 +113,10 @@ fn H() { G(3); }
// CHECK:STDOUT: %pattern_type: type = pattern_type %array_type.loc7_22.2 [symbolic = %pattern_type (constants.%pattern_type.b5c)]
// CHECK:STDOUT: %array: @G.%array_type.loc7_22.2 (%array_type.512) = tuple_value () [symbolic = %array (constants.%array.8ba)]
// CHECK:STDOUT: %facet_value: %type_where = facet_value %array_type.loc7_22.2, () [symbolic = %facet_value (constants.%facet_value.30f)]
// CHECK:STDOUT: %.loc7_3.2: require_specific_def_type = require_specific_def @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [symbolic = %.loc7_3.2 (constants.%.019)]
// CHECK:STDOUT: %Destroy.impl_witness: <witness> = impl_witness imports.%Destroy.impl_witness_table, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.aa0)]
// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %array_type.loc7_22.2, (%Destroy.impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet.49e)]
// CHECK:STDOUT: %.loc7_3.2: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet [symbolic = %.loc7_3.2 (constants.%.fb1)]
// CHECK:STDOUT: %.loc7_3.3: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet [symbolic = %.loc7_3.3 (constants.%.fb1)]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [symbolic = %DestroyT.binding.as_type.as.Destroy.impl.Op.type (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.type.cc4)]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op: @G.%DestroyT.binding.as_type.as.Destroy.impl.Op.type (%DestroyT.binding.as_type.as.Destroy.impl.Op.type.cc4) = struct_value () [symbolic = %DestroyT.binding.as_type.as.Destroy.impl.Op (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.44f)]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn: <specific function> = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value) [symbolic = %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.91d)]
Expand All @@ -137,7 +140,7 @@ fn H() { G(3); }
// CHECK:STDOUT: %array_type.loc7_22.1: type = array_type %int_0, %T.ref [symbolic = %array_type.loc7_22.2 (constants.%array_type.512)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %arr: ref @G.%array_type.loc7_22.2 (%array_type.512) = ref_binding arr, %arr.var
// CHECK:STDOUT: %impl.elem0: @G.%.loc7_3.2 (%.fb1) = impl_witness_access constants.%Destroy.impl_witness.aa0, element0 [symbolic = %DestroyT.binding.as_type.as.Destroy.impl.Op (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.44f)]
// CHECK:STDOUT: %impl.elem0: @G.%.loc7_3.3 (%.fb1) = impl_witness_access constants.%Destroy.impl_witness.aa0, element0 [symbolic = %DestroyT.binding.as_type.as.Destroy.impl.Op (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.44f)]
// CHECK:STDOUT: %bound_method.loc7_3.1: <bound method> = bound_method %arr.var, %impl.elem0
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.30f) [symbolic = %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.91d)]
// CHECK:STDOUT: %bound_method.loc7_3.2: <bound method> = bound_method %arr.var, %specific_fn
Expand All @@ -160,9 +163,10 @@ fn H() { G(3); }
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.9c8
// CHECK:STDOUT: %array => constants.%array.2e5
// CHECK:STDOUT: %facet_value => constants.%facet_value.cba
// CHECK:STDOUT: %.loc7_3.2 => constants.%.793
// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.dff
// CHECK:STDOUT: %Destroy.facet => constants.%Destroy.facet.105
// CHECK:STDOUT: %.loc7_3.2 => constants.%.0c7
// CHECK:STDOUT: %.loc7_3.3 => constants.%.0c7
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type => constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.type.cc8
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op => constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.dcd
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn => constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.bf3
Expand Down
16 changes: 10 additions & 6 deletions toolchain/check/testdata/class/destroy_calls.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -391,20 +391,22 @@ fn G() { F({}); }
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.76f: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.7d9 = struct_value () [template]
// CHECK:STDOUT: %ptr.d75: type = ptr_type %C.3f0 [template]
// CHECK:STDOUT: %require_complete.ba9: <witness> = require_complete_type %ptr.d75 [template]
// CHECK:STDOUT: %.3ed: require_specific_def_type = require_specific_def @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.bf8) [template]
// CHECK:STDOUT: %Destroy.facet.a5b: %Destroy.type = facet_value %C.3f0, (%Destroy.impl_witness.a59) [template]
// CHECK:STDOUT: %.4c5: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.a5b [template]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.5e4: <specific function> = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op.76f, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value.bf8) [template]
// CHECK:STDOUT: %C.7a7: type = class_type @C, @C(%empty_struct_type) [concrete]
// CHECK:STDOUT: %pattern_type.99a: type = pattern_type %C.7a7 [concrete]
// CHECK:STDOUT: %facet_value.036: %type_where = facet_value %C.7a7, () [concrete]
// CHECK:STDOUT: %Destroy.impl_witness.8e7: <witness> = impl_witness imports.%Destroy.impl_witness_table, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.036) [concrete]
// CHECK:STDOUT: %Destroy.facet.056: %Destroy.type = facet_value %C.7a7, (%Destroy.impl_witness.8e7) [concrete]
// CHECK:STDOUT: %.1c0: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.056 [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.c3a: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.036) [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.b3a: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.c3a = struct_value () [concrete]
// CHECK:STDOUT: %ptr.308: type = ptr_type %C.7a7 [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.a93: <specific function> = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op.b3a, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value.036) [concrete]
// CHECK:STDOUT: %complete_type.903: <witness> = complete_type_witness %ptr.308 [concrete]
// CHECK:STDOUT: %.8e4: require_specific_def_type = require_specific_def @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.036) [concrete]
// CHECK:STDOUT: %Destroy.facet.056: %Destroy.type = facet_value %C.7a7, (%Destroy.impl_witness.8e7) [concrete]
// CHECK:STDOUT: %.1c0: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.056 [concrete]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.a93: <specific function> = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op.b3a, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value.036) [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
Expand All @@ -429,9 +431,10 @@ fn G() { F({}); }
// CHECK:STDOUT: %require_complete.loc7_13: <witness> = require_complete_type %C.loc7_13.2 [template = %require_complete.loc7_13 (constants.%require_complete.c98)]
// CHECK:STDOUT: %pattern_type: type = pattern_type %C.loc7_13.2 [template = %pattern_type (constants.%pattern_type.06f)]
// CHECK:STDOUT: %facet_value: %type_where = facet_value %C.loc7_13.2, () [template = %facet_value (constants.%facet_value.bf8)]
// CHECK:STDOUT: %.loc7_3.1: require_specific_def_type = require_specific_def @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [template = %.loc7_3.1 (constants.%.3ed)]
// CHECK:STDOUT: %Destroy.impl_witness: <witness> = impl_witness imports.%Destroy.impl_witness_table, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [template = %Destroy.impl_witness (constants.%Destroy.impl_witness.a59)]
// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %C.loc7_13.2, (%Destroy.impl_witness) [template = %Destroy.facet (constants.%Destroy.facet.a5b)]
// CHECK:STDOUT: %.loc7_3: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet [template = %.loc7_3 (constants.%.4c5)]
// CHECK:STDOUT: %.loc7_3.2: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet [template = %.loc7_3.2 (constants.%.4c5)]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [template = %DestroyT.binding.as_type.as.Destroy.impl.Op.type (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.type.7d9)]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op: @F.%DestroyT.binding.as_type.as.Destroy.impl.Op.type (%DestroyT.binding.as_type.as.Destroy.impl.Op.type.7d9) = struct_value () [template = %DestroyT.binding.as_type.as.Destroy.impl.Op (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.76f)]
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn: <specific function> = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value) [template = %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.5e4)]
Expand All @@ -451,7 +454,7 @@ fn G() { F({}); }
// CHECK:STDOUT: %C.loc7_13.1: type = class_type @C, @C(constants.%T) [template = %C.loc7_13.2 (constants.%C.3f0)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %v: ref @F.%C.loc7_13.2 (%C.3f0) = ref_binding v, %v.var
// CHECK:STDOUT: %impl.elem0: @F.%.loc7_3 (%.4c5) = impl_witness_access constants.%Destroy.impl_witness.a59, element0 [template = %DestroyT.binding.as_type.as.Destroy.impl.Op (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.76f)]
// CHECK:STDOUT: %impl.elem0: @F.%.loc7_3.2 (%.4c5) = impl_witness_access constants.%Destroy.impl_witness.a59, element0 [template = %DestroyT.binding.as_type.as.Destroy.impl.Op (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.76f)]
// CHECK:STDOUT: %bound_method.loc7_3.1: <bound method> = bound_method %v.var, %impl.elem0
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.bf8) [template = %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn (constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.5e4)]
// CHECK:STDOUT: %bound_method.loc7_3.2: <bound method> = bound_method %v.var, %specific_fn
Expand All @@ -473,9 +476,10 @@ fn G() { F({}); }
// CHECK:STDOUT: %require_complete.loc7_13 => constants.%complete_type.357
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.99a
// CHECK:STDOUT: %facet_value => constants.%facet_value.036
// CHECK:STDOUT: %.loc7_3.1 => constants.%.8e4
// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.8e7
// CHECK:STDOUT: %Destroy.facet => constants.%Destroy.facet.056
// CHECK:STDOUT: %.loc7_3 => constants.%.1c0
// CHECK:STDOUT: %.loc7_3.2 => constants.%.1c0
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type => constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.type.c3a
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op => constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.b3a
// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn => constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.a93
Expand Down
Loading
Loading