mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 07:54:41 +01:00
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:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user