mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 14:31:03 +01:00
Add an EvalOrAddInst function. (#5258)
Use that instead of `AddInstInNoBlock` to get the value of an instruction when evaluation might depend on the `InstId` but only the `ConstantId` of the instruction is desired by the consumer.
This commit is contained in:
@@ -1744,7 +1744,8 @@ static auto TryEvalTypedInst(EvalContext& eval_context, SemIR::InstId inst_id,
|
||||
// Couldn't perform the action because it's still dependent.
|
||||
return MakeConstantResult(eval_context.context(), inst,
|
||||
Phase::TemplateSymbolic);
|
||||
} else if constexpr (InstT::Kind.constant_needs_inst_id()) {
|
||||
} else if constexpr (InstT::Kind.constant_needs_inst_id() !=
|
||||
SemIR::InstConstantNeedsInstIdKind::No) {
|
||||
CARBON_CHECK(inst_id.has_value());
|
||||
return ConvertEvalResultToConstantId(
|
||||
eval_context.context(),
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "toolchain/check/context.h"
|
||||
#include "toolchain/sem_ir/ids.h"
|
||||
#include "toolchain/sem_ir/inst.h"
|
||||
#include "toolchain/sem_ir/inst_kind.h"
|
||||
|
||||
namespace Carbon::Check {
|
||||
|
||||
@@ -38,8 +39,12 @@ inline auto TryEvalInst(Context& context, SemIR::InstId inst_id)
|
||||
// value and the instruction is known to not matter. However, even then care
|
||||
// should be taken: if the produced constant is symbolic, you may still need an
|
||||
// instruction to associate the constant with the enclosing generic.
|
||||
//
|
||||
// To evaluate an instruction and add it to SemIR only if necessary, use
|
||||
// EvalOrAddInst instead.
|
||||
template <typename InstT>
|
||||
requires(!InstT::Kind.constant_needs_inst_id())
|
||||
requires(InstT::Kind.constant_needs_inst_id() ==
|
||||
SemIR::InstConstantNeedsInstIdKind::No)
|
||||
auto TryEvalInst(Context& context, InstT inst) -> SemIR::ConstantId {
|
||||
return TryEvalInstUnsafe(context, SemIR::InstId::None, inst);
|
||||
}
|
||||
|
||||
@@ -140,7 +140,8 @@ template <typename InstT>
|
||||
using FunctionTypeForEvalConstantInst =
|
||||
typename FunctionTypeForEvalConstantInstImpl<
|
||||
InstT, ConstantKindHasEvalConstantInst(InstT::Kind.constant_kind()),
|
||||
InstT::Kind.constant_needs_inst_id()>::Type;
|
||||
InstT::Kind.constant_needs_inst_id() !=
|
||||
SemIR::InstConstantNeedsInstIdKind::No>::Type;
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
|
||||
@@ -344,8 +344,8 @@ static auto FindWitnessInImpls(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::ConstantId query_self_const_id,
|
||||
SemIR::SpecificInterface interface)
|
||||
-> SemIR::InstId {
|
||||
auto witness_id = AddInstInNoBlock(
|
||||
context, loc_id,
|
||||
auto witness_const_id = EvalOrAddInst(
|
||||
context, loc_id.ToImplicit(),
|
||||
SemIR::LookupImplWitness{
|
||||
.type_id =
|
||||
GetSingletonType(context, SemIR::WitnessType::SingletonInstId),
|
||||
@@ -356,7 +356,6 @@ static auto FindWitnessInImpls(Context& context, SemIR::LocId loc_id,
|
||||
});
|
||||
// We use a NotConstant result from eval to communicate back an impl
|
||||
// lookup failure. See `EvalConstantInst()` for `LookupImplWitness`.
|
||||
auto witness_const_id = context.constant_values().Get(witness_id);
|
||||
if (!witness_const_id.is_constant()) {
|
||||
return SemIR::InstId::None;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "toolchain/check/generic_region_stack.h"
|
||||
#include "toolchain/sem_ir/constant.h"
|
||||
#include "toolchain/sem_ir/ids.h"
|
||||
#include "toolchain/sem_ir/inst_kind.h"
|
||||
|
||||
namespace Carbon::Check {
|
||||
|
||||
@@ -100,20 +101,91 @@ auto AddPatternInst(Context& context, SemIR::LocIdAndInst loc_id_and_inst)
|
||||
|
||||
auto GetOrAddInst(Context& context, SemIR::LocIdAndInst loc_id_and_inst)
|
||||
-> SemIR::InstId {
|
||||
if (loc_id_and_inst.loc_id.is_implicit() &&
|
||||
!loc_id_and_inst.inst.kind().constant_needs_inst_id()) {
|
||||
auto const_id =
|
||||
TryEvalInstUnsafe(context, SemIR::InstId::None, loc_id_and_inst.inst);
|
||||
if (const_id.has_value()) {
|
||||
CARBON_VLOG_TO(context.vlog_stream(), "GetOrAddInst: constant: {0}\n",
|
||||
loc_id_and_inst.inst);
|
||||
return context.constant_values().GetInstId(const_id);
|
||||
CARBON_CHECK(!loc_id_and_inst.inst.kind().has_cleanup());
|
||||
|
||||
auto handle_constant_id = [&](SemIR::ConstantId const_id) -> SemIR::InstId {
|
||||
CARBON_CHECK(const_id.has_value());
|
||||
|
||||
// If we didn't produce a constant value for the instruction, we have to add
|
||||
// the instruction.
|
||||
if (!const_id.is_constant()) {
|
||||
return SemIR::InstId::None;
|
||||
}
|
||||
|
||||
CARBON_VLOG_TO(context.vlog_stream(), "GetOrAddInst: constant: {0}\n",
|
||||
loc_id_and_inst.inst);
|
||||
return context.constant_values().GetInstId(const_id);
|
||||
};
|
||||
|
||||
// If the instruction is implicit, produce its constant value instead if
|
||||
// possible.
|
||||
if (loc_id_and_inst.loc_id.is_implicit()) {
|
||||
switch (loc_id_and_inst.inst.kind().constant_needs_inst_id()) {
|
||||
case SemIR::InstConstantNeedsInstIdKind::No: {
|
||||
// Evaluation doesn't need an InstId. Just do it.
|
||||
auto const_id = TryEvalInstUnsafe(context, SemIR::InstId::None,
|
||||
loc_id_and_inst.inst);
|
||||
if (auto result_inst_id = handle_constant_id(const_id);
|
||||
result_inst_id.has_value()) {
|
||||
return result_inst_id;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SemIR::InstConstantNeedsInstIdKind::DuringEvaluation: {
|
||||
// Evaluation temporarily needs an InstId. Add one for now.
|
||||
auto inst_id = AddInstInNoBlock(context, loc_id_and_inst);
|
||||
auto const_id = context.constant_values().Get(inst_id);
|
||||
if (auto result_inst_id = handle_constant_id(const_id);
|
||||
result_inst_id.has_value()) {
|
||||
// TODO: We didn't end up needing the `inst_id` instruction. Consider
|
||||
// removing it from `insts` if it's still the most recently added
|
||||
// instruction.
|
||||
CARBON_CHECK(result_inst_id != inst_id);
|
||||
return result_inst_id;
|
||||
}
|
||||
context.inst_block_stack().AddInstId(inst_id);
|
||||
return inst_id;
|
||||
}
|
||||
|
||||
case SemIR::InstConstantNeedsInstIdKind::Permanent: {
|
||||
// Evaluation needs a permanent InstId. Add the instruction.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: For an implicit instruction, this reattempts evaluation.
|
||||
return AddInst(context, loc_id_and_inst);
|
||||
}
|
||||
|
||||
auto EvalOrAddInst(Context& context, SemIR::LocIdAndInst loc_id_and_inst)
|
||||
-> SemIR::ConstantId {
|
||||
CARBON_CHECK(!loc_id_and_inst.inst.kind().has_cleanup());
|
||||
|
||||
switch (loc_id_and_inst.inst.kind().constant_needs_inst_id()) {
|
||||
case SemIR::InstConstantNeedsInstIdKind::No: {
|
||||
// Evaluation doesn't need an InstId. Just do it.
|
||||
return TryEvalInstUnsafe(context, SemIR::InstId::None,
|
||||
loc_id_and_inst.inst);
|
||||
}
|
||||
|
||||
case SemIR::InstConstantNeedsInstIdKind::DuringEvaluation: {
|
||||
// Evaluation temporarily needs an InstId. Add one for now.
|
||||
auto inst_id = AddInstInNoBlock(context, loc_id_and_inst);
|
||||
// TODO: Consider removing `inst_id` from `insts` if it's still the most
|
||||
// recently added instruction.
|
||||
return context.constant_values().Get(inst_id);
|
||||
}
|
||||
|
||||
case SemIR::InstConstantNeedsInstIdKind::Permanent: {
|
||||
// Evaluation needs a permanent InstId. Add the instruction.
|
||||
auto inst_id = AddInst(context, loc_id_and_inst);
|
||||
return context.constant_values().Get(inst_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto AddPlaceholderInstInNoBlock(Context& context,
|
||||
SemIR::LocIdAndInst loc_id_and_inst)
|
||||
-> SemIR::InstId {
|
||||
|
||||
@@ -64,6 +64,23 @@ auto GetOrAddInst(Context& context, LocT loc, InstT inst) -> SemIR::InstId {
|
||||
return GetOrAddInst(context, SemIR::LocIdAndInst(loc, inst));
|
||||
}
|
||||
|
||||
// Evaluate the given instruction, and returns the corresponding constant value.
|
||||
// Adds the instruction to the current block if it might be referenced by its
|
||||
// constant value; otherwise, does not add the instruction to an instruction
|
||||
// block.
|
||||
auto EvalOrAddInst(Context& context, SemIR::LocIdAndInst loc_id_and_inst)
|
||||
-> SemIR::ConstantId;
|
||||
|
||||
// Convenience for EvalOrAddInst with typed nodes.
|
||||
//
|
||||
// As a safety check, prevent use with storage insts (see `AddInstWithCleanup`).
|
||||
template <typename InstT, typename LocT>
|
||||
requires(!InstT::Kind.has_cleanup())
|
||||
auto EvalOrAddInst(Context& context, LocT loc, InstT inst)
|
||||
-> SemIR::ConstantId {
|
||||
return EvalOrAddInst(context, SemIR::LocIdAndInst(loc, inst));
|
||||
}
|
||||
|
||||
// Adds an instruction and enqueues it to be added to the eval block of the
|
||||
// enclosing generic, returning the produced ID. The instruction is expected to
|
||||
// be a dependent template instantiation action.
|
||||
|
||||
@@ -405,15 +405,13 @@ class SubstConstantCallbacks final : public SubstInstCallbacks {
|
||||
// Rebuilds an instruction by building a new constant.
|
||||
auto Rebuild(SemIR::InstId old_inst_id, SemIR::Inst new_inst) const
|
||||
-> SemIR::InstId override {
|
||||
auto result_id = GetOrAddInst(
|
||||
auto const_id = EvalOrAddInst(
|
||||
*context_,
|
||||
SemIR::LocIdAndInst::UncheckedLoc(
|
||||
context_->insts().GetLocId(old_inst_id).ToImplicit(), new_inst));
|
||||
auto const_inst_id =
|
||||
context_->constant_values().GetConstantInstId(result_id);
|
||||
CARBON_CHECK(const_inst_id.has_value(),
|
||||
CARBON_CHECK(const_id.has_value(),
|
||||
"Substitution into constant produced non-constant");
|
||||
return const_inst_id;
|
||||
return context_->constant_values().GetInstId(const_id);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Vendored
-3
@@ -245,7 +245,6 @@ fn G() {
|
||||
// CHECK:STDOUT: %CallGenericMethod.ref: %CallGenericMethod.type = name_ref CallGenericMethod, file.%CallGenericMethod.decl [concrete = constants.%CallGenericMethod]
|
||||
// CHECK:STDOUT: %GenericParam.ref: type = name_ref GenericParam, file.%GenericParam.decl [concrete = constants.%GenericParam]
|
||||
// CHECK:STDOUT: %ImplsGeneric.ref: type = name_ref ImplsGeneric, file.%ImplsGeneric.decl [concrete = constants.%ImplsGeneric]
|
||||
// CHECK:STDOUT: %Generic.type: type = facet_type <@Generic, @Generic(constants.%GenericParam)> [concrete = constants.%Generic.type.769]
|
||||
// CHECK:STDOUT: %Generic.facet: %Generic.type.769 = facet_value constants.%ImplsGeneric, (constants.%impl_witness) [concrete = constants.%Generic.facet]
|
||||
// CHECK:STDOUT: %.loc18: %Generic.type.769 = converted constants.%ImplsGeneric, %Generic.facet [concrete = constants.%Generic.facet]
|
||||
// CHECK:STDOUT: %CallGenericMethod.specific_fn: <specific function> = specific_function %CallGenericMethod.ref, @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet) [concrete = constants.%CallGenericMethod.specific_fn.934]
|
||||
@@ -279,7 +278,6 @@ fn G() {
|
||||
// CHECK:STDOUT: %PassThroughToGenericMethod.ref: %PassThroughToGenericMethod.type = name_ref PassThroughToGenericMethod, file.%PassThroughToGenericMethod.decl [concrete = constants.%PassThroughToGenericMethod]
|
||||
// CHECK:STDOUT: %GenericParam.ref: type = name_ref GenericParam, file.%GenericParam.decl [concrete = constants.%GenericParam]
|
||||
// CHECK:STDOUT: %ImplsGeneric.ref: type = name_ref ImplsGeneric, file.%ImplsGeneric.decl [concrete = constants.%ImplsGeneric]
|
||||
// CHECK:STDOUT: %Generic.type: type = facet_type <@Generic, @Generic(constants.%GenericParam)> [concrete = constants.%Generic.type.769]
|
||||
// CHECK:STDOUT: %Generic.facet: %Generic.type.769 = facet_value constants.%ImplsGeneric, (constants.%impl_witness) [concrete = constants.%Generic.facet]
|
||||
// CHECK:STDOUT: %.loc26: %Generic.type.769 = converted constants.%ImplsGeneric, %Generic.facet [concrete = constants.%Generic.facet]
|
||||
// CHECK:STDOUT: %PassThroughToGenericMethod.specific_fn: <specific function> = specific_function %PassThroughToGenericMethod.ref, @PassThroughToGenericMethod(constants.%GenericParam, constants.%Generic.facet) [concrete = constants.%PassThroughToGenericMethod.specific_fn]
|
||||
@@ -537,7 +535,6 @@ fn G() {
|
||||
// CHECK:STDOUT: %.loc18_36.3: init %GenericParam = class_init (), %.loc18_36.2 [concrete = constants.%GenericParam.val]
|
||||
// CHECK:STDOUT: %.loc18_36.4: ref %GenericParam = temporary %.loc18_36.2, %.loc18_36.3
|
||||
// CHECK:STDOUT: %.loc18_38.1: ref %GenericParam = converted %.loc18_36.1, %.loc18_36.4
|
||||
// CHECK:STDOUT: %Generic.type: type = facet_type <@Generic, @Generic(constants.%GenericParam)> [concrete = constants.%Generic.type.769]
|
||||
// CHECK:STDOUT: %Generic.facet: %Generic.type.769 = facet_value constants.%ImplsGeneric, (constants.%impl_witness) [concrete = constants.%Generic.facet]
|
||||
// CHECK:STDOUT: %.loc18_53: %Generic.type.769 = converted constants.%ImplsGeneric, %Generic.facet [concrete = constants.%Generic.facet]
|
||||
// CHECK:STDOUT: %CallGenericMethod.specific_fn: <specific function> = specific_function %CallGenericMethod.ref, @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet) [concrete = constants.%CallGenericMethod.specific_fn]
|
||||
|
||||
Vendored
-1
@@ -319,7 +319,6 @@ fn B() {
|
||||
// CHECK:STDOUT: %.loc20_42.3: init %GenericParam = class_init (), %.loc20_42.2 [concrete = constants.%GenericParam.val]
|
||||
// CHECK:STDOUT: %.loc20_42.4: ref %GenericParam = temporary %.loc20_42.2, %.loc20_42.3
|
||||
// CHECK:STDOUT: %.loc20_44.1: ref %GenericParam = converted %.loc20_42.1, %.loc20_42.4
|
||||
// CHECK:STDOUT: %Generic.type: type = facet_type <@Generic, @Generic(constants.%GenericParam)> [concrete = constants.%Generic.type.769]
|
||||
// CHECK:STDOUT: %Generic.facet: %Generic.type.769 = facet_value constants.%ImplsGeneric, (constants.%impl_witness) [concrete = constants.%Generic.facet.8bd]
|
||||
// CHECK:STDOUT: %.loc20_59: %Generic.type.769 = converted constants.%ImplsGeneric, %Generic.facet [concrete = constants.%Generic.facet.8bd]
|
||||
// CHECK:STDOUT: %CallGenericMethod.specific_fn: <specific function> = specific_function %CallGenericMethod.ref, @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet.8bd) [concrete = constants.%CallGenericMethod.specific_fn]
|
||||
|
||||
Vendored
+4
-6
@@ -919,8 +919,8 @@ fn CallsWithTypeExplicit(U:! type) {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type @HandleTameAnimal2.%W.as_type.loc11_44.2 (%W.as_type) [symbolic = %require_complete (constants.%require_complete.ba9)]
|
||||
// CHECK:STDOUT: %W.as_wit.iface0.loc12_14.3: <witness> = facet_access_witness %W.loc11_22.2, element0 [symbolic = %W.as_wit.iface0.loc12_14.3 (constants.%W.as_wit.iface0)]
|
||||
// CHECK:STDOUT: %Animal.facet.loc12_14.3: %Animal.type = facet_value %W.as_type.loc11_44.2, (%W.as_wit.iface0.loc12_14.3) [symbolic = %Animal.facet.loc12_14.3 (constants.%Animal.facet)]
|
||||
// CHECK:STDOUT: %W.as_wit.iface0: <witness> = facet_access_witness %W.loc11_22.2, element0 [symbolic = %W.as_wit.iface0 (constants.%W.as_wit.iface0)]
|
||||
// CHECK:STDOUT: %Animal.facet.loc12_14.3: %Animal.type = facet_value %W.as_type.loc11_44.2, (%W.as_wit.iface0) [symbolic = %Animal.facet.loc12_14.3 (constants.%Animal.facet)]
|
||||
// CHECK:STDOUT: %Eats.lookup_impl_witness: <witness> = lookup_impl_witness %W.loc11_22.2, @Eats [symbolic = %Eats.lookup_impl_witness (constants.%Eats.lookup_impl_witness)]
|
||||
// CHECK:STDOUT: %W.as_wit.iface1.loc12_14.3: <witness> = facet_access_witness %W.loc11_22.2, element1 [symbolic = %W.as_wit.iface1.loc12_14.3 (constants.%W.as_wit.iface1)]
|
||||
// CHECK:STDOUT: %facet_value.loc12_14.3: %facet_type.6ff = facet_value %W.as_type.loc11_44.2, (%Eats.lookup_impl_witness, %W.as_wit.iface1.loc12_14.3) [symbolic = %facet_value.loc12_14.3 (constants.%facet_value)]
|
||||
@@ -932,16 +932,14 @@ fn CallsWithTypeExplicit(U:! type) {
|
||||
// CHECK:STDOUT: %w.ref: @HandleTameAnimal2.%W.as_type.loc11_44.2 (%W.as_type) = name_ref w, %w
|
||||
// CHECK:STDOUT: %W.as_type.loc12_14.1: type = facet_access_type constants.%W [symbolic = %W.as_type.loc11_44.2 (constants.%W.as_type)]
|
||||
// CHECK:STDOUT: %.loc12_14.1: type = converted constants.%W, %W.as_type.loc12_14.1 [symbolic = %W.as_type.loc11_44.2 (constants.%W.as_type)]
|
||||
// CHECK:STDOUT: %W.as_wit.iface0.loc12_14.1: <witness> = facet_access_witness constants.%W, element0 [symbolic = %W.as_wit.iface0.loc12_14.3 (constants.%W.as_wit.iface0)]
|
||||
// CHECK:STDOUT: %Animal.facet.loc12_14.1: %Animal.type = facet_value constants.%W.as_type, (%W.as_wit.iface0.loc12_14.1) [symbolic = %Animal.facet.loc12_14.3 (constants.%Animal.facet)]
|
||||
// CHECK:STDOUT: %Animal.facet.loc12_14.1: %Animal.type = facet_value constants.%W.as_type, (constants.%W.as_wit.iface0) [symbolic = %Animal.facet.loc12_14.3 (constants.%Animal.facet)]
|
||||
// CHECK:STDOUT: %.loc12_14.2: %Animal.type = converted %.loc12_14.1, %Animal.facet.loc12_14.1 [symbolic = %Animal.facet.loc12_14.3 (constants.%Animal.facet)]
|
||||
// CHECK:STDOUT: %W.as_wit.iface1.loc12_14.1: <witness> = facet_access_witness constants.%W, element1 [symbolic = %W.as_wit.iface1.loc12_14.3 (constants.%W.as_wit.iface1)]
|
||||
// CHECK:STDOUT: %facet_value.loc12_14.1: %facet_type.6ff = facet_value constants.%W.as_type, (constants.%Eats.lookup_impl_witness, %W.as_wit.iface1.loc12_14.1) [symbolic = %facet_value.loc12_14.3 (constants.%facet_value)]
|
||||
// CHECK:STDOUT: %.loc12_14.3: %facet_type.6ff = converted constants.%W.as_type, %facet_value.loc12_14.1 [symbolic = %facet_value.loc12_14.3 (constants.%facet_value)]
|
||||
// CHECK:STDOUT: %W.as_type.loc12_14.2: type = facet_access_type constants.%W [symbolic = %W.as_type.loc11_44.2 (constants.%W.as_type)]
|
||||
// CHECK:STDOUT: %.loc12_14.4: type = converted constants.%W, %W.as_type.loc12_14.2 [symbolic = %W.as_type.loc11_44.2 (constants.%W.as_type)]
|
||||
// CHECK:STDOUT: %W.as_wit.iface0.loc12_14.2: <witness> = facet_access_witness constants.%W, element0 [symbolic = %W.as_wit.iface0.loc12_14.3 (constants.%W.as_wit.iface0)]
|
||||
// CHECK:STDOUT: %Animal.facet.loc12_14.2: %Animal.type = facet_value constants.%W.as_type, (%W.as_wit.iface0.loc12_14.2) [symbolic = %Animal.facet.loc12_14.3 (constants.%Animal.facet)]
|
||||
// CHECK:STDOUT: %Animal.facet.loc12_14.2: %Animal.type = facet_value constants.%W.as_type, (constants.%W.as_wit.iface0) [symbolic = %Animal.facet.loc12_14.3 (constants.%Animal.facet)]
|
||||
// CHECK:STDOUT: %.loc12_14.5: %Animal.type = converted %.loc12_14.4, %Animal.facet.loc12_14.2 [symbolic = %Animal.facet.loc12_14.3 (constants.%Animal.facet)]
|
||||
// CHECK:STDOUT: %W.as_wit.iface1.loc12_14.2: <witness> = facet_access_witness constants.%W, element1 [symbolic = %W.as_wit.iface1.loc12_14.3 (constants.%W.as_wit.iface1)]
|
||||
// CHECK:STDOUT: %facet_value.loc12_14.2: %facet_type.6ff = facet_value constants.%W.as_type, (constants.%Eats.lookup_impl_witness, %W.as_wit.iface1.loc12_14.2) [symbolic = %facet_value.loc12_14.3 (constants.%facet_value)]
|
||||
|
||||
+5
-7
@@ -335,9 +335,9 @@ fn F() {
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete.loc31_45: <witness> = require_complete_type @HandleAnimal.%T.as_type.loc31_47.2 (%T.as_type.2ad) [symbolic = %require_complete.loc31_45 (constants.%require_complete.234)]
|
||||
// CHECK:STDOUT: %require_complete.loc31_54: <witness> = require_complete_type @HandleAnimal.%Food.as_type.loc31_56.2 (%Food.as_type.fae) [symbolic = %require_complete.loc31_54 (constants.%require_complete.444)]
|
||||
// CHECK:STDOUT: %Eats.type.2: type = facet_type <@Eats, @Eats(%Food.as_type.loc31_56.2)> [symbolic = %Eats.type.2 (constants.%Eats.type.f54c3d.2)]
|
||||
// CHECK:STDOUT: %Eats.lookup_impl_witness: <witness> = lookup_impl_witness %T.loc31_17.2, @Eats, @Eats(%Food.as_type.loc31_56.2) [symbolic = %Eats.lookup_impl_witness (constants.%Eats.lookup_impl_witness)]
|
||||
// CHECK:STDOUT: %Eats.facet.loc31_76.2: @HandleAnimal.%Eats.type.2 (%Eats.type.f54c3d.2) = facet_value %T.as_type.loc31_47.2, (%Eats.lookup_impl_witness) [symbolic = %Eats.facet.loc31_76.2 (constants.%Eats.facet.512)]
|
||||
// CHECK:STDOUT: %Eats.type: type = facet_type <@Eats, @Eats(%Food.as_type.loc31_56.2)> [symbolic = %Eats.type (constants.%Eats.type.f54c3d.2)]
|
||||
// CHECK:STDOUT: %Eats.facet.loc31_76.2: @HandleAnimal.%Eats.type (%Eats.type.f54c3d.2) = facet_value %T.as_type.loc31_47.2, (%Eats.lookup_impl_witness) [symbolic = %Eats.facet.loc31_76.2 (constants.%Eats.facet.512)]
|
||||
// CHECK:STDOUT: %Feed.specific_fn.loc31_64.2: <specific function> = specific_function constants.%Feed, @Feed(%Food.loc31_29.2, %Eats.facet.loc31_76.2) [symbolic = %Feed.specific_fn.loc31_64.2 (constants.%Feed.specific_fn.ea3)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.patt.loc31_17.1: %Animal.type, %Food.patt.loc31_29.1: %Edible.type](%a.param_patt: @HandleAnimal.%T.as_type.loc31_47.2 (%T.as_type.2ad), %food.param_patt: @HandleAnimal.%Food.as_type.loc31_56.2 (%Food.as_type.fae)) {
|
||||
@@ -347,14 +347,12 @@ fn F() {
|
||||
// CHECK:STDOUT: %food.ref: @HandleAnimal.%Food.as_type.loc31_56.2 (%Food.as_type.fae) = name_ref food, %food
|
||||
// CHECK:STDOUT: %.loc31_76.1: %Edible.type = converted constants.%Food.as_type.fae, constants.%Food.5fe [symbolic = %Food.loc31_29.2 (constants.%Food.5fe)]
|
||||
// CHECK:STDOUT: %.loc31_76.2: %Edible.type = converted constants.%Food.as_type.fae, constants.%Food.5fe [symbolic = %Food.loc31_29.2 (constants.%Food.5fe)]
|
||||
// CHECK:STDOUT: %Food.as_type.1: type = facet_access_type constants.%Food.5fe [symbolic = %Food.as_type.loc31_56.2 (constants.%Food.as_type.fae)]
|
||||
// CHECK:STDOUT: %Eats.type.1: type = facet_type <@Eats, @Eats(constants.%Food.as_type.fae)> [symbolic = %Eats.type.2 (constants.%Eats.type.f54c3d.2)]
|
||||
// CHECK:STDOUT: %.loc31_76.3: %Edible.type = converted constants.%Food.as_type.fae, constants.%Food.5fe [symbolic = %Food.loc31_29.2 (constants.%Food.5fe)]
|
||||
// CHECK:STDOUT: %T.as_type.loc31_76: type = facet_access_type constants.%T.fd4 [symbolic = %T.as_type.loc31_47.2 (constants.%T.as_type.2ad)]
|
||||
// CHECK:STDOUT: %.loc31_76.4: type = converted constants.%T.fd4, %T.as_type.loc31_76 [symbolic = %T.as_type.loc31_47.2 (constants.%T.as_type.2ad)]
|
||||
// CHECK:STDOUT: %.loc31_76.5: %Animal.type = converted %.loc31_76.4, constants.%T.fd4 [symbolic = %T.loc31_17.2 (constants.%T.fd4)]
|
||||
// CHECK:STDOUT: %Eats.facet.loc31_76.1: @HandleAnimal.%Eats.type.2 (%Eats.type.f54c3d.2) = facet_value constants.%T.as_type.2ad, (constants.%Eats.lookup_impl_witness) [symbolic = %Eats.facet.loc31_76.2 (constants.%Eats.facet.512)]
|
||||
// CHECK:STDOUT: %.loc31_76.6: @HandleAnimal.%Eats.type.2 (%Eats.type.f54c3d.2) = converted constants.%T.as_type.2ad, %Eats.facet.loc31_76.1 [symbolic = %Eats.facet.loc31_76.2 (constants.%Eats.facet.512)]
|
||||
// CHECK:STDOUT: %Eats.facet.loc31_76.1: @HandleAnimal.%Eats.type (%Eats.type.f54c3d.2) = facet_value constants.%T.as_type.2ad, (constants.%Eats.lookup_impl_witness) [symbolic = %Eats.facet.loc31_76.2 (constants.%Eats.facet.512)]
|
||||
// CHECK:STDOUT: %.loc31_76.6: @HandleAnimal.%Eats.type (%Eats.type.f54c3d.2) = converted constants.%T.as_type.2ad, %Eats.facet.loc31_76.1 [symbolic = %Eats.facet.loc31_76.2 (constants.%Eats.facet.512)]
|
||||
// CHECK:STDOUT: %Feed.specific_fn.loc31_64.1: <specific function> = specific_function %Feed.ref, @Feed(constants.%Food.5fe, constants.%Eats.facet.512) [symbolic = %Feed.specific_fn.loc31_64.2 (constants.%Feed.specific_fn.ea3)]
|
||||
// CHECK:STDOUT: %Feed.call: init %empty_tuple.type = call %Feed.specific_fn.loc31_64.1(%a.ref, %food.ref)
|
||||
// CHECK:STDOUT: return
|
||||
@@ -497,8 +495,8 @@ fn F() {
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete.loc31_45 => constants.%complete_type.357
|
||||
// CHECK:STDOUT: %require_complete.loc31_54 => constants.%complete_type.357
|
||||
// CHECK:STDOUT: %Eats.type.2 => constants.%Eats.type.1ae
|
||||
// CHECK:STDOUT: %Eats.lookup_impl_witness => constants.%impl_witness.4f1
|
||||
// CHECK:STDOUT: %Eats.type => constants.%Eats.type.1ae
|
||||
// CHECK:STDOUT: %Eats.facet.loc31_76.2 => constants.%Eats.facet.fa6
|
||||
// CHECK:STDOUT: %Feed.specific_fn.loc31_64.2 => constants.%Feed.specific_fn.d82
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
Vendored
-1
@@ -210,7 +210,6 @@ fn G() {
|
||||
// CHECK:STDOUT: %CallGenericMethod.ref: %CallGenericMethod.type = name_ref CallGenericMethod, file.%CallGenericMethod.decl [concrete = constants.%CallGenericMethod]
|
||||
// CHECK:STDOUT: %WrongGenericParam.ref: type = name_ref WrongGenericParam, file.%WrongGenericParam.decl [concrete = constants.%WrongGenericParam]
|
||||
// CHECK:STDOUT: %ImplsGeneric.ref: type = name_ref ImplsGeneric, file.%ImplsGeneric.decl [concrete = constants.%ImplsGeneric]
|
||||
// CHECK:STDOUT: %Generic.type: type = facet_type <@Generic, @Generic(constants.%WrongGenericParam)> [concrete = constants.%Generic.type.c3b]
|
||||
// CHECK:STDOUT: %CallGenericMethod.specific_fn: <specific function> = specific_function %CallGenericMethod.ref, @CallGenericMethod(constants.%WrongGenericParam, <error>) [concrete = <error>]
|
||||
// CHECK:STDOUT: %CallGenericMethod.call: init %empty_tuple.type = call %CallGenericMethod.specific_fn() [concrete = <error>]
|
||||
// CHECK:STDOUT: return
|
||||
|
||||
Vendored
-1
@@ -304,7 +304,6 @@ fn G(holds_to: HoldsType((RuntimeConvertTo, ))) {
|
||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
|
||||
// CHECK:STDOUT: %from.ref: %RuntimeConvertFrom = name_ref from, %from [symbolic = constants.%from]
|
||||
// CHECK:STDOUT: %holds_to.ref: %HoldsType.066 = name_ref holds_to, %holds_to
|
||||
// CHECK:STDOUT: %tuple.elem0: type = tuple_access constants.%tuple, element0 [concrete = constants.%RuntimeConvertTo]
|
||||
// CHECK:STDOUT: %impl.elem0: %.31e = impl_witness_access constants.%impl_witness, element0 [concrete = constants.%Convert.e81]
|
||||
// CHECK:STDOUT: %bound_method: <bound method> = bound_method constants.%from, %impl.elem0 [symbolic = constants.%Convert.bound]
|
||||
// CHECK:STDOUT: %.loc40_19.1: ref %RuntimeConvertTo = temporary_storage
|
||||
|
||||
@@ -273,7 +273,6 @@ fn G() {
|
||||
// CHECK:STDOUT: %CallGenericMethod.ref: %CallGenericMethod.type = name_ref CallGenericMethod, file.%CallGenericMethod.decl [concrete = constants.%CallGenericMethod]
|
||||
// CHECK:STDOUT: %GenericParam.ref: type = name_ref GenericParam, file.%GenericParam.decl [concrete = constants.%GenericParam]
|
||||
// CHECK:STDOUT: %ImplsGeneric.ref: type = name_ref ImplsGeneric, file.%ImplsGeneric.decl [concrete = constants.%ImplsGeneric]
|
||||
// CHECK:STDOUT: %Generic.type: type = facet_type <@Generic, @Generic(constants.%GenericParam)> [concrete = constants.%Generic.type.769]
|
||||
// CHECK:STDOUT: %Generic.facet: %Generic.type.769 = facet_value constants.%ImplsGeneric, (constants.%impl_witness.b42) [concrete = constants.%Generic.facet.8bd]
|
||||
// CHECK:STDOUT: %.loc34: %Generic.type.769 = converted constants.%ImplsGeneric, %Generic.facet [concrete = constants.%Generic.facet.8bd]
|
||||
// CHECK:STDOUT: %CallGenericMethod.specific_fn: <specific function> = specific_function %CallGenericMethod.ref, @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet.8bd) [concrete = constants.%CallGenericMethod.specific_fn]
|
||||
|
||||
+5
-33
@@ -559,8 +559,6 @@ fn F() {
|
||||
// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc]
|
||||
// CHECK:STDOUT: %impl.elem0.loc9_46: %.f1a = impl_witness_access constants.%impl_witness.01d, element0 [concrete = constants.%Op.c82]
|
||||
// CHECK:STDOUT: %bound_method.loc9_46.1: <bound method> = bound_method %u.ref, %impl.elem0.loc9_46
|
||||
// CHECK:STDOUT: %i32.1: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %i32.2: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %specific_fn.loc9_46: <specific function> = specific_function %impl.elem0.loc9_46, @Op.2(constants.%int_32) [concrete = constants.%Op.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc9_46.2: <bound method> = bound_method %u.ref, %specific_fn.loc9_46
|
||||
// CHECK:STDOUT: %impl.elem0.loc9_48: %.be7 = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956]
|
||||
@@ -820,8 +818,6 @@ fn F() {
|
||||
// CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba]
|
||||
// CHECK:STDOUT: %impl.elem0.loc11_34: %.f1a = impl_witness_access constants.%impl_witness.01d, element0 [concrete = constants.%Op.c82]
|
||||
// CHECK:STDOUT: %bound_method.loc11_34.1: <bound method> = bound_method %u.ref, %impl.elem0.loc11_34
|
||||
// CHECK:STDOUT: %i32.1: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %i32.2: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %specific_fn.loc11_34: <specific function> = specific_function %impl.elem0.loc11_34, @Op.2(constants.%int_32) [concrete = constants.%Op.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc11_34.2: <bound method> = bound_method %u.ref, %specific_fn.loc11_34
|
||||
// CHECK:STDOUT: %impl.elem0.loc11_36: %.be7 = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956]
|
||||
@@ -1232,8 +1228,6 @@ fn F() {
|
||||
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
|
||||
// CHECK:STDOUT: %impl.elem0.loc12_16: %.f1a = impl_witness_access constants.%impl_witness.01d, element0 [concrete = constants.%Op.c82]
|
||||
// CHECK:STDOUT: %bound_method.loc12_16.1: <bound method> = bound_method %u.ref, %impl.elem0.loc12_16
|
||||
// CHECK:STDOUT: %i32.1: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %i32.2: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %specific_fn.loc12_16: <specific function> = specific_function %impl.elem0.loc12_16, @Op.2(constants.%int_32) [concrete = constants.%Op.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc12_16.2: <bound method> = bound_method %u.ref, %specific_fn.loc12_16
|
||||
// CHECK:STDOUT: %impl.elem0.loc12_18: %.be7 = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956]
|
||||
@@ -1255,8 +1249,6 @@ fn F() {
|
||||
// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc]
|
||||
// CHECK:STDOUT: %impl.elem0.loc15_16: %.f1a = impl_witness_access constants.%impl_witness.01d, element0 [concrete = constants.%Op.c82]
|
||||
// CHECK:STDOUT: %bound_method.loc15_16.1: <bound method> = bound_method %v.ref, %impl.elem0.loc15_16
|
||||
// CHECK:STDOUT: %i32.1: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %i32.2: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %specific_fn.loc15_16: <specific function> = specific_function %impl.elem0.loc15_16, @Op.2(constants.%int_32) [concrete = constants.%Op.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc15_16.2: <bound method> = bound_method %v.ref, %specific_fn.loc15_16
|
||||
// CHECK:STDOUT: %impl.elem0.loc15_18: %.be7 = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956]
|
||||
@@ -1404,10 +1396,6 @@ fn F() {
|
||||
// CHECK:STDOUT: %T.as_wit.iface0.loc25: <witness> = facet_access_witness constants.%T, element0 [symbolic = %T.as_wit.iface0.loc24_34.2 (constants.%T.as_wit.iface0)]
|
||||
// CHECK:STDOUT: %impl.elem1.loc25_11.1: @GenericCallF.%.loc25_11.2 (%.4d2) = impl_witness_access %T.as_wit.iface0.loc25, element1 [symbolic = %impl.elem1.loc25_11.2 (constants.%impl.elem1)]
|
||||
// CHECK:STDOUT: %u.ref: @GenericCallF.%impl.elem0.loc24_34.2 (%impl.elem0.d9c3a6.2) = name_ref u, %u
|
||||
// CHECK:STDOUT: %as_wit.iface0.1: <witness> = facet_access_witness constants.%J.facet.085e97.2, element0 [symbolic = %T.as_wit.iface0.loc24_34.2 (constants.%T.as_wit.iface0)]
|
||||
// CHECK:STDOUT: %impl.elem0.1: type = impl_witness_access constants.%T.as_wit.iface0, element0 [symbolic = %impl.elem0.loc24_34.2 (constants.%impl.elem0.d9c3a6.2)]
|
||||
// CHECK:STDOUT: %as_wit.iface0.2: <witness> = facet_access_witness constants.%J.facet.085e97.2, element0 [symbolic = %T.as_wit.iface0.loc24_34.2 (constants.%T.as_wit.iface0)]
|
||||
// CHECK:STDOUT: %impl.elem0.2: type = impl_witness_access constants.%T.as_wit.iface0, element0 [symbolic = %impl.elem0.loc24_34.2 (constants.%impl.elem0.d9c3a6.2)]
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc25_11.1: <specific function> = specific_impl_function %impl.elem1.loc25_11.1, @F.1(constants.%J.facet.085e97.2) [symbolic = %specific_impl_fn.loc25_11.2 (constants.%specific_impl_fn)]
|
||||
// CHECK:STDOUT: %.loc25_15: init @GenericCallF.%impl.elem0.loc24_34.2 (%impl.elem0.d9c3a6.2) = call %specific_impl_fn.loc25_11.1(%u.ref)
|
||||
// CHECK:STDOUT: %.loc25_16.1: @GenericCallF.%impl.elem0.loc24_34.2 (%impl.elem0.d9c3a6.2) = value_of_initializer %.loc25_15
|
||||
@@ -1683,11 +1671,7 @@ fn F() {
|
||||
// CHECK:STDOUT: %impl.elem1.loc9_11.1: @GenericAddResult.%.loc9_11.2 (%.4d2) = impl_witness_access %T.as_wit.iface0.loc9_11, element1 [symbolic = %impl.elem1.loc9_11.2 (constants.%impl.elem1)]
|
||||
// CHECK:STDOUT: %u.ref.loc9_14: @GenericAddResult.%as_type.loc8_38.2 (%as_type.6b96b1.2) = name_ref u, %u
|
||||
// CHECK:STDOUT: %.loc9_15.1: %Add.type = converted constants.%as_type.6b96b1.2, constants.%impl.elem0.c57618.2 [symbolic = %impl.elem0.loc8_38.2 (constants.%impl.elem0.c57618.2)]
|
||||
// CHECK:STDOUT: %as_wit.iface0.1: <witness> = facet_access_witness constants.%J.facet.085e97.2, element0 [symbolic = %T.as_wit.iface0.loc8_38.2 (constants.%T.as_wit.iface0)]
|
||||
// CHECK:STDOUT: %impl.elem0.1: %Add.type = impl_witness_access constants.%T.as_wit.iface0, element0 [symbolic = %impl.elem0.loc8_38.2 (constants.%impl.elem0.c57618.2)]
|
||||
// CHECK:STDOUT: %.loc9_15.2: %Add.type = converted constants.%as_type.6b96b1.2, constants.%impl.elem0.c57618.2 [symbolic = %impl.elem0.loc8_38.2 (constants.%impl.elem0.c57618.2)]
|
||||
// CHECK:STDOUT: %as_wit.iface0.2: <witness> = facet_access_witness constants.%J.facet.085e97.2, element0 [symbolic = %T.as_wit.iface0.loc8_38.2 (constants.%T.as_wit.iface0)]
|
||||
// CHECK:STDOUT: %impl.elem0.2: %Add.type = impl_witness_access constants.%T.as_wit.iface0, element0 [symbolic = %impl.elem0.loc8_38.2 (constants.%impl.elem0.c57618.2)]
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc9_11.1: <specific function> = specific_impl_function %impl.elem1.loc9_11.1, @F(constants.%J.facet.085e97.2) [symbolic = %specific_impl_fn.loc9_11.2 (constants.%specific_impl_fn.5d8)]
|
||||
// CHECK:STDOUT: %.loc9_15.3: init @GenericAddResult.%as_type.loc8_38.2 (%as_type.6b96b1.2) = call %specific_impl_fn.loc9_11.1(%u.ref.loc9_14)
|
||||
// CHECK:STDOUT: %T.ref.loc9: %J.type = name_ref T, %T.loc8_21.1 [symbolic = %T.loc8_21.2 (constants.%T)]
|
||||
@@ -1698,11 +1682,7 @@ fn F() {
|
||||
// CHECK:STDOUT: %impl.elem1.loc9_20: @GenericAddResult.%.loc9_11.2 (%.4d2) = impl_witness_access %T.as_wit.iface0.loc9_20, element1 [symbolic = %impl.elem1.loc9_11.2 (constants.%impl.elem1)]
|
||||
// CHECK:STDOUT: %u.ref.loc9_23: @GenericAddResult.%as_type.loc8_38.2 (%as_type.6b96b1.2) = name_ref u, %u
|
||||
// CHECK:STDOUT: %.loc9_24.1: %Add.type = converted constants.%as_type.6b96b1.2, constants.%impl.elem0.c57618.2 [symbolic = %impl.elem0.loc8_38.2 (constants.%impl.elem0.c57618.2)]
|
||||
// CHECK:STDOUT: %as_wit.iface0.3: <witness> = facet_access_witness constants.%J.facet.085e97.2, element0 [symbolic = %T.as_wit.iface0.loc8_38.2 (constants.%T.as_wit.iface0)]
|
||||
// CHECK:STDOUT: %impl.elem0.3: %Add.type = impl_witness_access constants.%T.as_wit.iface0, element0 [symbolic = %impl.elem0.loc8_38.2 (constants.%impl.elem0.c57618.2)]
|
||||
// CHECK:STDOUT: %.loc9_24.2: %Add.type = converted constants.%as_type.6b96b1.2, constants.%impl.elem0.c57618.2 [symbolic = %impl.elem0.loc8_38.2 (constants.%impl.elem0.c57618.2)]
|
||||
// CHECK:STDOUT: %as_wit.iface0.4: <witness> = facet_access_witness constants.%J.facet.085e97.2, element0 [symbolic = %T.as_wit.iface0.loc8_38.2 (constants.%T.as_wit.iface0)]
|
||||
// CHECK:STDOUT: %impl.elem0.4: %Add.type = impl_witness_access constants.%T.as_wit.iface0, element0 [symbolic = %impl.elem0.loc8_38.2 (constants.%impl.elem0.c57618.2)]
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc9_20: <specific function> = specific_impl_function %impl.elem1.loc9_20, @F(constants.%J.facet.085e97.2) [symbolic = %specific_impl_fn.loc9_11.2 (constants.%specific_impl_fn.5d8)]
|
||||
// CHECK:STDOUT: %.loc9_24.3: init @GenericAddResult.%as_type.loc8_38.2 (%as_type.6b96b1.2) = call %specific_impl_fn.loc9_20(%u.ref.loc9_23)
|
||||
// CHECK:STDOUT: %as_wit.iface0.loc9_17.1: <witness> = facet_access_witness constants.%impl.elem0.c57618.2, element0 [symbolic = %as_wit.iface0.loc9_17.2 (constants.%as_wit.iface0)]
|
||||
@@ -1916,10 +1896,6 @@ fn F() {
|
||||
// CHECK:STDOUT: %impl.elem1.loc9_11.1: @GenericCallInterfaceQualified.%.loc9_11 (%.9ac) = impl_witness_access %T.as_wit.iface0.loc9, element1 [symbolic = %impl.elem1.loc9_11.2 (constants.%impl.elem1)]
|
||||
// CHECK:STDOUT: %bound_method.loc9_11: <bound method> = bound_method %t.ref, %impl.elem1.loc9_11.1
|
||||
// CHECK:STDOUT: %u.ref: @GenericCallInterfaceQualified.%impl.elem0.loc8_51.2 (%impl.elem0.d9c3a6.2) = name_ref u, %u
|
||||
// CHECK:STDOUT: %as_wit.iface0.1: <witness> = facet_access_witness constants.%J.facet.085e97.2, element0 [symbolic = %T.as_wit.iface0.loc8_51.2 (constants.%T.as_wit.iface0)]
|
||||
// CHECK:STDOUT: %impl.elem0.1: type = impl_witness_access constants.%T.as_wit.iface0, element0 [symbolic = %impl.elem0.loc8_51.2 (constants.%impl.elem0.d9c3a6.2)]
|
||||
// CHECK:STDOUT: %as_wit.iface0.2: <witness> = facet_access_witness constants.%J.facet.085e97.2, element0 [symbolic = %T.as_wit.iface0.loc8_51.2 (constants.%T.as_wit.iface0)]
|
||||
// CHECK:STDOUT: %impl.elem0.2: type = impl_witness_access constants.%T.as_wit.iface0, element0 [symbolic = %impl.elem0.loc8_51.2 (constants.%impl.elem0.d9c3a6.2)]
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc9_11.1: <specific function> = specific_impl_function %impl.elem1.loc9_11.1, @G(constants.%J.facet.085e97.2) [symbolic = %specific_impl_fn.loc9_11.2 (constants.%specific_impl_fn)]
|
||||
// CHECK:STDOUT: %bound_method.loc9_19: <bound method> = bound_method %t.ref, %specific_impl_fn.loc9_11.1
|
||||
// CHECK:STDOUT: %.loc9_19: init @GenericCallInterfaceQualified.%impl.elem0.loc8_51.2 (%impl.elem0.d9c3a6.2) = call %bound_method.loc9_19(%t.ref, %u.ref)
|
||||
@@ -2109,10 +2085,10 @@ fn F() {
|
||||
// CHECK:STDOUT: %J.facet: %J.type = facet_value %T.as_type.loc8_45.2, (%T.as_wit.iface0.loc26_11.2) [symbolic = %J.facet (constants.%J.facet.869)]
|
||||
// CHECK:STDOUT: %.loc26_11.2: type = fn_type_with_self_type constants.%F.type, %J.facet [symbolic = %.loc26_11.2 (constants.%.861)]
|
||||
// CHECK:STDOUT: %impl.elem1.loc26_11.2: @GenericCallFI32.%.loc26_11.2 (%.861) = impl_witness_access %T.as_wit.iface0.loc26_11.2, element1 [symbolic = %impl.elem1.loc26_11.2 (constants.%impl.elem1)]
|
||||
// CHECK:STDOUT: %impl.elem0.3: type = impl_witness_access %T.as_wit.iface0.loc26_11.2, element0 [symbolic = %impl.elem0.3 (constants.%impl.elem0.37e)]
|
||||
// CHECK:STDOUT: %impl.elem0.1: type = impl_witness_access %T.as_wit.iface0.loc26_11.2, element0 [symbolic = %impl.elem0.1 (constants.%impl.elem0.37e)]
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc26_11.2: <specific function> = specific_impl_function %impl.elem1.loc26_11.2, @F(%J.facet) [symbolic = %specific_impl_fn.loc26_11.2 (constants.%specific_impl_fn)]
|
||||
// CHECK:STDOUT: %require_complete.loc26_15: <witness> = require_complete_type @GenericCallFI32.%impl.elem0.3 (%impl.elem0.37e) [symbolic = %require_complete.loc26_15 (constants.%require_complete.8bd)]
|
||||
// CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(%impl.elem0.3)> [symbolic = %ImplicitAs.type (constants.%ImplicitAs.type.820)]
|
||||
// CHECK:STDOUT: %require_complete.loc26_15: <witness> = require_complete_type @GenericCallFI32.%impl.elem0.1 (%impl.elem0.37e) [symbolic = %require_complete.loc26_15 (constants.%require_complete.8bd)]
|
||||
// CHECK:STDOUT: %ImplicitAs.type: type = facet_type <@ImplicitAs, @ImplicitAs(%impl.elem0.1)> [symbolic = %ImplicitAs.type (constants.%ImplicitAs.type.820)]
|
||||
// CHECK:STDOUT: %require_complete.loc26_14: <witness> = require_complete_type @GenericCallFI32.%ImplicitAs.type (%ImplicitAs.type.820) [symbolic = %require_complete.loc26_14 (constants.%require_complete.1ce)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn[%T.patt.loc8_20.1: %J_where.type](%t.param_patt: @GenericCallFI32.%T.as_type.loc8_45.2 (%T.as_type)) -> %i32 {
|
||||
@@ -2124,13 +2100,9 @@ fn F() {
|
||||
// CHECK:STDOUT: %T.as_wit.iface0.loc26_11.1: <witness> = facet_access_witness constants.%T, element0 [symbolic = %T.as_wit.iface0.loc26_11.2 (constants.%T.as_wit.iface0)]
|
||||
// CHECK:STDOUT: %impl.elem1.loc26_11.1: @GenericCallFI32.%.loc26_11.2 (%.861) = impl_witness_access %T.as_wit.iface0.loc26_11.1, element1 [symbolic = %impl.elem1.loc26_11.2 (constants.%impl.elem1)]
|
||||
// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2]
|
||||
// CHECK:STDOUT: %as_wit.iface0.1: <witness> = facet_access_witness constants.%J.facet.869, element0 [symbolic = %T.as_wit.iface0.loc26_11.2 (constants.%T.as_wit.iface0)]
|
||||
// CHECK:STDOUT: %impl.elem0.1: type = impl_witness_access constants.%T.as_wit.iface0, element0 [symbolic = %impl.elem0.3 (constants.%impl.elem0.37e)]
|
||||
// CHECK:STDOUT: %as_wit.iface0.2: <witness> = facet_access_witness constants.%J.facet.869, element0 [symbolic = %T.as_wit.iface0.loc26_11.2 (constants.%T.as_wit.iface0)]
|
||||
// CHECK:STDOUT: %impl.elem0.2: type = impl_witness_access constants.%T.as_wit.iface0, element0 [symbolic = %impl.elem0.3 (constants.%impl.elem0.37e)]
|
||||
// CHECK:STDOUT: %specific_impl_fn.loc26_11.1: <specific function> = specific_impl_function %impl.elem1.loc26_11.1, @F(constants.%J.facet.869) [symbolic = %specific_impl_fn.loc26_11.2 (constants.%specific_impl_fn)]
|
||||
// CHECK:STDOUT: %.loc26_14: @GenericCallFI32.%impl.elem0.3 (%impl.elem0.37e) = converted %int_2, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %.loc26_15: init @GenericCallFI32.%impl.elem0.3 (%impl.elem0.37e) = call %specific_impl_fn.loc26_11.1(<error>) [concrete = <error>]
|
||||
// CHECK:STDOUT: %.loc26_14: @GenericCallFI32.%impl.elem0.1 (%impl.elem0.37e) = converted %int_2, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: %.loc26_15: init @GenericCallFI32.%impl.elem0.1 (%impl.elem0.37e) = call %specific_impl_fn.loc26_11.1(<error>) [concrete = <error>]
|
||||
// CHECK:STDOUT: %.loc26_16: %i32 = converted %.loc26_15, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: return <error>
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
@@ -86,6 +86,19 @@ enum class InstConstantKind : int8_t {
|
||||
Unique,
|
||||
};
|
||||
|
||||
// Whether constant evaluation of an instruction needs the instruction to have
|
||||
// been created and allocated an InstId, or only needs the instruction operands.
|
||||
enum class InstConstantNeedsInstIdKind : int8_t {
|
||||
// This instruction kind doesn't need an InstId to be evaluated.
|
||||
No,
|
||||
// This instruction needs an InstId during evaluation, but doesn't need the
|
||||
// instruction to persist after evaluation.
|
||||
DuringEvaluation,
|
||||
// This instruction needs a permanent instruction ID, for example because that
|
||||
// instruction ID can appear in the constant result of evaluation.
|
||||
Permanent,
|
||||
};
|
||||
|
||||
// Whether an instruction is a terminator or part of the terminator sequence.
|
||||
// The instructions in a block appear in the order NotTerminator, then
|
||||
// TerminatorSequence, then Terminator, which is also the numerical order of
|
||||
@@ -123,7 +136,10 @@ class InstKind : public CARBON_ENUM_BASE(InstKind) {
|
||||
llvm::StringLiteral ir_name;
|
||||
InstIsType is_type = InstIsType::Never;
|
||||
InstConstantKind constant_kind = InstConstantKind::Indirect;
|
||||
bool constant_needs_inst_id = constant_kind == InstConstantKind::Unique;
|
||||
InstConstantNeedsInstIdKind constant_needs_inst_id =
|
||||
constant_kind == InstConstantKind::Unique
|
||||
? InstConstantNeedsInstIdKind::Permanent
|
||||
: InstConstantNeedsInstIdKind::No;
|
||||
TerminatorKind terminator_kind = TerminatorKind::NotTerminator;
|
||||
bool is_lowered = true;
|
||||
bool deduce_through = false;
|
||||
@@ -173,7 +189,7 @@ class InstKind : public CARBON_ENUM_BASE(InstKind) {
|
||||
// location, for example for diagnostics or for newly-created instructions,
|
||||
// and for instructions whose evaluation needs to inspect the original form of
|
||||
// its operands.
|
||||
auto constant_needs_inst_id() const -> bool {
|
||||
auto constant_needs_inst_id() const -> InstConstantNeedsInstIdKind {
|
||||
return definition_info(*this).constant_needs_inst_id;
|
||||
}
|
||||
|
||||
@@ -192,6 +208,12 @@ class InstKind : public CARBON_ENUM_BASE(InstKind) {
|
||||
return definition_info(*this).deduce_through;
|
||||
}
|
||||
|
||||
// Returns true if this instruction has scoped cleanup associated, typically a
|
||||
// destructor.
|
||||
constexpr auto has_cleanup() const -> bool {
|
||||
return definition_info(*this).has_cleanup;
|
||||
}
|
||||
|
||||
private:
|
||||
// Returns the DefinitionInfo for the kind.
|
||||
static auto definition_info(InstKind kind) -> const DefinitionInfo&;
|
||||
@@ -232,7 +254,7 @@ class InstKind::Definition : public InstKind {
|
||||
}
|
||||
|
||||
// Returns whether constant evaluation of this instruction needs an InstId.
|
||||
constexpr auto constant_needs_inst_id() const -> bool {
|
||||
constexpr auto constant_needs_inst_id() const -> InstConstantNeedsInstIdKind {
|
||||
return info_.constant_needs_inst_id;
|
||||
}
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ struct ArrayType {
|
||||
{.ir_name = "array_type",
|
||||
.is_type = InstIsType::Always,
|
||||
.constant_kind = InstConstantKind::Conditional,
|
||||
.constant_needs_inst_id = true,
|
||||
.constant_needs_inst_id = InstConstantNeedsInstIdKind::DuringEvaluation,
|
||||
.deduce_through = true});
|
||||
|
||||
TypeId type_id;
|
||||
@@ -773,7 +773,7 @@ struct FloatType {
|
||||
{.ir_name = "float_type",
|
||||
.is_type = InstIsType::Always,
|
||||
.constant_kind = InstConstantKind::Conditional,
|
||||
.constant_needs_inst_id = true,
|
||||
.constant_needs_inst_id = InstConstantNeedsInstIdKind::DuringEvaluation,
|
||||
.deduce_through = true});
|
||||
|
||||
TypeId type_id;
|
||||
@@ -924,7 +924,8 @@ struct ImplWitnessAccess {
|
||||
{.ir_name = "impl_witness_access",
|
||||
.is_type = InstIsType::Maybe,
|
||||
.constant_kind = InstConstantKind::SymbolicOnly,
|
||||
.constant_needs_inst_id = true,
|
||||
.constant_needs_inst_id =
|
||||
InstConstantNeedsInstIdKind::DuringEvaluation,
|
||||
.is_lowered = false});
|
||||
|
||||
TypeId type_id;
|
||||
@@ -1108,7 +1109,7 @@ struct IntType {
|
||||
{.ir_name = "int_type",
|
||||
.is_type = InstIsType::Always,
|
||||
.constant_kind = InstConstantKind::Conditional,
|
||||
.constant_needs_inst_id = true,
|
||||
.constant_needs_inst_id = InstConstantNeedsInstIdKind::DuringEvaluation,
|
||||
.deduce_through = true});
|
||||
|
||||
TypeId type_id;
|
||||
@@ -1133,7 +1134,8 @@ struct LookupImplWitness {
|
||||
InstKind::LookupImplWitness.Define<Parse::NodeId>(
|
||||
{.ir_name = "lookup_impl_witness",
|
||||
.constant_kind = InstConstantKind::SymbolicOnly,
|
||||
.constant_needs_inst_id = true,
|
||||
.constant_needs_inst_id =
|
||||
InstConstantNeedsInstIdKind::DuringEvaluation,
|
||||
.is_lowered = false});
|
||||
|
||||
// Always the type of the builtin `WitnessType` singleton instruction.
|
||||
@@ -1337,7 +1339,8 @@ struct RequireCompleteType {
|
||||
InstKind::RequireCompleteType.Define<Parse::NodeId>(
|
||||
{.ir_name = "require_complete_type",
|
||||
.constant_kind = InstConstantKind::SymbolicOnly,
|
||||
.constant_needs_inst_id = true,
|
||||
.constant_needs_inst_id =
|
||||
InstConstantNeedsInstIdKind::DuringEvaluation,
|
||||
.is_lowered = false});
|
||||
// Always the builtin witness type.
|
||||
TypeId type_id;
|
||||
@@ -1477,7 +1480,8 @@ struct SpecificFunction {
|
||||
static constexpr auto Kind = InstKind::SpecificFunction.Define<Parse::NodeId>(
|
||||
{.ir_name = "specific_function",
|
||||
.constant_kind = InstConstantKind::Conditional,
|
||||
.constant_needs_inst_id = true});
|
||||
// InstId is added to definitions_required_by_use.
|
||||
.constant_needs_inst_id = InstConstantNeedsInstIdKind::Permanent});
|
||||
|
||||
// Always the builtin SpecificFunctionType.
|
||||
TypeId type_id;
|
||||
@@ -1514,7 +1518,8 @@ struct SpecificImplFunction {
|
||||
InstKind::SpecificImplFunction.Define<Parse::NodeId>(
|
||||
{.ir_name = "specific_impl_function",
|
||||
.constant_kind = InstConstantKind::SymbolicOnly,
|
||||
.constant_needs_inst_id = true});
|
||||
// InstId is added to definitions_required_by_use.
|
||||
.constant_needs_inst_id = InstConstantNeedsInstIdKind::Permanent});
|
||||
|
||||
// Always the builtin SpecificFunctionType.
|
||||
TypeId type_id;
|
||||
|
||||
Reference in New Issue
Block a user