Assign locations to instructions in a generic eval block. (#4393)

The locations point to the first instruction in the generic that needed
the relevant constant value or type.

For now, this must makes the formatted SemIR a bit more useful, but in
the future it will also provide locations for diagnostics caused by
monomorphization failure.
This commit is contained in:
Richard Smith
2024-10-09 19:03:15 +00:00
committed by GitHub
parent b1366f3e4e
commit efb5d6d25a
70 changed files with 2719 additions and 2714 deletions
+13 -8
View File
@@ -9,6 +9,7 @@
#include "toolchain/check/generic_region_stack.h"
#include "toolchain/check/subst.h"
#include "toolchain/sem_ir/ids.h"
#include "toolchain/sem_ir/inst.h"
namespace Carbon::Check {
@@ -59,11 +60,12 @@ class RebuildGenericConstantInEvalBlockCallbacks final
public:
RebuildGenericConstantInEvalBlockCallbacks(
Context& context, SemIR::GenericId generic_id,
SemIR::GenericInstIndex::Region region,
SemIR::GenericInstIndex::Region region, SemIR::LocId loc_id,
ConstantsInGenericMap& constants_in_generic)
: context_(context),
generic_id_(generic_id),
region_(region),
loc_id_(loc_id),
constants_in_generic_(constants_in_generic) {}
// Check for instructions for which we already have a mapping into the eval
@@ -121,10 +123,10 @@ class RebuildGenericConstantInEvalBlockCallbacks final
// TODO: Add a function on `Context` to add the instruction without
// inserting it into the dependent instructions list or computing a
// constant value for it.
// TODO: Provide a location based on the location of the instruction
// that uses the constant.
// TODO: Is the location we pick here always appropriate for the new
// instruction?
auto inst_id = context_.sem_ir().insts().AddInNoBlock(
SemIR::LocIdAndInst::NoLoc(new_inst));
SemIR::LocIdAndInst::UncheckedLoc(loc_id_, new_inst));
auto const_id = AddGenericConstantInstToEvalBlock(
context_, generic_id_, region_, const_inst_id, inst_id);
context_.constant_values().Set(inst_id, const_id);
@@ -137,6 +139,7 @@ class RebuildGenericConstantInEvalBlockCallbacks final
Context& context_;
SemIR::GenericId generic_id_;
SemIR::GenericInstIndex::Region region_;
SemIR::LocId loc_id_;
ConstantsInGenericMap& constants_in_generic_;
};
} // namespace
@@ -147,7 +150,7 @@ class RebuildGenericConstantInEvalBlockCallbacks final
// type in each specific.
static auto AddGenericTypeToEvalBlock(
Context& context, SemIR::GenericId generic_id,
SemIR::GenericInstIndex::Region region,
SemIR::GenericInstIndex::Region region, SemIR::LocId loc_id,
ConstantsInGenericMap& constants_in_generic, SemIR::TypeId type_id)
-> SemIR::TypeId {
// Substitute into the type's constant instruction and rebuild it in the eval
@@ -155,7 +158,7 @@ static auto AddGenericTypeToEvalBlock(
auto type_inst_id =
SubstInst(context, context.types().GetInstId(type_id),
RebuildGenericConstantInEvalBlockCallbacks(
context, generic_id, region, constants_in_generic));
context, generic_id, region, loc_id, constants_in_generic));
return context.GetTypeIdForTypeInst(type_inst_id);
}
@@ -174,7 +177,8 @@ static auto AddGenericConstantToEvalBlock(
auto new_inst_id =
SubstInst(context, const_inst_id,
RebuildGenericConstantInEvalBlockCallbacks(
context, generic_id, region, constants_in_generic));
context, generic_id, region,
context.insts().GetLocId(inst_id), constants_in_generic));
CARBON_CHECK(new_inst_id != const_inst_id,
"Did not apply any substitutions to symbolic constant {0}",
context.insts().Get(const_inst_id));
@@ -227,7 +231,8 @@ static auto MakeGenericEvalBlock(Context& context, SemIR::GenericId generic_id,
GenericRegionStack::DependencyKind::None) {
auto inst = context.insts().Get(inst_id);
auto type_id = AddGenericTypeToEvalBlock(
context, generic_id, region, constants_in_generic, inst.type_id());
context, generic_id, region, context.insts().GetLocId(inst_id),
constants_in_generic, inst.type_id());
// TODO: Eventually, completeness requirements should be modeled as
// constraints on the generic rather than properties of the type. For now,
// require the transformed type to be complete if the original was.