mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-25 15:00:13 +01:00
Initialize specifics in-place. (#7717)
Don't wait until we reach the end of the eval block to set the value block on the specific. This is a prerequisite for allowing template actions to read from the specific.
This commit is contained in:
+19
-77
@@ -76,14 +76,11 @@ struct LocalEvalInfo {
|
|||||||
// `context` must not be null.
|
// `context` must not be null.
|
||||||
class EvalContext {
|
class EvalContext {
|
||||||
public:
|
public:
|
||||||
explicit EvalContext(
|
explicit EvalContext(Context* context, SemIR::LocId fallback_loc_id,
|
||||||
Context* context, SemIR::LocId fallback_loc_id,
|
SemIR::SpecificId specific_id = SemIR::SpecificId::None)
|
||||||
SemIR::SpecificId specific_id = SemIR::SpecificId::None,
|
|
||||||
std::optional<SpecificEvalInfo> specific_eval_info = std::nullopt)
|
|
||||||
: context_(context),
|
: context_(context),
|
||||||
fallback_loc_id_(fallback_loc_id),
|
fallback_loc_id_(fallback_loc_id),
|
||||||
specific_id_(specific_id),
|
specific_id_(specific_id) {}
|
||||||
specific_eval_info_(specific_eval_info) {}
|
|
||||||
|
|
||||||
EvalContext(const EvalContext&) = delete;
|
EvalContext(const EvalContext&) = delete;
|
||||||
auto operator=(const EvalContext&) -> EvalContext& = delete;
|
auto operator=(const EvalContext&) -> EvalContext& = delete;
|
||||||
@@ -156,29 +153,6 @@ class EvalContext {
|
|||||||
return constant_values().Get(args[binding_index]);
|
return constant_values().Get(args[binding_index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given information about a symbolic constant, determine its value in the
|
|
||||||
// currently-being-evaluated eval block, if it refers to that eval block. If
|
|
||||||
// we can't find a value in this way, returns `None`.
|
|
||||||
auto GetInEvaluatedSpecific(const SemIR::SymbolicConstant& symbolic_info)
|
|
||||||
-> SemIR::ConstantId {
|
|
||||||
if (!specific_eval_info_ || !symbolic_info.index.has_value()) {
|
|
||||||
return SemIR::ConstantId::None;
|
|
||||||
}
|
|
||||||
|
|
||||||
CARBON_CHECK(
|
|
||||||
symbolic_info.generic_id == specifics().Get(specific_id_).generic_id,
|
|
||||||
"Instruction has constant operand in wrong generic");
|
|
||||||
if (symbolic_info.index.region() != specific_eval_info_->region) {
|
|
||||||
return SemIR::ConstantId::None;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto inst_id = specific_eval_info_->values[symbolic_info.index.index()];
|
|
||||||
if (!inst_id.has_value()) {
|
|
||||||
return SemIR::ConstantId::NotConstant;
|
|
||||||
}
|
|
||||||
return constant_values().Get(inst_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gets the constant value of the specified instruction in this context.
|
// Gets the constant value of the specified instruction in this context.
|
||||||
auto GetConstantValue(SemIR::InstId inst_id) -> SemIR::ConstantId {
|
auto GetConstantValue(SemIR::InstId inst_id) -> SemIR::ConstantId {
|
||||||
auto const_id = constant_values().GetAttached(inst_id);
|
auto const_id = constant_values().GetAttached(inst_id);
|
||||||
@@ -194,41 +168,11 @@ class EvalContext {
|
|||||||
return const_id;
|
return const_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!const_id.is_symbolic()) {
|
|
||||||
return const_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// While resolving a specific, map from previous instructions in the eval
|
|
||||||
// block into their evaluated values. These values won't be present on the
|
|
||||||
// specific itself yet, so `GetConstantValueInSpecific` won't be able to
|
|
||||||
// find them.
|
|
||||||
const auto& symbolic_info = constant_values().GetSymbolicConstant(const_id);
|
|
||||||
if (auto eval_block_const_id = GetInEvaluatedSpecific(symbolic_info);
|
|
||||||
eval_block_const_id.has_value()) {
|
|
||||||
return eval_block_const_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetConstantValueInSpecific(sem_ir(), specific_id_, inst_id);
|
return GetConstantValueInSpecific(sem_ir(), specific_id_, inst_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the type of the specified instruction in this context.
|
// Gets the type of the specified instruction in this context.
|
||||||
auto GetTypeOfInst(SemIR::InstId inst_id) -> SemIR::TypeId {
|
auto GetTypeOfInst(SemIR::InstId inst_id) -> SemIR::TypeId {
|
||||||
auto type_id = insts().GetAttachedType(inst_id);
|
|
||||||
if (!type_id.is_symbolic()) {
|
|
||||||
return type_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// While resolving a specific, map from previous instructions in the eval
|
|
||||||
// block into their evaluated values. These values won't be present on the
|
|
||||||
// specific itself yet, so `GetTypeOfInstInSpecific` won't be able to
|
|
||||||
// find them.
|
|
||||||
const auto& symbolic_info =
|
|
||||||
constant_values().GetSymbolicConstant(types().GetConstantId(type_id));
|
|
||||||
if (auto eval_block_const_id = GetInEvaluatedSpecific(symbolic_info);
|
|
||||||
eval_block_const_id.has_value()) {
|
|
||||||
return types().GetTypeIdForTypeConstantId(eval_block_const_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetTypeOfInstInSpecific(sem_ir(), specific_id_, inst_id);
|
return GetTypeOfInstInSpecific(sem_ir(), specific_id_, inst_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,9 +242,6 @@ class EvalContext {
|
|||||||
SemIR::LocId fallback_loc_id_;
|
SemIR::LocId fallback_loc_id_;
|
||||||
// The specific that we are evaluating within.
|
// The specific that we are evaluating within.
|
||||||
SemIR::SpecificId specific_id_;
|
SemIR::SpecificId specific_id_;
|
||||||
// If we are currently evaluating an eval block for `specific_id_`,
|
|
||||||
// information about that evaluation.
|
|
||||||
std::optional<SpecificEvalInfo> specific_eval_info_;
|
|
||||||
// If we are currently evaluating within a local scope, values of local
|
// If we are currently evaluating within a local scope, values of local
|
||||||
// instructions that have already been evaluated. This is here rather than in
|
// instructions that have already been evaluated. This is here rather than in
|
||||||
// `FunctionEvalContext` so we can reference it from `GetConstantValue`.
|
// `FunctionEvalContext` so we can reference it from `GetConstantValue`.
|
||||||
@@ -3511,20 +3452,23 @@ auto TryEvalInstUnsafe(Context& context, SemIR::InstId inst_id,
|
|||||||
|
|
||||||
auto TryEvalBlockForSpecific(Context& context, SemIR::LocId loc_id,
|
auto TryEvalBlockForSpecific(Context& context, SemIR::LocId loc_id,
|
||||||
SemIR::SpecificId specific_id,
|
SemIR::SpecificId specific_id,
|
||||||
SemIR::GenericInstIndex::Region region)
|
SemIR::GenericInstIndex::Region region) -> void {
|
||||||
-> std::pair<SemIR::InstBlockId, bool> {
|
|
||||||
auto generic_id = context.specifics().Get(specific_id).generic_id;
|
auto generic_id = context.specifics().Get(specific_id).generic_id;
|
||||||
auto eval_block_id = context.generics().Get(generic_id).GetEvalBlock(region);
|
auto eval_block_id = context.generics().Get(generic_id).GetEvalBlock(region);
|
||||||
auto eval_block = context.inst_blocks().Get(eval_block_id);
|
auto eval_block = context.inst_blocks().Get(eval_block_id);
|
||||||
|
|
||||||
llvm::SmallVector<SemIR::InstId> result;
|
// Allocate the value block and store it back onto the specific, so that our
|
||||||
result.resize(eval_block.size(), SemIR::InstId::None);
|
// in-progress results are visible.
|
||||||
|
auto& specific = context.specifics().Get(specific_id);
|
||||||
|
auto value_block_id =
|
||||||
|
context.inst_blocks().AddUninitialized(eval_block.size());
|
||||||
|
auto value_block = context.inst_blocks().GetMutable(value_block_id);
|
||||||
|
for (auto& inst_id : value_block) {
|
||||||
|
inst_id = SemIR::InstId::None;
|
||||||
|
}
|
||||||
|
specific.SetValueBlock(region, value_block_id);
|
||||||
|
|
||||||
EvalContext eval_context(&context, loc_id, specific_id,
|
EvalContext eval_context(&context, loc_id, specific_id);
|
||||||
SpecificEvalInfo{
|
|
||||||
.region = region,
|
|
||||||
.values = result,
|
|
||||||
});
|
|
||||||
|
|
||||||
Diagnostics::ContextScope diagnostic_context(
|
Diagnostics::ContextScope diagnostic_context(
|
||||||
&context.emitter(), [&](auto& builder) {
|
&context.emitter(), [&](auto& builder) {
|
||||||
@@ -3534,19 +3478,17 @@ auto TryEvalBlockForSpecific(Context& context, SemIR::LocId loc_id,
|
|||||||
builder.Context(loc_id, ResolvingSpecificHere, specific_id);
|
builder.Context(loc_id, ResolvingSpecificHere, specific_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
bool has_error = false;
|
for (auto [i, inst_id, result_id] :
|
||||||
for (auto [i, inst_id] : llvm::enumerate(eval_block)) {
|
llvm::enumerate(eval_block, value_block)) {
|
||||||
auto const_id = TryEvalInstInContext(eval_context, inst_id,
|
auto const_id = TryEvalInstInContext(eval_context, inst_id,
|
||||||
context.insts().Get(inst_id));
|
context.insts().Get(inst_id));
|
||||||
CARBON_CHECK(const_id.has_value(), "Failed to evaluate {0} in eval block",
|
CARBON_CHECK(const_id.has_value(), "Failed to evaluate {0} in eval block",
|
||||||
context.insts().Get(inst_id));
|
context.insts().Get(inst_id));
|
||||||
if (const_id == SemIR::ErrorInst::ConstantId) {
|
if (const_id == SemIR::ErrorInst::ConstantId) {
|
||||||
has_error = true;
|
specific.SetHasError(region);
|
||||||
}
|
}
|
||||||
result[i] = context.constant_values().GetInstId(const_id);
|
result_id = context.constant_values().GetInstId(const_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {context.inst_blocks().Add(result), has_error};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Information about the function call we are currently executing. Unlike
|
// Information about the function call we are currently executing. Unlike
|
||||||
|
|||||||
@@ -50,13 +50,12 @@ auto TryEvalInst(Context& context, InstT inst) -> SemIR::ConstantId {
|
|||||||
return TryEvalInstUnsafe(context, SemIR::InstId::None, inst);
|
return TryEvalInstUnsafe(context, SemIR::InstId::None, inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluates the eval block for a region of a specific. Produces a block
|
// Evaluates the eval block for a region of a specific. Writes a block
|
||||||
// containing the evaluated constant values of the instructions in the eval
|
// containing the evaluated constant values of the instructions in the eval
|
||||||
// block. The returned bool indicates whether the region has an error.
|
// block to the specific.
|
||||||
auto TryEvalBlockForSpecific(Context& context, SemIR::LocId loc_id,
|
auto TryEvalBlockForSpecific(Context& context, SemIR::LocId loc_id,
|
||||||
SemIR::SpecificId specific_id,
|
SemIR::SpecificId specific_id,
|
||||||
SemIR::GenericInstIndex::Region region)
|
SemIR::GenericInstIndex::Region region) -> void;
|
||||||
-> std::pair<SemIR::InstBlockId, bool>;
|
|
||||||
|
|
||||||
} // namespace Carbon::Check
|
} // namespace Carbon::Check
|
||||||
|
|
||||||
|
|||||||
@@ -681,12 +681,8 @@ auto ResolveSpecificDecl(Context& context, SemIR::LocId loc_id,
|
|||||||
// block to form information about the specific.
|
// block to form information about the specific.
|
||||||
auto& specific = context.specifics().Get(specific_id);
|
auto& specific = context.specifics().Get(specific_id);
|
||||||
if (!specific.decl_block_id.has_value()) {
|
if (!specific.decl_block_id.has_value()) {
|
||||||
// Set a placeholder value as the decl block ID so we won't attempt to
|
TryEvalBlockForSpecific(context, loc_id, specific_id,
|
||||||
// recursively resolve the same specific.
|
SemIR::GenericInstIndex::Region::Declaration);
|
||||||
specific.decl_block_id = SemIR::InstBlockId::Empty;
|
|
||||||
std::tie(specific.decl_block_id, specific.decl_block_has_error) =
|
|
||||||
TryEvalBlockForSpecific(context, loc_id, specific_id,
|
|
||||||
SemIR::GenericInstIndex::Region::Declaration);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -750,10 +746,8 @@ auto ResolveSpecificDefinition(Context& context, SemIR::LocId loc_id,
|
|||||||
// The generic is not defined yet.
|
// The generic is not defined yet.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::tie(specific.definition_block_id,
|
TryEvalBlockForSpecific(context, loc_id, specific_id,
|
||||||
specific.definition_block_has_error) =
|
SemIR::GenericInstIndex::Definition);
|
||||||
TryEvalBlockForSpecific(context, loc_id, specific_id,
|
|
||||||
SemIR::GenericInstIndex::Definition);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -234,13 +234,13 @@ library "[[@TEST_NAME]]";
|
|||||||
// CHECK:STDOUT: %C.call: init %empty_tuple.type = call %C.ref()
|
// CHECK:STDOUT: %C.call: init %empty_tuple.type = call %C.ref()
|
||||||
// CHECK:STDOUT: %.loc13_7.1: ref %empty_tuple.type = temporary_storage
|
// CHECK:STDOUT: %.loc13_7.1: ref %empty_tuple.type = temporary_storage
|
||||||
// CHECK:STDOUT: %.loc13_7.2: ref %empty_tuple.type = temporary %.loc13_7.1, %A.call
|
// CHECK:STDOUT: %.loc13_7.2: ref %empty_tuple.type = temporary %.loc13_7.1, %A.call
|
||||||
// CHECK:STDOUT: %tuple.loc13: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %empty_tuple.loc13: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc13_7.3: %empty_tuple.type = converted %A.call, %tuple.loc13 [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc13_7.3: %empty_tuple.type = converted %A.call, %empty_tuple.loc13 [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: <elided>
|
// CHECK:STDOUT: <elided>
|
||||||
// CHECK:STDOUT: %.loc17_7.1: ref %empty_tuple.type = temporary_storage
|
// CHECK:STDOUT: %.loc17_7.1: ref %empty_tuple.type = temporary_storage
|
||||||
// CHECK:STDOUT: %.loc17_7.2: ref %empty_tuple.type = temporary %.loc17_7.1, %C.call
|
// CHECK:STDOUT: %.loc17_7.2: ref %empty_tuple.type = temporary %.loc17_7.1, %C.call
|
||||||
// CHECK:STDOUT: %tuple.loc17: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %empty_tuple.loc17: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc17_7.3: %empty_tuple.type = converted %C.call, %tuple.loc17 [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc17_7.3: %empty_tuple.type = converted %C.call, %empty_tuple.loc17 [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: <elided>
|
// CHECK:STDOUT: <elided>
|
||||||
// CHECK:STDOUT: %Destroy.Op.bound.loc17: <bound method> = bound_method %.loc17_7.2, constants.%Destroy.Op
|
// CHECK:STDOUT: %Destroy.Op.bound.loc17: <bound method> = bound_method %.loc17_7.2, constants.%Destroy.Op
|
||||||
// CHECK:STDOUT: %Destroy.Op.call.loc17: init %empty_tuple.type = call %Destroy.Op.bound.loc17(%.loc17_7.2)
|
// CHECK:STDOUT: %Destroy.Op.call.loc17: init %empty_tuple.type = call %Destroy.Op.bound.loc17(%.loc17_7.2)
|
||||||
|
|||||||
@@ -130,14 +130,14 @@ fn Foo(n: ()) -> ((), ()) {
|
|||||||
// CHECK:STDOUT: inst50000032: {kind: TupleLiteral, arg0: inst_block_empty, type: type(inst50000010)}
|
// CHECK:STDOUT: inst50000032: {kind: TupleLiteral, arg0: inst_block_empty, type: type(inst50000010)}
|
||||||
// CHECK:STDOUT: inst50000033: {kind: TupleLiteral, arg0: inst_block50000010, type: type(inst5000001C)}
|
// CHECK:STDOUT: inst50000033: {kind: TupleLiteral, arg0: inst_block50000010, type: type(inst5000001C)}
|
||||||
// CHECK:STDOUT: inst50000034: {kind: TupleAccess, arg0: inst5000002C, arg1: element0, type: type(inst50000010)}
|
// CHECK:STDOUT: inst50000034: {kind: TupleAccess, arg0: inst5000002C, arg1: element0, type: type(inst50000010)}
|
||||||
// CHECK:STDOUT: inst50000035: {kind: TupleInit, arg0: inst_block50000011, arg1: inst50000034, type: type(inst50000010)}
|
// CHECK:STDOUT: inst50000035: {kind: TupleInit, arg0: inst_block_empty, arg1: inst50000034, type: type(inst50000010)}
|
||||||
// CHECK:STDOUT: inst50000036: {kind: Converted, arg0: inst50000031, arg1: inst50000035, type: type(inst50000010)}
|
// CHECK:STDOUT: inst50000036: {kind: Converted, arg0: inst50000031, arg1: inst50000035, type: type(inst50000010)}
|
||||||
// CHECK:STDOUT: inst50000037: {kind: InPlaceInit, arg0: inst50000036, arg1: inst50000034, type: type(inst50000010)}
|
// CHECK:STDOUT: inst50000037: {kind: InPlaceInit, arg0: inst50000036, arg1: inst50000034, type: type(inst50000010)}
|
||||||
// CHECK:STDOUT: inst50000038: {kind: TupleAccess, arg0: inst5000002C, arg1: element1, type: type(inst50000010)}
|
// CHECK:STDOUT: inst50000038: {kind: TupleAccess, arg0: inst5000002C, arg1: element1, type: type(inst50000010)}
|
||||||
// CHECK:STDOUT: inst50000039: {kind: TupleInit, arg0: inst_block_empty, arg1: inst50000038, type: type(inst50000010)}
|
// CHECK:STDOUT: inst50000039: {kind: TupleInit, arg0: inst_block_empty, arg1: inst50000038, type: type(inst50000010)}
|
||||||
// CHECK:STDOUT: inst5000003A: {kind: Converted, arg0: inst50000032, arg1: inst50000039, type: type(inst50000010)}
|
// CHECK:STDOUT: inst5000003A: {kind: Converted, arg0: inst50000032, arg1: inst50000039, type: type(inst50000010)}
|
||||||
// CHECK:STDOUT: inst5000003B: {kind: InPlaceInit, arg0: inst5000003A, arg1: inst50000038, type: type(inst50000010)}
|
// CHECK:STDOUT: inst5000003B: {kind: InPlaceInit, arg0: inst5000003A, arg1: inst50000038, type: type(inst50000010)}
|
||||||
// CHECK:STDOUT: inst5000003C: {kind: TupleInit, arg0: inst_block50000012, arg1: inst5000002C, type: type(inst5000001C)}
|
// CHECK:STDOUT: inst5000003C: {kind: TupleInit, arg0: inst_block50000011, arg1: inst5000002C, type: type(inst5000001C)}
|
||||||
// CHECK:STDOUT: inst5000003D: {kind: Converted, arg0: inst50000033, arg1: inst5000003C, type: type(inst5000001C)}
|
// CHECK:STDOUT: inst5000003D: {kind: Converted, arg0: inst50000033, arg1: inst5000003C, type: type(inst5000001C)}
|
||||||
// CHECK:STDOUT: inst5000003E: {kind: ReturnExpr, arg0: inst5000003D, arg1: inst5000002C}
|
// CHECK:STDOUT: inst5000003E: {kind: ReturnExpr, arg0: inst5000003D, arg1: inst5000002C}
|
||||||
// CHECK:STDOUT: bundles: {}
|
// CHECK:STDOUT: bundles: {}
|
||||||
@@ -249,11 +249,10 @@ fn Foo(n: ()) -> ((), ()) {
|
|||||||
// CHECK:STDOUT: inst_block50000010:
|
// CHECK:STDOUT: inst_block50000010:
|
||||||
// CHECK:STDOUT: 0: inst50000031
|
// CHECK:STDOUT: 0: inst50000031
|
||||||
// CHECK:STDOUT: 1: inst50000032
|
// CHECK:STDOUT: 1: inst50000032
|
||||||
// CHECK:STDOUT: inst_block50000011: {}
|
// CHECK:STDOUT: inst_block50000011:
|
||||||
// CHECK:STDOUT: inst_block50000012:
|
|
||||||
// CHECK:STDOUT: 0: inst50000037
|
// CHECK:STDOUT: 0: inst50000037
|
||||||
// CHECK:STDOUT: 1: inst5000003B
|
// CHECK:STDOUT: 1: inst5000003B
|
||||||
// CHECK:STDOUT: inst_block50000013:
|
// CHECK:STDOUT: inst_block50000012:
|
||||||
// CHECK:STDOUT: 0: instF
|
// CHECK:STDOUT: 0: instF
|
||||||
// CHECK:STDOUT: 1: inst5000002E
|
// CHECK:STDOUT: 1: inst5000002E
|
||||||
// CHECK:STDOUT: value_stores:
|
// CHECK:STDOUT: value_stores:
|
||||||
|
|||||||
+4
-4
@@ -188,8 +188,8 @@ fn G(holds_to: HoldsType((RuntimeConvertTo, )), generic from: RuntimeConvertFrom
|
|||||||
// CHECK:STDOUT: %HoldsType.ref: %HoldsType.type = name_ref HoldsType, file.%HoldsType.decl [concrete = constants.%HoldsType.generic]
|
// CHECK:STDOUT: %HoldsType.ref: %HoldsType.type = name_ref HoldsType, file.%HoldsType.decl [concrete = constants.%HoldsType.generic]
|
||||||
// CHECK:STDOUT: %RuntimeConvertTo.ref: type = name_ref RuntimeConvertTo, file.%RuntimeConvertTo.decl [concrete = constants.%RuntimeConvertTo]
|
// CHECK:STDOUT: %RuntimeConvertTo.ref: type = name_ref RuntimeConvertTo, file.%RuntimeConvertTo.decl [concrete = constants.%RuntimeConvertTo]
|
||||||
// CHECK:STDOUT: %.loc29_45: %tuple.type = tuple_literal (%RuntimeConvertTo.ref) [concrete = constants.%tuple.162]
|
// CHECK:STDOUT: %.loc29_45: %tuple.type = tuple_literal (%RuntimeConvertTo.ref) [concrete = constants.%tuple.162]
|
||||||
// CHECK:STDOUT: %tuple.loc29: %tuple.type = tuple_value (%RuntimeConvertTo.ref) [concrete = constants.%tuple.162]
|
// CHECK:STDOUT: %tuple: %tuple.type = tuple_value (%RuntimeConvertTo.ref) [concrete = constants.%tuple.162]
|
||||||
// CHECK:STDOUT: %.loc29_46.2: %tuple.type = converted %.loc29_45, %tuple.loc29 [concrete = constants.%tuple.162]
|
// CHECK:STDOUT: %.loc29_46.2: %tuple.type = converted %.loc29_45, %tuple [concrete = constants.%tuple.162]
|
||||||
// CHECK:STDOUT: %HoldsType: type = class_type @HoldsType, @HoldsType(constants.%tuple.162) [concrete = constants.%HoldsType.9f2]
|
// CHECK:STDOUT: %HoldsType: type = class_type @HoldsType, @HoldsType(constants.%tuple.162) [concrete = constants.%HoldsType.9f2]
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT: %holds_to: %HoldsType.9f2 = wrapper_binding holds_to, %holds_to.param
|
// CHECK:STDOUT: %holds_to: %HoldsType.9f2 = wrapper_binding holds_to, %holds_to.param
|
||||||
@@ -307,8 +307,8 @@ fn G(holds_to: HoldsType((RuntimeConvertTo, )), generic from: RuntimeConvertFrom
|
|||||||
// CHECK:STDOUT: %.loc40_19.4: %RuntimeConvertTo = acquire_value %.loc40_19.3
|
// CHECK:STDOUT: %.loc40_19.4: %RuntimeConvertTo = acquire_value %.loc40_19.3
|
||||||
// CHECK:STDOUT: %F.specific_fn: <specific function> = specific_function %F.ref, @F(constants.%tuple.162, <error>) [concrete = <error>]
|
// CHECK:STDOUT: %F.specific_fn: <specific function> = specific_function %F.ref, @F(constants.%tuple.162, <error>) [concrete = <error>]
|
||||||
// CHECK:STDOUT: %.loc40_19.5: %empty_tuple.type = call %F.specific_fn(%holds_to.ref)
|
// CHECK:STDOUT: %.loc40_19.5: %empty_tuple.type = call %F.specific_fn(%holds_to.ref)
|
||||||
// CHECK:STDOUT: %tuple.loc40: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc40_19.6: %empty_tuple.type = converted %.loc40_19.5, %tuple.loc40 [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc40_19.6: %empty_tuple.type = converted %.loc40_19.5, %empty_tuple [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %Destroy.Op.bound: <bound method> = bound_method %.loc40_19.3, constants.%Destroy.Op.1a2547.2
|
// CHECK:STDOUT: %Destroy.Op.bound: <bound method> = bound_method %.loc40_19.3, constants.%Destroy.Op.1a2547.2
|
||||||
// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call %Destroy.Op.bound(%.loc40_19.3)
|
// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call %Destroy.Op.bound(%.loc40_19.3)
|
||||||
// CHECK:STDOUT: return
|
// CHECK:STDOUT: return
|
||||||
|
|||||||
+2
-2
@@ -167,8 +167,8 @@ fn Run() {
|
|||||||
// CHECK:STDOUT: %Optional.Get.call: init %empty_tuple.type = call %bound_method.loc18_35.4(%.loc18_35.8)
|
// CHECK:STDOUT: %Optional.Get.call: init %empty_tuple.type = call %bound_method.loc18_35.4(%.loc18_35.8)
|
||||||
// CHECK:STDOUT: %.loc18_35.9: ref %empty_tuple.type = temporary_storage
|
// CHECK:STDOUT: %.loc18_35.9: ref %empty_tuple.type = temporary_storage
|
||||||
// CHECK:STDOUT: %.loc18_35.10: ref %empty_tuple.type = temporary %.loc18_35.9, %Optional.Get.call
|
// CHECK:STDOUT: %.loc18_35.10: ref %empty_tuple.type = temporary %.loc18_35.9, %Optional.Get.call
|
||||||
// CHECK:STDOUT: %tuple: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc18_35.11: %empty_tuple.type = converted %Optional.Get.call, %tuple [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc18_35.11: %empty_tuple.type = converted %Optional.Get.call, %empty_tuple [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc18_12.1: type = splice_block %.loc18_12.3 [concrete = constants.%empty_tuple.type] {
|
// CHECK:STDOUT: %.loc18_12.1: type = splice_block %.loc18_12.3 [concrete = constants.%empty_tuple.type] {
|
||||||
// CHECK:STDOUT: %.loc18_12.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc18_12.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc18_12.3: type = converted %.loc18_12.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
// CHECK:STDOUT: %.loc18_12.3: type = converted %.loc18_12.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||||
|
|||||||
+2
-2
@@ -984,8 +984,8 @@ fn InstanceCallFail() {
|
|||||||
// CHECK:STDOUT: %impl.elem0: %.df4 = impl_witness_access constants.%Instance1.impl_witness, element0 [concrete = constants.%struct_type.d.as.Instance1.impl.G1]
|
// CHECK:STDOUT: %impl.elem0: %.df4 = impl_witness_access constants.%Instance1.impl_witness, element0 [concrete = constants.%struct_type.d.as.Instance1.impl.G1]
|
||||||
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc16_4.1, %impl.elem0
|
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc16_4.1, %impl.elem0
|
||||||
// CHECK:STDOUT: %.loc16_4.2: ref %empty_tuple.type = struct_access %.loc16_4.1, element0
|
// CHECK:STDOUT: %.loc16_4.2: ref %empty_tuple.type = struct_access %.loc16_4.1, element0
|
||||||
// CHECK:STDOUT: %tuple: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc16_4.3: %empty_tuple.type = converted %.loc16_4.2, %tuple [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc16_4.3: %empty_tuple.type = converted %.loc16_4.2, %empty_tuple [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %struct: %struct_type.d = struct_value (%.loc16_4.3) [concrete = constants.%struct]
|
// CHECK:STDOUT: %struct: %struct_type.d = struct_value (%.loc16_4.3) [concrete = constants.%struct]
|
||||||
// CHECK:STDOUT: %.loc16_4.4: %struct_type.d = converted %.loc16_4.1, %struct [concrete = constants.%struct]
|
// CHECK:STDOUT: %.loc16_4.4: %struct_type.d = converted %.loc16_4.1, %struct [concrete = constants.%struct]
|
||||||
// CHECK:STDOUT: %struct_type.d.as.Instance1.impl.G1.call: init %empty_tuple.type = call %bound_method(%.loc16_4.4)
|
// CHECK:STDOUT: %struct_type.d.as.Instance1.impl.G1.call: init %empty_tuple.type = call %bound_method(%.loc16_4.4)
|
||||||
|
|||||||
+2
-2
@@ -744,8 +744,8 @@ fn InstanceCallImportFail() {
|
|||||||
// CHECK:STDOUT: %impl.elem0: %.760 = impl_witness_access constants.%Instance.impl_witness, element0 [concrete = constants.%struct_type.i.as.Instance.impl.G]
|
// CHECK:STDOUT: %impl.elem0: %.760 = impl_witness_access constants.%Instance.impl_witness, element0 [concrete = constants.%struct_type.i.as.Instance.impl.G]
|
||||||
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc10_4.1, %impl.elem0
|
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc10_4.1, %impl.elem0
|
||||||
// CHECK:STDOUT: %.loc10_4.2: ref %empty_tuple.type = struct_access %.loc10_4.1, element0
|
// CHECK:STDOUT: %.loc10_4.2: ref %empty_tuple.type = struct_access %.loc10_4.1, element0
|
||||||
// CHECK:STDOUT: %tuple: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc10_4.3: %empty_tuple.type = converted %.loc10_4.2, %tuple [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc10_4.3: %empty_tuple.type = converted %.loc10_4.2, %empty_tuple [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %struct: %struct_type.i = struct_value (%.loc10_4.3) [concrete = constants.%struct]
|
// CHECK:STDOUT: %struct: %struct_type.i = struct_value (%.loc10_4.3) [concrete = constants.%struct]
|
||||||
// CHECK:STDOUT: %.loc10_4.4: %struct_type.i = converted %.loc10_4.1, %struct [concrete = constants.%struct]
|
// CHECK:STDOUT: %.loc10_4.4: %struct_type.i = converted %.loc10_4.1, %struct [concrete = constants.%struct]
|
||||||
// CHECK:STDOUT: %struct_type.i.as.Instance.impl.G.call: init %empty_tuple.type = call %bound_method(%.loc10_4.4)
|
// CHECK:STDOUT: %struct_type.i.as.Instance.impl.G.call: init %empty_tuple.type = call %bound_method(%.loc10_4.4)
|
||||||
|
|||||||
@@ -397,8 +397,8 @@ let x: i32 = c[0];
|
|||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT: %.loc8: <witness> = impl_self_witness @tuple.type.as.IndexWith.impl.%.loc8_11.2, @IndexWith, @IndexWith(Core.IntLiteral) [concrete = constants.%.291]
|
// CHECK:STDOUT: %.loc8: <witness> = impl_self_witness @tuple.type.as.IndexWith.impl.%.loc8_11.2, @IndexWith, @IndexWith(Core.IntLiteral) [concrete = constants.%.291]
|
||||||
// CHECK:STDOUT: %tuple.loc14: %tuple.type.748 = tuple_value (@__global_init.%.loc14_21.2, @__global_init.%.loc14_30.2) [concrete = constants.%tuple.adf]
|
// CHECK:STDOUT: %tuple: %tuple.type.748 = tuple_value (@__global_init.%.loc14_21.2, @__global_init.%.loc14_30.2) [concrete = constants.%tuple.adf]
|
||||||
// CHECK:STDOUT: %.loc14_34: %tuple.type.748 = converted @__global_init.%.loc14_34, %tuple.loc14 [concrete = constants.%tuple.adf]
|
// CHECK:STDOUT: %.loc14_34: %tuple.type.748 = converted @__global_init.%.loc14_34, %tuple [concrete = constants.%tuple.adf]
|
||||||
// CHECK:STDOUT: %.loc14_13.1: type = splice_block %.loc14_13.3 [concrete = constants.%tuple.type.748] {
|
// CHECK:STDOUT: %.loc14_13.1: type = splice_block %.loc14_13.3 [concrete = constants.%tuple.type.748] {
|
||||||
// CHECK:STDOUT: %C.ref.loc14_9: type = name_ref C, %C.decl [concrete = constants.%C]
|
// CHECK:STDOUT: %C.ref.loc14_9: type = name_ref C, %C.decl [concrete = constants.%C]
|
||||||
// CHECK:STDOUT: %C.ref.loc14_12: type = name_ref C, %C.decl [concrete = constants.%C]
|
// CHECK:STDOUT: %C.ref.loc14_12: type = name_ref C, %C.decl [concrete = constants.%C]
|
||||||
@@ -412,8 +412,8 @@ let x: i32 = c[0];
|
|||||||
// CHECK:STDOUT: %.loc15_15.1: init %empty_tuple.type = as_compatible @__global_init.%tuple.type.as.IndexWith.impl.At.call
|
// CHECK:STDOUT: %.loc15_15.1: init %empty_tuple.type = as_compatible @__global_init.%tuple.type.as.IndexWith.impl.At.call
|
||||||
// CHECK:STDOUT: %.loc15_15.2: ref %empty_tuple.type = temporary_storage
|
// CHECK:STDOUT: %.loc15_15.2: ref %empty_tuple.type = temporary_storage
|
||||||
// CHECK:STDOUT: %.loc15_15.3: ref %empty_tuple.type = temporary %.loc15_15.2, %.loc15_15.1
|
// CHECK:STDOUT: %.loc15_15.3: ref %empty_tuple.type = temporary %.loc15_15.2, %.loc15_15.1
|
||||||
// CHECK:STDOUT: %tuple.loc15: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple.af4]
|
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple.af4]
|
||||||
// CHECK:STDOUT: %.loc15_15.4: %C = as_compatible %tuple.loc15 [concrete = constants.%empty_tuple.4db]
|
// CHECK:STDOUT: %.loc15_15.4: %C = as_compatible %empty_tuple [concrete = constants.%empty_tuple.4db]
|
||||||
// CHECK:STDOUT: %.loc15_15.5: %C = converted @__global_init.%tuple.type.as.IndexWith.impl.At.call, %.loc15_15.4 [concrete = constants.%empty_tuple.4db]
|
// CHECK:STDOUT: %.loc15_15.5: %C = converted @__global_init.%tuple.type.as.IndexWith.impl.At.call, %.loc15_15.4 [concrete = constants.%empty_tuple.4db]
|
||||||
// CHECK:STDOUT: %C.ref.loc15: type = name_ref C, %C.decl [concrete = constants.%C]
|
// CHECK:STDOUT: %C.ref.loc15: type = name_ref C, %C.decl [concrete = constants.%C]
|
||||||
// CHECK:STDOUT: %e: %C = wrapper_binding e, %.loc15_15.5
|
// CHECK:STDOUT: %e: %C = wrapper_binding e, %.loc15_15.5
|
||||||
|
|||||||
+8
-8
@@ -121,15 +121,15 @@ let (((b: ()),)) = ((),);
|
|||||||
// CHECK:STDOUT: %.loc7_24.1: ref %tuple.type = temporary @__global_init.%.loc7, @__global_init.%F.call
|
// CHECK:STDOUT: %.loc7_24.1: ref %tuple.type = temporary @__global_init.%.loc7, @__global_init.%F.call
|
||||||
// CHECK:STDOUT: %tuple.elem0: ref %empty_tuple.type = tuple_access %.loc7_24.1, element0
|
// CHECK:STDOUT: %tuple.elem0: ref %empty_tuple.type = tuple_access %.loc7_24.1, element0
|
||||||
// CHECK:STDOUT: %tuple.elem1: ref %empty_tuple.type = tuple_access %.loc7_24.1, element1
|
// CHECK:STDOUT: %tuple.elem1: ref %empty_tuple.type = tuple_access %.loc7_24.1, element1
|
||||||
// CHECK:STDOUT: %tuple.loc7_24.1: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %empty_tuple.loc7_24.1: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc7_24.2: %empty_tuple.type = converted %tuple.elem0, %tuple.loc7_24.1 [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc7_24.2: %empty_tuple.type = converted %tuple.elem0, %empty_tuple.loc7_24.1 [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc7_10.1: type = splice_block %.loc7_10.3 [concrete = constants.%empty_tuple.type] {
|
// CHECK:STDOUT: %.loc7_10.1: type = splice_block %.loc7_10.3 [concrete = constants.%empty_tuple.type] {
|
||||||
// CHECK:STDOUT: %.loc7_10.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc7_10.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc7_10.3: type = converted %.loc7_10.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
// CHECK:STDOUT: %.loc7_10.3: type = converted %.loc7_10.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT: %a: %empty_tuple.type = wrapper_binding a, %.loc7_24.2
|
// CHECK:STDOUT: %a: %empty_tuple.type = wrapper_binding a, %.loc7_24.2
|
||||||
// CHECK:STDOUT: %tuple.loc7_24.2: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %empty_tuple.loc7_24.2: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc7_24.3: %empty_tuple.type = converted %tuple.elem1, %tuple.loc7_24.2 [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc7_24.3: %empty_tuple.type = converted %tuple.elem1, %empty_tuple.loc7_24.2 [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc7_17.1: type = splice_block %.loc7_17.3 [concrete = constants.%empty_tuple.type] {
|
// CHECK:STDOUT: %.loc7_17.1: type = splice_block %.loc7_17.3 [concrete = constants.%empty_tuple.type] {
|
||||||
// CHECK:STDOUT: %.loc7_17.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc7_17.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc7_17.3: type = converted %.loc7_17.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
// CHECK:STDOUT: %.loc7_17.3: type = converted %.loc7_17.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||||
@@ -168,15 +168,15 @@ let (((b: ()),)) = ((),);
|
|||||||
// CHECK:STDOUT: file {
|
// CHECK:STDOUT: file {
|
||||||
// CHECK:STDOUT: %tuple.elem0: ref %empty_tuple.type = tuple_access @__global_init.%t.ref, element0 [concrete = constants.%tuple.elem0]
|
// CHECK:STDOUT: %tuple.elem0: ref %empty_tuple.type = tuple_access @__global_init.%t.ref, element0 [concrete = constants.%tuple.elem0]
|
||||||
// CHECK:STDOUT: %tuple.elem1: ref %empty_tuple.type = tuple_access @__global_init.%t.ref, element1 [concrete = constants.%tuple.elem1]
|
// CHECK:STDOUT: %tuple.elem1: ref %empty_tuple.type = tuple_access @__global_init.%t.ref, element1 [concrete = constants.%tuple.elem1]
|
||||||
// CHECK:STDOUT: %tuple.loc6_22.1: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %empty_tuple.loc6_22.1: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc6_22.1: %empty_tuple.type = converted %tuple.elem0, %tuple.loc6_22.1 [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc6_22.1: %empty_tuple.type = converted %tuple.elem0, %empty_tuple.loc6_22.1 [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc6_10.1: type = splice_block %.loc6_10.3 [concrete = constants.%empty_tuple.type] {
|
// CHECK:STDOUT: %.loc6_10.1: type = splice_block %.loc6_10.3 [concrete = constants.%empty_tuple.type] {
|
||||||
// CHECK:STDOUT: %.loc6_10.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc6_10.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc6_10.3: type = converted %.loc6_10.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
// CHECK:STDOUT: %.loc6_10.3: type = converted %.loc6_10.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT: %a: %empty_tuple.type = wrapper_binding a, %.loc6_22.1
|
// CHECK:STDOUT: %a: %empty_tuple.type = wrapper_binding a, %.loc6_22.1
|
||||||
// CHECK:STDOUT: %tuple.loc6_22.2: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %empty_tuple.loc6_22.2: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc6_22.2: %empty_tuple.type = converted %tuple.elem1, %tuple.loc6_22.2 [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc6_22.2: %empty_tuple.type = converted %tuple.elem1, %empty_tuple.loc6_22.2 [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc6_17.1: type = splice_block %.loc6_17.3 [concrete = constants.%empty_tuple.type] {
|
// CHECK:STDOUT: %.loc6_17.1: type = splice_block %.loc6_17.3 [concrete = constants.%empty_tuple.type] {
|
||||||
// CHECK:STDOUT: %.loc6_17.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc6_17.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc6_17.3: type = converted %.loc6_17.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
// CHECK:STDOUT: %.loc6_17.3: type = converted %.loc6_17.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||||
|
|||||||
+6
-6
@@ -555,8 +555,8 @@ fn Call() {
|
|||||||
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
|
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
|
||||||
// CHECK:STDOUT: %v.ref: ref %empty_tuple.type = name_ref v, %v
|
// CHECK:STDOUT: %v.ref: ref %empty_tuple.type = name_ref v, %v
|
||||||
// CHECK:STDOUT: %.loc8_9.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc8_9.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %tuple: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc8_5: %empty_tuple.type = converted %v.ref, %tuple [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc8_5: %empty_tuple.type = converted %v.ref, %empty_tuple [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %y.var: ref %empty_tuple.type = var_storage @F.%y.param_patt
|
// CHECK:STDOUT: %y.var: ref %empty_tuple.type = var_storage @F.%y.param_patt
|
||||||
// CHECK:STDOUT: %.loc8_9.2: init %empty_tuple.type = tuple_init () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc8_9.2: init %empty_tuple.type = tuple_init () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc4: init %empty_tuple.type = converted %.loc8_9.1, %.loc8_9.2 [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc4: init %empty_tuple.type = converted %.loc8_9.1, %.loc8_9.2 [concrete = constants.%empty_tuple]
|
||||||
@@ -911,8 +911,8 @@ fn Call() {
|
|||||||
// CHECK:STDOUT: %.loc8_70: %tuple.type = tuple_literal (%F.call.loc8_59, %F.call.loc8_64, %F.call.loc8_69)
|
// CHECK:STDOUT: %.loc8_70: %tuple.type = tuple_literal (%F.call.loc8_59, %F.call.loc8_64, %F.call.loc8_69)
|
||||||
// CHECK:STDOUT: %.loc8_59.1: ref %empty_tuple.type = temporary_storage
|
// CHECK:STDOUT: %.loc8_59.1: ref %empty_tuple.type = temporary_storage
|
||||||
// CHECK:STDOUT: %.loc8_59.2: ref %empty_tuple.type = temporary %.loc8_59.1, %F.call.loc8_59
|
// CHECK:STDOUT: %.loc8_59.2: ref %empty_tuple.type = temporary %.loc8_59.1, %F.call.loc8_59
|
||||||
// CHECK:STDOUT: %tuple.loc8_59: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %empty_tuple.loc8_59: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc8_59.3: %empty_tuple.type = converted %F.call.loc8_59, %tuple.loc8_59 [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc8_59.3: %empty_tuple.type = converted %F.call.loc8_59, %empty_tuple.loc8_59 [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc8_19.1: type = splice_block %.loc8_19.3 [concrete = constants.%empty_tuple.type] {
|
// CHECK:STDOUT: %.loc8_19.1: type = splice_block %.loc8_19.3 [concrete = constants.%empty_tuple.type] {
|
||||||
// CHECK:STDOUT: %.loc8_19.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc8_19.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc8_19.3: type = converted %.loc8_19.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
// CHECK:STDOUT: %.loc8_19.3: type = converted %.loc8_19.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||||
@@ -926,8 +926,8 @@ fn Call() {
|
|||||||
// CHECK:STDOUT: %y: ref %empty_tuple.type = wrapper_binding y, %y.var
|
// CHECK:STDOUT: %y: ref %empty_tuple.type = wrapper_binding y, %y.var
|
||||||
// CHECK:STDOUT: %.loc8_69.1: ref %empty_tuple.type = temporary_storage
|
// CHECK:STDOUT: %.loc8_69.1: ref %empty_tuple.type = temporary_storage
|
||||||
// CHECK:STDOUT: %.loc8_69.2: ref %empty_tuple.type = temporary %.loc8_69.1, %F.call.loc8_69
|
// CHECK:STDOUT: %.loc8_69.2: ref %empty_tuple.type = temporary %.loc8_69.1, %F.call.loc8_69
|
||||||
// CHECK:STDOUT: %tuple.loc8_69: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %empty_tuple.loc8_69: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc8_69.3: %empty_tuple.type = converted %F.call.loc8_69, %tuple.loc8_69 [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc8_69.3: %empty_tuple.type = converted %F.call.loc8_69, %empty_tuple.loc8_69 [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc8_51.1: type = splice_block %.loc8_51.3 [concrete = constants.%empty_tuple.type] {
|
// CHECK:STDOUT: %.loc8_51.1: type = splice_block %.loc8_51.3 [concrete = constants.%empty_tuple.type] {
|
||||||
// CHECK:STDOUT: %.loc8_51.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
// CHECK:STDOUT: %.loc8_51.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
||||||
// CHECK:STDOUT: %.loc8_51.3: type = converted %.loc8_51.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
// CHECK:STDOUT: %.loc8_51.3: type = converted %.loc8_51.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||||
|
|||||||
@@ -99,9 +99,14 @@ static auto GetConstantInSpecific(const File& specific_ir,
|
|||||||
// specific.
|
// specific.
|
||||||
return {&const_ir, const_ir.constant_values().Get(symbolic.inst_id)};
|
return {&const_ir, const_ir.constant_values().Get(symbolic.inst_id)};
|
||||||
}
|
}
|
||||||
return {&specific_ir,
|
// TODO: Distinguish between parts of the instruction block that we've not
|
||||||
specific_ir.constant_values().Get(specific_ir.inst_blocks().Get(
|
// reached yet during eval and values that evaluated successfully to
|
||||||
value_block_id)[symbolic.index.index()])};
|
// ConstantId::NotConstant.
|
||||||
|
auto value_id =
|
||||||
|
specific_ir.inst_blocks().Get(value_block_id)[symbolic.index.index()];
|
||||||
|
return {&specific_ir, value_id.has_value()
|
||||||
|
? specific_ir.constant_values().Get(value_id)
|
||||||
|
: SemIR::ConstantId::NotConstant};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto GetConstantValueInSpecific(const File& sem_ir, SpecificId specific_id,
|
auto GetConstantValueInSpecific(const File& sem_ir, SpecificId specific_id,
|
||||||
|
|||||||
@@ -100,11 +100,28 @@ struct Specific : Printable<Specific> {
|
|||||||
? decl_block_id
|
? decl_block_id
|
||||||
: definition_block_id;
|
: definition_block_id;
|
||||||
}
|
}
|
||||||
|
// Sets the specified value block of this specific.
|
||||||
|
auto SetValueBlock(GenericInstIndex::Region region, InstBlockId inst_block_id)
|
||||||
|
-> void {
|
||||||
|
auto& value_block_id = region == GenericInstIndex::Region::Declaration
|
||||||
|
? decl_block_id
|
||||||
|
: definition_block_id;
|
||||||
|
CARBON_CHECK(!value_block_id.has_value(), "Value block set twice");
|
||||||
|
value_block_id = inst_block_id;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns whether either block has an error.
|
// Returns whether either block has an error.
|
||||||
auto HasError() const -> bool {
|
auto HasError() const -> bool {
|
||||||
return decl_block_has_error || definition_block_has_error;
|
return decl_block_has_error || definition_block_has_error;
|
||||||
}
|
}
|
||||||
|
// Sets that one of the blocks has an error.
|
||||||
|
auto SetHasError(GenericInstIndex::Region region) -> void {
|
||||||
|
if (region == SemIR::GenericInstIndex::Declaration) {
|
||||||
|
decl_block_has_error = true;
|
||||||
|
} else {
|
||||||
|
definition_block_has_error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The generic that this is a specific version of.
|
// The generic that this is a specific version of.
|
||||||
GenericId generic_id;
|
GenericId generic_id;
|
||||||
|
|||||||
@@ -678,7 +678,8 @@ class InstBlockStore
|
|||||||
// Adds an uninitialized block of the given size. The caller is expected to
|
// Adds an uninitialized block of the given size. The caller is expected to
|
||||||
// modify values.
|
// modify values.
|
||||||
auto AddUninitialized(size_t size) -> InstBlockId {
|
auto AddUninitialized(size_t size) -> InstBlockId {
|
||||||
return values().Add(AllocateUninitialized(size));
|
return size ? values().Add(AllocateUninitialized(size))
|
||||||
|
: InstBlockId::Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reserves and returns a block ID. The contents of the block should be
|
// Reserves and returns a block ID. The contents of the block should be
|
||||||
|
|||||||
Reference in New Issue
Block a user