From a8668c9b4e5f68a0e941f8afb46a52ef9337a4cc Mon Sep 17 00:00:00 2001 From: Geoff Romer Date: Tue, 23 Jun 2026 13:12:22 -0700 Subject: [PATCH] Remove `RefineFormAction` (#7393) Wrapping symbolic forms in `RefineFormAction` was making it very difficult to reason about them symbolically, and at least for now we don't really need it. See [this discussion](https://discord.com/channels/655572317891461132/655578254970716160/1516867358751195136) for background and possible future approaches. --- toolchain/check/action.cpp | 80 +------- toolchain/check/action.h | 4 - toolchain/check/convert.cpp | 4 - .../testdata/basics/raw_sem_ir/bundle.carbon | 188 ++++++++---------- .../check/testdata/function/call/form.carbon | 58 +++--- toolchain/sem_ir/formatter.cpp | 4 +- toolchain/sem_ir/inst_kind.def | 1 - toolchain/sem_ir/typed_insts.h | 29 --- 8 files changed, 116 insertions(+), 252 deletions(-) diff --git a/toolchain/check/action.cpp b/toolchain/check/action.cpp index 5494e2835a61..a4a8ffd7892d 100644 --- a/toolchain/check/action.cpp +++ b/toolchain/check/action.cpp @@ -25,45 +25,6 @@ auto PerformAction(Context& context, SemIR::LocId loc_id, .source_id = action.inst_id}); } -auto PerformAction(Context& context, SemIR::LocId loc_id, - SemIR::RefineFormAction action) -> SemIR::InstId { - auto expr_const_id = context.constant_values().Get(action.form_id); - if (!expr_const_id.is_constant()) { - // This is an error which will be diagnosed elsewhere, so we should just - // get out of its way. - return action.form_id; - } - auto expr = - context.insts().Get(context.constant_values().GetInstId(expr_const_id)); - CARBON_KIND_SWITCH(expr) { - case SemIR::InitForm::Kind: - case SemIR::RefForm::Kind: - case SemIR::ValueForm::Kind: - // Primitive forms have no form operands, so the action is a no-op. - return action.form_id; - case CARBON_KIND(SemIR::TupleValue tuple_value): { - SemIR::CopyOnWriteInstBlock new_inst_block(&context.sem_ir(), - tuple_value.elements_id); - for (auto [i, element_id] : llvm::enumerate( - context.inst_blocks().Get(tuple_value.elements_id))) { - new_inst_block.Set(i, HandleAction( - context, loc_id, SemIR::FormType::TypeInstId, - {.type_id = SemIR::InstType::TypeId, - .form_id = element_id})); - } - auto new_inst_block_id = new_inst_block.GetCanonical(); - if (new_inst_block_id == tuple_value.elements_id) { - return action.form_id; - } - return AddInst(context, loc_id, - {.type_id = SemIR::FormType::TypeId, - .elements_id = new_inst_block_id}); - } - default: - CARBON_FATAL("Unexpected kind for non-dependent form constant {0}", expr); - } -} - static auto OperandDependence(Context& context, SemIR::ConstantId const_id) -> SemIR::ConstantDependence { // A type operand makes the instruction dependent if it is a @@ -147,35 +108,6 @@ auto ActionIsPerformable(Context& context, SemIR::Inst action_inst) -> bool { SemIR::ConstantDependence::Template; } - if (auto refine_action = action_inst.TryAs()) { - auto form_const_id = context.constant_values().Get(refine_action->form_id); - auto form_id = context.constant_values().GetInstIdIfValid(form_const_id); - if (!form_id.has_value()) { - // This is an error which will be diagnosed elsewhere, so we should just - // get out of its way. - return true; - } - // A RefineFormAction can be performed if we can identify all of the - // subexpressions of `form_id` that are in form positions. - CARBON_KIND_SWITCH(context.insts().Get(form_id)) { - case SemIR::InitForm::Kind: - case SemIR::RefForm::Kind: - case SemIR::ValueForm::Kind: - case SemIR::TupleValue::Kind: - // These inst kinds are not rewritten by constant evaluation except to - // substitute values for their operands (i.e. their constant kind is - // WheneverPossible, Always, or AlwaysUnique), so we can identify all of - // their form subexpressions. - return true; - default: - // All other inst kinds either can't appear in a form position, or - // may be rewritten by constant evaluation, so we can't identify - // their form subexpressions unless they are already concrete. - return OperandDependence(context, form_const_id) == - SemIR::ConstantDependence::None; - } - } - // A form-parameterized action is performable if we can see at least the top // level of its form's structure (i.e. it is not an action or a splice). if (auto form_parameterized_action = @@ -188,8 +120,16 @@ auto ActionIsPerformable(Context& context, SemIR::Inst action_inst) -> bool { // get out of its way. return true; } - return !context.insts().Is(form_id) && - !context.insts().Is(form_id); + auto form_inst = context.insts().Get(form_id); + switch (form_inst.kind()) { + case SemIR::InitForm::Kind: + case SemIR::RefForm::Kind: + case SemIR::ValueForm::Kind: + case SemIR::ErrorInst::Kind: + return true; + default: + return false; + } } return OperandDependence(context, action_inst.type_id()) < diff --git a/toolchain/check/action.h b/toolchain/check/action.h index a8ef790fb2da..34830ef35457 100644 --- a/toolchain/check/action.h +++ b/toolchain/check/action.h @@ -40,10 +40,6 @@ auto PerformAction(Context& context, SemIR::LocId loc_id, auto PerformAction(Context& context, SemIR::LocId loc_id, SemIR::RefineTypeAction action) -> SemIR::InstId; -// Performs a form refinement action. -auto PerformAction(Context& context, SemIR::LocId loc_id, - SemIR::RefineFormAction action) -> SemIR::InstId; - // Determines whether the given action can be performed immediately (i.e. // whether it is non-template-dependent). auto ActionIsPerformable(Context& context, SemIR::Inst action_inst) -> bool; diff --git a/toolchain/check/convert.cpp b/toolchain/check/convert.cpp index 4c6c264f1549..fbc39ac8d3df 100644 --- a/toolchain/check/convert.cpp +++ b/toolchain/check/convert.cpp @@ -2280,10 +2280,6 @@ auto FormExprAsForm(Context& context, SemIR::LocId loc_id, return Context::FormExpr::Error; } - form_inst_id = HandleAction( - context, loc_id, SemIR::FormType::TypeInstId, - {.type_id = SemIR::InstType::TypeId, .form_id = form_inst_id}); - auto form_const_id = context.constant_values().Get(form_inst_id); if (!form_const_id.is_constant()) { CARBON_DIAGNOSTIC(FormExprEvaluationFailure, Error, diff --git a/toolchain/check/testdata/basics/raw_sem_ir/bundle.carbon b/toolchain/check/testdata/basics/raw_sem_ir/bundle.carbon index 3241dd05fac6..e51153938a7c 100644 --- a/toolchain/check/testdata/basics/raw_sem_ir/bundle.carbon +++ b/toolchain/check/testdata/basics/raw_sem_ir/bundle.carbon @@ -31,20 +31,20 @@ fn F(Form:! Core.Form) ->? Form; // CHECK:STDOUT: clang_decls: {} // CHECK:STDOUT: clang_decl_signatures: {} // CHECK:STDOUT: name_scopes: -// CHECK:STDOUT: name_scope0: {inst: instF, parent_scope: name_scope, has_error: false, extended_scopes: [], names: {name(Core): inst70000011, name0: inst70000033}} +// CHECK:STDOUT: name_scope0: {inst: instF, parent_scope: name_scope, has_error: false, extended_scopes: [], names: {name(Core): inst70000011, name0: inst7000002F}} // CHECK:STDOUT: name_scope70000001: {inst: inst70000011, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name1: inst70000016}} // CHECK:STDOUT: entity_names: // CHECK:STDOUT: entity_name70000000: {name: name(PeriodSelf), parent_scope: name_scope, index: -1, is_template: 0, is_unused: 0, form: inst} // CHECK:STDOUT: entity_name70000001: {name: name1, parent_scope: name_scope70000001, index: -1, is_template: 0, is_unused: 0, form: inst} // CHECK:STDOUT: entity_name70000002: {name: name1, parent_scope: name_scope, index: 0, is_template: 0, is_unused: 0, form: inst} // CHECK:STDOUT: functions: -// CHECK:STDOUT: function70000000: {name: name0, parent_scope: name_scope0, call_param_patterns_id: inst_block70000007, call_params_id: inst_block70000008, return_type_inst_id: inst70000024, return_form_inst_id: inst70000021, return_pattern_id: inst7000002C} +// CHECK:STDOUT: function70000000: {name: name0, parent_scope: name_scope0, call_param_patterns_id: inst_block70000007, call_params_id: inst_block70000008, return_type_inst_id: inst70000020, return_form_inst_id: inst7000001F, return_pattern_id: inst70000028} // CHECK:STDOUT: classes: {} // CHECK:STDOUT: interfaces: {} // CHECK:STDOUT: associated_constants: {} // CHECK:STDOUT: impls: {} // CHECK:STDOUT: generics: -// CHECK:STDOUT: generic70000000: {decl: inst70000033, bindings: inst_block7000000B, self_specific_id: specific70000000, decl_block_id: inst_block7000000D, definition_block_id: inst_block} +// CHECK:STDOUT: generic70000000: {decl: inst7000002F, bindings: inst_block7000000B, self_specific_id: specific70000000, decl_block_id: inst_block7000000D, definition_block_id: inst_block} // CHECK:STDOUT: specifics: // CHECK:STDOUT: specific70000000: {generic: generic70000000, args: inst_block7000000C, decl_block_id: inst_block7000000E, decl_has_error: 0, definition_block_id: inst_block, definition_has_error: 0} // CHECK:STDOUT: specific_interfaces: {} @@ -76,13 +76,13 @@ fn F(Form:! Core.Form) ->? Form; // CHECK:STDOUT: object_layout: // CHECK:STDOUT: size: 0 // CHECK:STDOUT: alignment: 1 -// CHECK:STDOUT: 'type(inst7000003C)': -// CHECK:STDOUT: value_repr: {kind: none, type: type(inst7000003D)} +// CHECK:STDOUT: 'type(inst70000034)': +// CHECK:STDOUT: value_repr: {kind: none, type: type(inst70000035)} // CHECK:STDOUT: object_layout: // CHECK:STDOUT: size: 0 // CHECK:STDOUT: alignment: 1 -// CHECK:STDOUT: 'type(inst7000003D)': -// CHECK:STDOUT: value_repr: {kind: none, type: type(inst7000003D)} +// CHECK:STDOUT: 'type(inst70000035)': +// CHECK:STDOUT: value_repr: {kind: none, type: type(inst70000035)} // CHECK:STDOUT: object_layout: // CHECK:STDOUT: size: 0 // CHECK:STDOUT: alignment: 1 @@ -106,40 +106,32 @@ fn F(Form:! Core.Form) ->? Form; // CHECK:STDOUT: inst7000001D: {kind: SymbolicBinding, arg0: entity_name70000002, arg1: inst, type: type(inst(FormType))} // CHECK:STDOUT: inst7000001E: {kind: SymbolicBinding, arg0: entity_name70000002, arg1: inst, type: type(inst(FormType))} // CHECK:STDOUT: inst7000001F: {kind: NameRef, arg0: name1, arg1: inst7000001C, type: type(inst(FormType))} -// CHECK:STDOUT: inst70000020: {kind: RefineFormAction, arg0: inst7000001F, type: type(inst(InstType))} -// CHECK:STDOUT: inst70000021: {kind: SpliceInst, arg0: inst70000020, type: type(inst(FormType))} -// CHECK:STDOUT: inst70000022: {kind: SpliceInst, arg0: inst70000020, type: type(inst(FormType))} -// CHECK:STDOUT: inst70000023: {kind: SpliceInst, arg0: inst70000020, type: type(inst(FormType))} -// CHECK:STDOUT: inst70000024: {kind: TypeComponentOf, arg0: inst70000022, type: type(TypeType)} -// CHECK:STDOUT: inst70000025: {kind: PatternType, arg0: inst70000024, type: type(TypeType)} -// CHECK:STDOUT: inst70000026: {kind: OutFormParamPatternAction, arg0: inst70000021, type: type(inst(InstType))} -// CHECK:STDOUT: inst70000027: {kind: SpliceInst, arg0: inst70000026, type: type(symbolic_constant7000000D)} -// CHECK:STDOUT: inst70000028: {kind: SpliceInst, arg0: inst70000026, type: type(symbolic_constant70000009)} -// CHECK:STDOUT: inst70000029: {kind: TypeComponentOf, arg0: inst70000023, type: type(TypeType)} -// CHECK:STDOUT: inst7000002A: {kind: PatternType, arg0: inst70000029, type: type(TypeType)} -// CHECK:STDOUT: inst7000002B: {kind: SpliceInst, arg0: inst70000026, type: type(symbolic_constant7000000D)} -// CHECK:STDOUT: inst7000002C: {kind: ReturnSlotPattern, arg0: inst70000027, arg1: inst70000024, type: type(symbolic_constant7000000D)} -// CHECK:STDOUT: inst7000002D: {kind: ReturnSlotPattern, arg0: inst70000028, arg1: inst70000024, type: type(symbolic_constant70000009)} -// CHECK:STDOUT: inst7000002E: {kind: ReturnSlotPattern, arg0: inst7000002B, arg1: inst70000029, type: type(symbolic_constant7000000D)} -// CHECK:STDOUT: inst7000002F: {kind: SpliceBlock, arg0: inst_block70000005, arg1: inst70000017, type: type(TypeType)} -// CHECK:STDOUT: inst70000030: {kind: CalleePatternMatchAction, arg0: bundle70000000, type: type(inst(InstType))} -// CHECK:STDOUT: inst70000031: {kind: SpliceInst, arg0: inst70000030, type: type(symbolic_constant7000000D)} -// CHECK:STDOUT: inst70000032: {kind: ReturnSlot, arg0: inst70000024, arg1: inst70000031, type: type(symbolic_constant7000000C)} -// CHECK:STDOUT: inst70000033: {kind: FunctionDecl, arg0: function70000000, arg1: inst_block7000000A, type: type(inst7000003C)} -// CHECK:STDOUT: inst70000034: {kind: RefineFormAction, arg0: inst7000001D, type: type(inst(InstType))} -// CHECK:STDOUT: inst70000035: {kind: SpliceInst, arg0: inst70000034, type: type(inst(FormType))} -// CHECK:STDOUT: inst70000036: {kind: OutFormParamPatternAction, arg0: inst70000035, type: type(inst(InstType))} -// CHECK:STDOUT: inst70000037: {kind: TypeComponentOf, arg0: inst70000035, type: type(TypeType)} -// CHECK:STDOUT: inst70000038: {kind: PatternType, arg0: inst70000037, type: type(TypeType)} -// CHECK:STDOUT: inst70000039: {kind: SpliceInst, arg0: inst70000036, type: type(symbolic_constant70000016)} -// CHECK:STDOUT: inst7000003A: {kind: ReturnSlotPattern, arg0: inst70000039, arg1: inst70000037, type: type(symbolic_constant70000016)} -// CHECK:STDOUT: inst7000003B: {kind: CalleePatternMatchAction, arg0: bundle70000001, type: type(inst(InstType))} -// CHECK:STDOUT: inst7000003C: {kind: FunctionType, arg0: function70000000, arg1: specific, type: type(TypeType)} -// CHECK:STDOUT: inst7000003D: {kind: TupleType, arg0: inst_block_empty, type: type(TypeType)} -// CHECK:STDOUT: inst7000003E: {kind: StructValue, arg0: inst_block_empty, type: type(inst7000003C)} +// CHECK:STDOUT: inst70000020: {kind: TypeComponentOf, arg0: inst7000001D, type: type(TypeType)} +// CHECK:STDOUT: inst70000021: {kind: PatternType, arg0: inst70000020, type: type(TypeType)} +// CHECK:STDOUT: inst70000022: {kind: OutFormParamPatternAction, arg0: inst7000001F, type: type(inst(InstType))} +// CHECK:STDOUT: inst70000023: {kind: SpliceInst, arg0: inst70000022, type: type(symbolic_constant7000000A)} +// CHECK:STDOUT: inst70000024: {kind: SpliceInst, arg0: inst70000022, type: type(symbolic_constant70000006)} +// CHECK:STDOUT: inst70000025: {kind: TypeComponentOf, arg0: inst7000001E, type: type(TypeType)} +// CHECK:STDOUT: inst70000026: {kind: PatternType, arg0: inst70000025, type: type(TypeType)} +// CHECK:STDOUT: inst70000027: {kind: SpliceInst, arg0: inst70000022, type: type(symbolic_constant7000000A)} +// CHECK:STDOUT: inst70000028: {kind: ReturnSlotPattern, arg0: inst70000023, arg1: inst70000020, type: type(symbolic_constant7000000A)} +// CHECK:STDOUT: inst70000029: {kind: ReturnSlotPattern, arg0: inst70000024, arg1: inst70000020, type: type(symbolic_constant70000006)} +// CHECK:STDOUT: inst7000002A: {kind: ReturnSlotPattern, arg0: inst70000027, arg1: inst70000025, type: type(symbolic_constant7000000A)} +// CHECK:STDOUT: inst7000002B: {kind: SpliceBlock, arg0: inst_block70000005, arg1: inst70000017, type: type(TypeType)} +// CHECK:STDOUT: inst7000002C: {kind: CalleePatternMatchAction, arg0: bundle70000000, type: type(inst(InstType))} +// CHECK:STDOUT: inst7000002D: {kind: SpliceInst, arg0: inst7000002C, type: type(symbolic_constant7000000A)} +// CHECK:STDOUT: inst7000002E: {kind: ReturnSlot, arg0: inst70000020, arg1: inst7000002D, type: type(symbolic_constant70000009)} +// CHECK:STDOUT: inst7000002F: {kind: FunctionDecl, arg0: function70000000, arg1: inst_block7000000A, type: type(inst70000034)} +// CHECK:STDOUT: inst70000030: {kind: OutFormParamPatternAction, arg0: inst7000001D, type: type(inst(InstType))} +// CHECK:STDOUT: inst70000031: {kind: SpliceInst, arg0: inst70000030, type: type(symbolic_constant70000006)} +// CHECK:STDOUT: inst70000032: {kind: ReturnSlotPattern, arg0: inst70000031, arg1: inst70000020, type: type(symbolic_constant70000006)} +// CHECK:STDOUT: inst70000033: {kind: CalleePatternMatchAction, arg0: bundle70000001, type: type(inst(InstType))} +// CHECK:STDOUT: inst70000034: {kind: FunctionType, arg0: function70000000, arg1: specific, type: type(TypeType)} +// CHECK:STDOUT: inst70000035: {kind: TupleType, arg0: inst_block_empty, type: type(TypeType)} +// CHECK:STDOUT: inst70000036: {kind: StructValue, arg0: inst_block_empty, type: type(inst70000034)} // CHECK:STDOUT: bundles: -// CHECK:STDOUT: bundle70000000: {arg0: inst70000027, arg1: call_param0} -// CHECK:STDOUT: bundle70000001: {arg0: inst70000039, arg1: call_param0} +// CHECK:STDOUT: bundle70000000: {arg0: inst70000023, arg1: call_param0} +// CHECK:STDOUT: bundle70000001: {arg0: inst70000031, arg1: call_param0} // CHECK:STDOUT: constant_values: // CHECK:STDOUT: values: // CHECK:STDOUT: instF: concrete_constant(instF) @@ -159,65 +151,50 @@ fn F(Form:! Core.Form) ->? Form; // CHECK:STDOUT: inst7000001E: symbolic_constant70000004 // CHECK:STDOUT: inst7000001F: symbolic_constant70000004 // CHECK:STDOUT: inst70000020: symbolic_constant70000005 -// CHECK:STDOUT: inst70000021: symbolic_constant70000007 -// CHECK:STDOUT: inst70000022: symbolic_constant70000006 -// CHECK:STDOUT: inst70000023: symbolic_constant70000007 +// CHECK:STDOUT: inst70000021: symbolic_constant70000006 +// CHECK:STDOUT: inst70000022: symbolic_constant70000007 +// CHECK:STDOUT: inst70000023: symbolic_constant7000000B // CHECK:STDOUT: inst70000024: symbolic_constant70000008 // CHECK:STDOUT: inst70000025: symbolic_constant70000009 // CHECK:STDOUT: inst70000026: symbolic_constant7000000A -// CHECK:STDOUT: inst70000027: symbolic_constant7000000E -// CHECK:STDOUT: inst70000028: symbolic_constant7000000B +// CHECK:STDOUT: inst70000027: symbolic_constant7000000B +// CHECK:STDOUT: inst70000028: symbolic_constant7000000D // CHECK:STDOUT: inst70000029: symbolic_constant7000000C // CHECK:STDOUT: inst7000002A: symbolic_constant7000000D -// CHECK:STDOUT: inst7000002B: symbolic_constant7000000E -// CHECK:STDOUT: inst7000002C: symbolic_constant70000010 -// CHECK:STDOUT: inst7000002D: symbolic_constant7000000F -// CHECK:STDOUT: inst7000002E: symbolic_constant70000010 -// CHECK:STDOUT: inst7000002F: concrete_constant(inst(FormType)) -// CHECK:STDOUT: inst70000030: symbolic_constant70000011 -// CHECK:STDOUT: inst70000033: concrete_constant(inst7000003E) -// CHECK:STDOUT: inst70000034: symbolic_constant70000012 -// CHECK:STDOUT: inst70000035: symbolic_constant70000013 -// CHECK:STDOUT: inst70000036: symbolic_constant70000014 -// CHECK:STDOUT: inst70000037: symbolic_constant70000015 -// CHECK:STDOUT: inst70000038: symbolic_constant70000016 -// CHECK:STDOUT: inst70000039: symbolic_constant70000017 -// CHECK:STDOUT: inst7000003A: symbolic_constant70000018 -// CHECK:STDOUT: inst7000003B: symbolic_constant70000019 -// CHECK:STDOUT: inst7000003C: concrete_constant(inst7000003C) -// CHECK:STDOUT: inst7000003D: concrete_constant(inst7000003D) -// CHECK:STDOUT: inst7000003E: concrete_constant(inst7000003E) +// CHECK:STDOUT: inst7000002B: concrete_constant(inst(FormType)) +// CHECK:STDOUT: inst7000002C: symbolic_constant7000000E +// CHECK:STDOUT: inst7000002F: concrete_constant(inst70000036) +// CHECK:STDOUT: inst70000030: symbolic_constant7000000F +// CHECK:STDOUT: inst70000031: symbolic_constant70000010 +// CHECK:STDOUT: inst70000032: symbolic_constant70000011 +// CHECK:STDOUT: inst70000033: symbolic_constant70000012 +// CHECK:STDOUT: inst70000034: concrete_constant(inst70000034) +// CHECK:STDOUT: inst70000035: concrete_constant(inst70000035) +// CHECK:STDOUT: inst70000036: concrete_constant(inst70000036) // CHECK:STDOUT: symbolic_constants: // CHECK:STDOUT: symbolic_constant70000000: {inst: inst70000014, kind: self, attached: null} // CHECK:STDOUT: symbolic_constant70000001: {inst: inst7000001A, kind: checked, attached: null} // CHECK:STDOUT: symbolic_constant70000002: {inst: inst7000001A, kind: checked, attached: {generic: generic70000000, index: generic_inst_in_decl0}} // CHECK:STDOUT: symbolic_constant70000003: {inst: inst7000001D, kind: checked, attached: null} // CHECK:STDOUT: symbolic_constant70000004: {inst: inst7000001D, kind: checked, attached: {generic: generic70000000, index: generic_inst_in_decl1}} -// CHECK:STDOUT: symbolic_constant70000005: {inst: inst70000020, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl2}} -// CHECK:STDOUT: symbolic_constant70000006: {inst: inst70000022, kind: template, attached: null} -// CHECK:STDOUT: symbolic_constant70000007: {inst: inst70000022, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl3}} +// CHECK:STDOUT: symbolic_constant70000005: {inst: inst70000020, kind: checked, attached: null} +// CHECK:STDOUT: symbolic_constant70000006: {inst: inst70000021, kind: checked, attached: null} +// CHECK:STDOUT: symbolic_constant70000007: {inst: inst70000022, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl2}} // CHECK:STDOUT: symbolic_constant70000008: {inst: inst70000024, kind: template, attached: null} -// CHECK:STDOUT: symbolic_constant70000009: {inst: inst70000025, kind: template, attached: null} -// CHECK:STDOUT: symbolic_constant7000000A: {inst: inst70000026, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl4}} -// CHECK:STDOUT: symbolic_constant7000000B: {inst: inst70000028, kind: template, attached: null} -// CHECK:STDOUT: symbolic_constant7000000C: {inst: inst70000024, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl5}} -// CHECK:STDOUT: symbolic_constant7000000D: {inst: inst70000025, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl6}} -// CHECK:STDOUT: symbolic_constant7000000E: {inst: inst70000028, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl7}} -// CHECK:STDOUT: symbolic_constant7000000F: {inst: inst7000002D, kind: template, attached: null} -// CHECK:STDOUT: symbolic_constant70000010: {inst: inst7000002D, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl8}} -// CHECK:STDOUT: symbolic_constant70000011: {inst: inst70000030, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl9}} -// CHECK:STDOUT: symbolic_constant70000012: {inst: inst70000034, kind: template, attached: null} -// CHECK:STDOUT: symbolic_constant70000013: {inst: inst70000035, kind: template, attached: null} -// CHECK:STDOUT: symbolic_constant70000014: {inst: inst70000036, kind: template, attached: null} -// CHECK:STDOUT: symbolic_constant70000015: {inst: inst70000037, kind: template, attached: null} -// CHECK:STDOUT: symbolic_constant70000016: {inst: inst70000038, kind: template, attached: null} -// CHECK:STDOUT: symbolic_constant70000017: {inst: inst70000039, kind: template, attached: null} -// CHECK:STDOUT: symbolic_constant70000018: {inst: inst7000003A, kind: template, attached: null} -// CHECK:STDOUT: symbolic_constant70000019: {inst: inst7000003B, kind: template, attached: null} +// CHECK:STDOUT: symbolic_constant70000009: {inst: inst70000020, kind: checked, attached: {generic: generic70000000, index: generic_inst_in_decl3}} +// CHECK:STDOUT: symbolic_constant7000000A: {inst: inst70000021, kind: checked, attached: {generic: generic70000000, index: generic_inst_in_decl4}} +// CHECK:STDOUT: symbolic_constant7000000B: {inst: inst70000024, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl5}} +// CHECK:STDOUT: symbolic_constant7000000C: {inst: inst70000029, kind: template, attached: null} +// CHECK:STDOUT: symbolic_constant7000000D: {inst: inst70000029, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl6}} +// CHECK:STDOUT: symbolic_constant7000000E: {inst: inst7000002C, kind: template, attached: {generic: generic70000000, index: generic_inst_in_decl7}} +// CHECK:STDOUT: symbolic_constant7000000F: {inst: inst70000030, kind: template, attached: null} +// CHECK:STDOUT: symbolic_constant70000010: {inst: inst70000031, kind: template, attached: null} +// CHECK:STDOUT: symbolic_constant70000011: {inst: inst70000032, kind: template, attached: null} +// CHECK:STDOUT: symbolic_constant70000012: {inst: inst70000033, kind: template, attached: null} // CHECK:STDOUT: inst_blocks: // CHECK:STDOUT: inst_block_empty: {} // CHECK:STDOUT: exports: -// CHECK:STDOUT: 0: inst70000033 +// CHECK:STDOUT: 0: inst7000002F // CHECK:STDOUT: generated: {} // CHECK:STDOUT: imports: // CHECK:STDOUT: 0: inst70000011 @@ -230,20 +207,19 @@ fn F(Form:! Core.Form) ->? Form; // CHECK:STDOUT: inst_block70000006: // CHECK:STDOUT: 0: inst70000019 // CHECK:STDOUT: inst_block70000007: -// CHECK:STDOUT: 0: inst70000027 +// CHECK:STDOUT: 0: inst70000023 // CHECK:STDOUT: inst_block70000008: -// CHECK:STDOUT: 0: inst70000031 +// CHECK:STDOUT: 0: inst7000002D // CHECK:STDOUT: inst_block70000009: // CHECK:STDOUT: 0: inst70000019 -// CHECK:STDOUT: 1: inst7000002C +// CHECK:STDOUT: 1: inst70000028 // CHECK:STDOUT: inst_block7000000A: // CHECK:STDOUT: 0: inst7000001F -// CHECK:STDOUT: 1: inst70000021 -// CHECK:STDOUT: 2: inst70000027 -// CHECK:STDOUT: 3: inst7000002F -// CHECK:STDOUT: 4: inst7000001C -// CHECK:STDOUT: 5: inst70000031 -// CHECK:STDOUT: 6: inst70000032 +// CHECK:STDOUT: 1: inst70000023 +// CHECK:STDOUT: 2: inst7000002B +// CHECK:STDOUT: 3: inst7000001C +// CHECK:STDOUT: 4: inst7000002D +// CHECK:STDOUT: 5: inst7000002E // CHECK:STDOUT: inst_block7000000B: // CHECK:STDOUT: 0: inst7000001C // CHECK:STDOUT: inst_block7000000C: @@ -251,29 +227,25 @@ fn F(Form:! Core.Form) ->? Form; // CHECK:STDOUT: inst_block7000000D: // CHECK:STDOUT: 0: inst7000001B // CHECK:STDOUT: 1: inst7000001E -// CHECK:STDOUT: 2: inst70000020 -// CHECK:STDOUT: 3: inst70000023 +// CHECK:STDOUT: 2: inst70000022 +// CHECK:STDOUT: 3: inst70000025 // CHECK:STDOUT: 4: inst70000026 -// CHECK:STDOUT: 5: inst70000029 +// CHECK:STDOUT: 5: inst70000027 // CHECK:STDOUT: 6: inst7000002A -// CHECK:STDOUT: 7: inst7000002B -// CHECK:STDOUT: 8: inst7000002E -// CHECK:STDOUT: 9: inst70000030 +// CHECK:STDOUT: 7: inst7000002C // CHECK:STDOUT: inst_block7000000E: // CHECK:STDOUT: 0: inst7000001A // CHECK:STDOUT: 1: inst7000001D -// CHECK:STDOUT: 2: inst70000034 -// CHECK:STDOUT: 3: inst70000035 -// CHECK:STDOUT: 4: inst70000036 -// CHECK:STDOUT: 5: inst70000037 -// CHECK:STDOUT: 6: inst70000038 -// CHECK:STDOUT: 7: inst70000039 -// CHECK:STDOUT: 8: inst7000003A -// CHECK:STDOUT: 9: inst7000003B +// CHECK:STDOUT: 2: inst70000030 +// CHECK:STDOUT: 3: inst70000020 +// CHECK:STDOUT: 4: inst70000021 +// CHECK:STDOUT: 5: inst70000031 +// CHECK:STDOUT: 6: inst70000032 +// CHECK:STDOUT: 7: inst70000033 // CHECK:STDOUT: inst_block7000000F: // CHECK:STDOUT: 0: instF // CHECK:STDOUT: 1: inst70000010 -// CHECK:STDOUT: 2: inst70000033 +// CHECK:STDOUT: 2: inst7000002F // CHECK:STDOUT: value_stores: // CHECK:STDOUT: shared_values: // CHECK:STDOUT: ints: {} diff --git a/toolchain/check/testdata/function/call/form.carbon b/toolchain/check/testdata/function/call/form.carbon index 37c75d3ba4c4..699dffc79985 100644 --- a/toolchain/check/testdata/function/call/form.carbon +++ b/toolchain/check/testdata/function/call/form.carbon @@ -566,19 +566,14 @@ fn F(Form:! Core.Form) ->? Form; // CHECK:STDOUT: %pattern_type.13f: type = pattern_type Core.Form [concrete] // CHECK:STDOUT: %Form.patt: %pattern_type.13f = symbolic_binding_pattern Form, 0 [symbolic] // CHECK:STDOUT: %Form: Core.Form = symbolic_binding Form, 0 [symbolic] -// CHECK:STDOUT: %.344: Core.Form = splice_inst @F.%.loc4_28.1 [template] -// CHECK:STDOUT: %.82f: type = type_component_of %.344 [template] -// CHECK:STDOUT: %pattern_type.ec7: type = pattern_type %.82f [template] -// CHECK:STDOUT: %.b9b: %pattern_type.ec7 = splice_inst @F.%.loc4_24.2 [template] -// CHECK:STDOUT: %return.patt.96f: %pattern_type.ec7 = return_slot_pattern %.b9b, %.82f [template] -// CHECK:STDOUT: %.33d: = refine_form_action %Form [template] -// CHECK:STDOUT: %.80a: Core.Form = splice_inst %.33d [template] -// CHECK:STDOUT: %.af3: = out_form_param_pattern_action %.80a [template] -// CHECK:STDOUT: %.465: type = type_component_of %.80a [template] -// CHECK:STDOUT: %pattern_type.a51: type = pattern_type %.465 [template] -// CHECK:STDOUT: %.3c2: %pattern_type.a51 = splice_inst %.af3 [template] -// CHECK:STDOUT: %return.patt.de0: %pattern_type.a51 = return_slot_pattern %.3c2, %.465 [template] -// CHECK:STDOUT: %.849: = callee_pattern_match_action %.3c2, call_param0 [template] +// CHECK:STDOUT: %.42f: type = type_component_of %Form [symbolic] +// CHECK:STDOUT: %pattern_type.177: type = pattern_type %.42f [symbolic] +// CHECK:STDOUT: %.35a: %pattern_type.177 = splice_inst @F.%.loc4_24.2 [template] +// CHECK:STDOUT: %return.patt.5b7: %pattern_type.177 = return_slot_pattern %.35a, %.42f [template] +// CHECK:STDOUT: %.94f: = out_form_param_pattern_action %Form [template] +// CHECK:STDOUT: %.1ac: %pattern_type.177 = splice_inst %.94f [template] +// CHECK:STDOUT: %return.patt.333: %pattern_type.177 = return_slot_pattern %.1ac, %.42f [template] +// CHECK:STDOUT: %.82b: = callee_pattern_match_action %.1ac, call_param0 [template] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: } @@ -595,47 +590,42 @@ fn F(Form:! Core.Form) ->? Form; // CHECK:STDOUT: file { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { // CHECK:STDOUT: %Form.patt.loc4_10.1: %pattern_type.13f = symbolic_binding_pattern Form, 0 [symbolic = %Form.patt.loc4_10.2 (constants.%Form.patt)] -// CHECK:STDOUT: %return.patt.loc4_24.1: @F.%pattern_type (%pattern_type.ec7) = return_slot_pattern %.loc4_24.6, constants.%.82f [template = %return.patt.loc4_24.2 (constants.%return.patt.96f)] +// CHECK:STDOUT: %return.patt.loc4_24.1: @F.%pattern_type (%pattern_type.177) = return_slot_pattern %.loc4_24.6, constants.%.42f [template = %return.patt.loc4_24.2 (constants.%return.patt.5b7)] // CHECK:STDOUT: } { // CHECK:STDOUT: %Form.ref.loc4_28: Core.Form = name_ref Form, %Form.loc4_10.2 [symbolic = %Form.loc4_10.1 (constants.%Form)] -// CHECK:STDOUT: %.loc4_28.3: Core.Form = splice_inst %.loc4_28.1 [template = %.loc4_28.2 (constants.%.344)] -// CHECK:STDOUT: %.loc4_24.6: @F.%pattern_type (%pattern_type.ec7) = splice_inst %.loc4_24.2 [template = %.loc4_24.4 (constants.%.b9b)] +// CHECK:STDOUT: %.loc4_24.6: @F.%pattern_type (%pattern_type.177) = splice_inst %.loc4_24.2 [template = %.loc4_24.4 (constants.%.35a)] // CHECK:STDOUT: %.loc4_17: type = splice_block %Form.ref.loc4_17 [concrete = Core.Form] { // CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %Form.ref.loc4_17: type = name_ref Form, imports.%Core.Form [concrete = Core.Form] // CHECK:STDOUT: } // CHECK:STDOUT: %Form.loc4_10.2: Core.Form = symbolic_binding Form, 0 [symbolic = %Form.loc4_10.1 (constants.%Form)] -// CHECK:STDOUT: %.loc4_24.1: @F.%pattern_type (%pattern_type.ec7) = splice_inst %.loc4_24.5 -// CHECK:STDOUT: %return: @F.%.loc4_24.3 (%.82f) = return_slot %.loc4_24.1 +// CHECK:STDOUT: %.loc4_24.1: @F.%pattern_type (%pattern_type.177) = splice_inst %.loc4_24.5 +// CHECK:STDOUT: %return: @F.%.loc4_24.3 (%.42f) = return_slot %.loc4_24.1 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%Form.loc4_10.2: Core.Form) { // CHECK:STDOUT: %Form.patt.loc4_10.2: %pattern_type.13f = symbolic_binding_pattern Form, 0 [symbolic = %Form.patt.loc4_10.2 (constants.%Form.patt)] // CHECK:STDOUT: %Form.loc4_10.1: Core.Form = symbolic_binding Form, 0 [symbolic = %Form.loc4_10.1 (constants.%Form)] -// CHECK:STDOUT: %.loc4_28.1: = refine_form_action %Form.ref.loc4_28 [template] -// CHECK:STDOUT: %.loc4_28.2: Core.Form = splice_inst %.loc4_28.1 [template = %.loc4_28.2 (constants.%.344)] -// CHECK:STDOUT: %.loc4_24.2: = out_form_param_pattern_action %.loc4_28.3 [template] -// CHECK:STDOUT: %.loc4_24.3: type = type_component_of %.loc4_28.2 [template = %.loc4_24.3 (constants.%.82f)] -// CHECK:STDOUT: %pattern_type: type = pattern_type %.loc4_24.3 [template = %pattern_type (constants.%pattern_type.ec7)] -// CHECK:STDOUT: %.loc4_24.4: @F.%pattern_type (%pattern_type.ec7) = splice_inst %.loc4_24.2 [template = %.loc4_24.4 (constants.%.b9b)] -// CHECK:STDOUT: %return.patt.loc4_24.2: @F.%pattern_type (%pattern_type.ec7) = return_slot_pattern %.loc4_24.4, %.loc4_24.3 [template = %return.patt.loc4_24.2 (constants.%return.patt.96f)] +// CHECK:STDOUT: %.loc4_24.2: = out_form_param_pattern_action %Form.ref.loc4_28 [template] +// CHECK:STDOUT: %.loc4_24.3: type = type_component_of %Form.loc4_10.1 [symbolic = %.loc4_24.3 (constants.%.42f)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %.loc4_24.3 [symbolic = %pattern_type (constants.%pattern_type.177)] +// CHECK:STDOUT: %.loc4_24.4: @F.%pattern_type (%pattern_type.177) = splice_inst %.loc4_24.2 [template = %.loc4_24.4 (constants.%.35a)] +// CHECK:STDOUT: %return.patt.loc4_24.2: @F.%pattern_type (%pattern_type.177) = return_slot_pattern %.loc4_24.4, %.loc4_24.3 [template = %return.patt.loc4_24.2 (constants.%return.patt.5b7)] // CHECK:STDOUT: %.loc4_24.5: = callee_pattern_match_action %.loc4_24.6, call_param0 [template] // CHECK:STDOUT: -// CHECK:STDOUT: fn() -> out %.loc4_24.1:? @F.%.loc4_28.1 (@F.%.loc4_28.1); +// CHECK:STDOUT: fn() -> out %.loc4_24.1:? %Form; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%Form) { // CHECK:STDOUT: %Form.patt.loc4_10.2 => constants.%Form.patt // CHECK:STDOUT: %Form.loc4_10.1 => constants.%Form -// CHECK:STDOUT: %.loc4_28.1 => constants.%.33d -// CHECK:STDOUT: %.loc4_28.2 => constants.%.80a -// CHECK:STDOUT: %.loc4_24.2 => constants.%.af3 -// CHECK:STDOUT: %.loc4_24.3 => constants.%.465 -// CHECK:STDOUT: %pattern_type => constants.%pattern_type.a51 -// CHECK:STDOUT: %.loc4_24.4 => constants.%.3c2 -// CHECK:STDOUT: %return.patt.loc4_24.2 => constants.%return.patt.de0 -// CHECK:STDOUT: %.loc4_24.5 => constants.%.849 +// CHECK:STDOUT: %.loc4_24.2 => constants.%.94f +// CHECK:STDOUT: %.loc4_24.3 => constants.%.42f +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.177 +// CHECK:STDOUT: %.loc4_24.4 => constants.%.1ac +// CHECK:STDOUT: %return.patt.loc4_24.2 => constants.%return.patt.333 +// CHECK:STDOUT: %.loc4_24.5 => constants.%.82b // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/sem_ir/formatter.cpp b/toolchain/sem_ir/formatter.cpp index 7abaa1c8fa15..bdaba2ce9e77 100644 --- a/toolchain/sem_ir/formatter.cpp +++ b/toolchain/sem_ir/formatter.cpp @@ -784,12 +784,12 @@ auto Formatter::FormatFunctionSignature(InstBlockId params_id, FormatInstAsType(return_form_id); break; } - case CARBON_KIND(SpliceInst splice): { + case CARBON_KIND(SymbolicBinding _): { out() << "out "; FormatName(params[i]); out() << ":? "; // A form isn't a type, but it's close enough for formatting purposes. - FormatInstAsType(splice.inst_id); + FormatInstAsType(return_form_id); ++i; break; } diff --git a/toolchain/sem_ir/inst_kind.def b/toolchain/sem_ir/inst_kind.def index 5ce7c6deb24d..3ed1c1f64b91 100644 --- a/toolchain/sem_ir/inst_kind.def +++ b/toolchain/sem_ir/inst_kind.def @@ -52,7 +52,6 @@ CARBON_SEM_IR_INST_KIND(ClassInit) CARBON_SEM_IR_INST_KIND(ClassType) CARBON_SEM_IR_INST_KIND(CompleteTypeWitness) CARBON_SEM_IR_INST_KIND(ConstType) -CARBON_SEM_IR_INST_KIND(RefineFormAction) CARBON_SEM_IR_INST_KIND(ConvertToValueAction) CARBON_SEM_IR_INST_KIND(Converted) CARBON_SEM_IR_INST_KIND(CppOverloadSetType) diff --git a/toolchain/sem_ir/typed_insts.h b/toolchain/sem_ir/typed_insts.h index 49c60c551cf7..e38814b3abad 100644 --- a/toolchain/sem_ir/typed_insts.h +++ b/toolchain/sem_ir/typed_insts.h @@ -1450,35 +1450,6 @@ struct RefBinding { InstId value_id; }; -// An action that performs form refinement of the form expression `form_id`: -// for each operand of `form_id` in a position where a form is expected, if the -// operand is not a concrete constant, it is wrapped in a `RefineFormAction`. -// A `RefineFormAction` can be performed (i.e. is non-template-dependent) if we -// can identify the form operands of `form_id`, which is typically possible only -// if it will not be rewritten by constant evaluation except to substitute -// values for its operands. As usual when creating Actions, if possible the -// nested `RefineFormActions` are performed immediately, and not added to the -// SemIR. -// -// This ensures that a form expression is template-dependent if it depends on -// any non-concrete constants in form positions, even if those constants are not -// themselves template-dependent. Unlike type refinement, form refinement does -// not necessarily produce a concrete result, but it moves as far as possible -// toward a state where non-concrete constants occur only in type positions, and -// so the structure of the form is concretely known even if its type component -// remains symbolic. -struct RefineFormAction { - static constexpr auto Kind = InstKind::RefineFormAction.Define( - {.ir_name = "refine_form_action", - .constant_kind = InstConstantKind::ConstantInstAction, - .is_lowered = false}); - - // Always `Core.Form`. - TypeId type_id; - - MetaInstId form_id; -}; - // An action that performs type refinement for an instruction, by creating an // instruction that converts from a template symbolic type to a concrete type. struct RefineTypeAction {