Skip to content

Commit

Permalink
Symbolic aggregate access (#4590)
Browse files Browse the repository at this point in the history
Co-authored-by: Josh L <[email protected]>
Co-authored-by: Richard Smith <[email protected]>
  • Loading branch information
3 people authored Nov 26, 2024
1 parent 5880954 commit 4d3b962
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 59 deletions.
9 changes: 5 additions & 4 deletions toolchain/check/eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,12 +509,12 @@ static auto PerformAggregateAccess(EvalContext& eval_context, SemIR::Inst inst)
-> SemIR::ConstantId {
auto access_inst = inst.As<SemIR::AnyAggregateAccess>();
Phase phase = Phase::Template;
if (auto aggregate_id =
GetConstantValue(eval_context, access_inst.aggregate_id, &phase);
aggregate_id.is_valid()) {
if (ReplaceFieldWithConstantValue(eval_context, &access_inst,
&SemIR::AnyAggregateAccess::aggregate_id,
&phase)) {
if (auto aggregate =
eval_context.insts().TryGetAs<SemIR::AnyAggregateValue>(
aggregate_id)) {
access_inst.aggregate_id)) {
auto elements = eval_context.inst_blocks().Get(aggregate->elements_id);
auto index = static_cast<size_t>(access_inst.index.index);
CARBON_CHECK(index < elements.size(), "Access out of bounds.");
Expand All @@ -526,6 +526,7 @@ static auto PerformAggregateAccess(EvalContext& eval_context, SemIR::Inst inst)
CARBON_CHECK(phase != Phase::Template,
"Failed to evaluate template constant {0}", inst);
}
return MakeConstantResult(eval_context.context(), access_inst, phase);
}
return MakeNonConstantResult(phase);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ impl bool as I where .T = bool {}
// CHECK:STDOUT: %Bool: %Bool.type = struct_value () [template]
// CHECK:STDOUT: %.Self: %I.type.1 = bind_symbolic_name .Self, 0 [symbolic]
// CHECK:STDOUT: %.3: <witness> = facet_access_witness %.Self [symbolic]
// CHECK:STDOUT: %.4: type = interface_witness_access %.3, element0 [symbolic]
// CHECK:STDOUT: %I.type.2: type = facet_type <@I where TODO> [template]
// CHECK:STDOUT: }
// CHECK:STDOUT:
Expand Down Expand Up @@ -53,7 +54,7 @@ impl bool as I where .T = bool {}
// CHECK:STDOUT: %.Self.ref: %I.type.1 = name_ref .Self, %.Self [symbolic = constants.%.Self]
// CHECK:STDOUT: %T.ref: %.1 = name_ref T, @I.%.loc11 [template = constants.%.2]
// CHECK:STDOUT: %.loc16_22.1: <witness> = facet_access_witness %.Self.ref [symbolic = constants.%.3]
// CHECK:STDOUT: %.loc16_22.2: type = interface_witness_access %.loc16_22.1, element0
// CHECK:STDOUT: %.loc16_22.2: type = interface_witness_access %.loc16_22.1, element0 [symbolic = constants.%.4]
// CHECK:STDOUT: %bool.make_type.loc16_27: init type = call constants.%Bool() [template = bool]
// CHECK:STDOUT: %.loc16_27.1: type = value_of_initializer %bool.make_type.loc16_27 [template = bool]
// CHECK:STDOUT: %.loc16_27.2: type = converted %bool.make_type.loc16_27, %.loc16_27.1 [template = bool]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ fn CallFacet(T:! Interface, x: T) {
// CHECK:STDOUT: %CallStatic.type: type = fn_type @CallStatic [template]
// CHECK:STDOUT: %CallStatic: %CallStatic.type = struct_value () [template]
// CHECK:STDOUT: %.3: <witness> = facet_access_witness %T [symbolic]
// CHECK:STDOUT: %.4: type = facet_access_type %T [symbolic]
// CHECK:STDOUT: %.4: %F.type = interface_witness_access %.3, element0 [symbolic]
// CHECK:STDOUT: %.5: type = facet_access_type %T [symbolic]
// CHECK:STDOUT: %CallFacet.type: type = fn_type @CallFacet [template]
// CHECK:STDOUT: %CallFacet: %CallFacet.type = struct_value () [template]
// CHECK:STDOUT: }
Expand All @@ -62,17 +63,17 @@ fn CallFacet(T:! Interface, x: T) {
// CHECK:STDOUT: %CallFacet.decl: %CallFacet.type = fn_decl @CallFacet [template = constants.%CallFacet] {
// CHECK:STDOUT: %T.patt.loc21_14.1: %Interface.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc21_14.2 (constants.%T.patt)]
// CHECK:STDOUT: %T.param_patt: %Interface.type = value_param_pattern %T.patt.loc21_14.1, runtime_param<invalid> [symbolic = %T.patt.loc21_14.2 (constants.%T.patt)]
// CHECK:STDOUT: %x.patt: @CallFacet.%.loc21_32.3 (%.4) = binding_pattern x
// CHECK:STDOUT: %x.param_patt: @CallFacet.%.loc21_32.3 (%.4) = value_param_pattern %x.patt, runtime_param0
// CHECK:STDOUT: %x.patt: @CallFacet.%.loc21_32.3 (%.5) = binding_pattern x
// CHECK:STDOUT: %x.param_patt: @CallFacet.%.loc21_32.3 (%.5) = value_param_pattern %x.patt, runtime_param0
// CHECK:STDOUT: } {
// CHECK:STDOUT: %Interface.ref: type = name_ref Interface, file.%Interface.decl [template = constants.%Interface.type]
// CHECK:STDOUT: %T.ref: %Interface.type = name_ref T, %T.loc21_14.1 [symbolic = %T.loc21_14.2 (constants.%T)]
// CHECK:STDOUT: %.loc21_32.1: type = facet_access_type %T.ref [symbolic = %.loc21_32.3 (constants.%.4)]
// CHECK:STDOUT: %.loc21_32.2: type = converted %T.ref, %.loc21_32.1 [symbolic = %.loc21_32.3 (constants.%.4)]
// CHECK:STDOUT: %.loc21_32.1: type = facet_access_type %T.ref [symbolic = %.loc21_32.3 (constants.%.5)]
// CHECK:STDOUT: %.loc21_32.2: type = converted %T.ref, %.loc21_32.1 [symbolic = %.loc21_32.3 (constants.%.5)]
// CHECK:STDOUT: %T.param: %Interface.type = value_param runtime_param<invalid>
// CHECK:STDOUT: %T.loc21_14.1: %Interface.type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc21_14.2 (constants.%T)]
// CHECK:STDOUT: %x.param: @CallFacet.%.loc21_32.3 (%.4) = value_param runtime_param0
// CHECK:STDOUT: %x: @CallFacet.%.loc21_32.3 (%.4) = bind_name x, %x.param
// CHECK:STDOUT: %x.param: @CallFacet.%.loc21_32.3 (%.5) = value_param runtime_param0
// CHECK:STDOUT: %x: @CallFacet.%.loc21_32.3 (%.5) = bind_name x, %x.param
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
Expand All @@ -98,27 +99,28 @@ fn CallFacet(T:! Interface, x: T) {
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %.loc18_4.3: <witness> = facet_access_witness %T.loc13_15.2 [symbolic = %.loc18_4.3 (constants.%.3)]
// CHECK:STDOUT: %.loc18_4.4: %F.type = interface_witness_access %.loc18_4.3, element0 [symbolic = %.loc18_4.4 (constants.%.4)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%T.param_patt: %Interface.type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %T.ref: %Interface.type = name_ref T, %T.loc13_15.1 [symbolic = %T.loc13_15.2 (constants.%T)]
// CHECK:STDOUT: %F.ref: %.1 = name_ref F, @Interface.%.loc11 [template = constants.%.2]
// CHECK:STDOUT: %.loc18_4.1: <witness> = facet_access_witness %T.ref [symbolic = %.loc18_4.3 (constants.%.3)]
// CHECK:STDOUT: %.loc18_4.2: %F.type = interface_witness_access %.loc18_4.1, element0
// CHECK:STDOUT: %.loc18_4.2: %F.type = interface_witness_access %.loc18_4.1, element0 [symbolic = %.loc18_4.4 (constants.%.4)]
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @CallFacet(%T.loc21_14.1: %Interface.type) {
// CHECK:STDOUT: %T.loc21_14.2: %Interface.type = bind_symbolic_name T, 0 [symbolic = %T.loc21_14.2 (constants.%T)]
// CHECK:STDOUT: %T.patt.loc21_14.2: %Interface.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc21_14.2 (constants.%T.patt)]
// CHECK:STDOUT: %.loc21_32.3: type = facet_access_type %T.loc21_14.2 [symbolic = %.loc21_32.3 (constants.%.4)]
// CHECK:STDOUT: %.loc21_32.3: type = facet_access_type %T.loc21_14.2 [symbolic = %.loc21_32.3 (constants.%.5)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%T.param_patt: %Interface.type, %x.param_patt: @CallFacet.%.loc21_32.3 (%.4)) {
// CHECK:STDOUT: fn(%T.param_patt: %Interface.type, %x.param_patt: @CallFacet.%.loc21_32.3 (%.5)) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %x.ref: @CallFacet.%.loc21_32.3 (%.4) = name_ref x, %x
// CHECK:STDOUT: %x.ref: @CallFacet.%.loc21_32.3 (%.5) = name_ref x, %x
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT: }
Expand All @@ -133,6 +135,6 @@ fn CallFacet(T:! Interface, x: T) {
// CHECK:STDOUT: specific @CallFacet(constants.%T) {
// CHECK:STDOUT: %T.loc21_14.2 => constants.%T
// CHECK:STDOUT: %T.patt.loc21_14.2 => constants.%T
// CHECK:STDOUT: %.loc21_32.3 => constants.%.4
// CHECK:STDOUT: %.loc21_32.3 => constants.%.5
// CHECK:STDOUT: }
// CHECK:STDOUT:
12 changes: 9 additions & 3 deletions toolchain/check/testdata/let/compile_time_bindings.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,10 @@ impl i32 as Empty {
// CHECK:STDOUT: %tuple.type.3: type = tuple_type (%empty_tuple.type, %empty_tuple.type) [template]
// CHECK:STDOUT: %tuple.2: %tuple.type.3 = tuple_value (%empty_tuple, %empty_tuple) [template]
// CHECK:STDOUT: %c: %tuple.type.3 = bind_symbolic_name c, 1 [symbolic]
// CHECK:STDOUT: %.5: %empty_tuple.type = tuple_access %b, element0 [symbolic]
// CHECK:STDOUT: %tuple.3: %tuple.type.1 = tuple_value (%empty_tuple) [template]
// CHECK:STDOUT: %.6: %empty_tuple.type = tuple_access %c, element0 [symbolic]
// CHECK:STDOUT: %.7: %empty_tuple.type = tuple_access %c, element1 [symbolic]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
Expand Down Expand Up @@ -369,6 +372,9 @@ impl i32 as Empty {
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %c.loc11_9.2: %tuple.type.3 = bind_symbolic_name c, 1 [symbolic = %c.loc11_9.2 (constants.%c)]
// CHECK:STDOUT: %.loc14_21.6: %empty_tuple.type = tuple_access %b.loc10_8.1, element0 [symbolic = %.loc14_21.6 (constants.%.5)]
// CHECK:STDOUT: %.loc15_24.10: %empty_tuple.type = tuple_access %c.loc11_9.2, element0 [symbolic = %.loc15_24.10 (constants.%.6)]
// CHECK:STDOUT: %.loc15_24.11: %empty_tuple.type = tuple_access %c.loc11_9.2, element1 [symbolic = %.loc15_24.11 (constants.%.7)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%b.param_patt: %tuple.type.1) {
// CHECK:STDOUT: !entry:
Expand Down Expand Up @@ -403,7 +409,7 @@ impl i32 as Empty {
// CHECK:STDOUT: %b1.var: ref %tuple.type.1 = var b1
// CHECK:STDOUT: %b1: ref %tuple.type.1 = bind_name b1, %b1.var
// CHECK:STDOUT: %b.ref: %tuple.type.1 = name_ref b, %b.loc10_8.2 [symbolic = %b.loc10_8.1 (constants.%b)]
// CHECK:STDOUT: %.loc14_21.1: %empty_tuple.type = tuple_access %b.ref, element0
// CHECK:STDOUT: %.loc14_21.1: %empty_tuple.type = tuple_access %b.ref, element0 [symbolic = %.loc14_21.6 (constants.%.5)]
// CHECK:STDOUT: %.loc14_21.2: ref %empty_tuple.type = tuple_access %b1.var, element0
// CHECK:STDOUT: %.loc14_21.3: init %empty_tuple.type = tuple_init () to %.loc14_21.2 [template = constants.%empty_tuple]
// CHECK:STDOUT: %.loc14_21.4: init %empty_tuple.type = converted %.loc14_21.1, %.loc14_21.3 [template = constants.%empty_tuple]
Expand All @@ -419,11 +425,11 @@ impl i32 as Empty {
// CHECK:STDOUT: %c1.var: ref %tuple.type.3 = var c1
// CHECK:STDOUT: %c1: ref %tuple.type.3 = bind_name c1, %c1.var
// CHECK:STDOUT: %c.ref: %tuple.type.3 = name_ref c, %c.loc11_9.1 [symbolic = %c.loc11_9.2 (constants.%c)]
// CHECK:STDOUT: %.loc15_24.1: %empty_tuple.type = tuple_access %c.ref, element0
// CHECK:STDOUT: %.loc15_24.1: %empty_tuple.type = tuple_access %c.ref, element0 [symbolic = %.loc15_24.10 (constants.%.6)]
// CHECK:STDOUT: %.loc15_24.2: ref %empty_tuple.type = tuple_access %c1.var, element0
// CHECK:STDOUT: %.loc15_24.3: init %empty_tuple.type = tuple_init () to %.loc15_24.2 [template = constants.%empty_tuple]
// CHECK:STDOUT: %.loc15_24.4: init %empty_tuple.type = converted %.loc15_24.1, %.loc15_24.3 [template = constants.%empty_tuple]
// CHECK:STDOUT: %.loc15_24.5: %empty_tuple.type = tuple_access %c.ref, element1
// CHECK:STDOUT: %.loc15_24.5: %empty_tuple.type = tuple_access %c.ref, element1 [symbolic = %.loc15_24.11 (constants.%.7)]
// CHECK:STDOUT: %.loc15_24.6: ref %empty_tuple.type = tuple_access %c1.var, element1
// CHECK:STDOUT: %.loc15_24.7: init %empty_tuple.type = tuple_init () to %.loc15_24.6 [template = constants.%empty_tuple]
// CHECK:STDOUT: %.loc15_24.8: init %empty_tuple.type = converted %.loc15_24.5, %.loc15_24.7 [template = constants.%empty_tuple]
Expand Down
Loading

0 comments on commit 4d3b962

Please sign in to comment.