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.
This commit is contained in:
Geoff Romer
2026-06-23 20:12:22 +00:00
committed by GitHub
parent 2271583d6d
commit a8668c9b4e
8 changed files with 116 additions and 252 deletions
+10 -70
View File
@@ -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<SemIR::RefineFormAction>(
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<SemIR::TupleValue>(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<SemIR::RefineFormAction>()) {
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<SemIR::RefineFormAction>(form_id) &&
!context.insts().Is<SemIR::SpliceInst>(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()) <
-4
View File
@@ -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;
-4
View File
@@ -2280,10 +2280,6 @@ auto FormExprAsForm(Context& context, SemIR::LocId loc_id,
return Context::FormExpr::Error;
}
form_inst_id = HandleAction<SemIR::RefineFormAction>(
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,
+80 -108
View File
@@ -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<none>, has_error: false, extended_scopes: [], names: {name(Core): inst70000011, name0: inst70000033}}
// CHECK:STDOUT: name_scope0: {inst: instF, parent_scope: name_scope<none>, 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<none>, index: -1, is_template: 0, is_unused: 0, form: inst<none>}
// CHECK:STDOUT: entity_name70000001: {name: name1, parent_scope: name_scope70000001, index: -1, is_template: 0, is_unused: 0, form: inst<none>}
// CHECK:STDOUT: entity_name70000002: {name: name1, parent_scope: name_scope<none>, index: 0, is_template: 0, is_unused: 0, form: inst<none>}
// 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<none>}
// CHECK:STDOUT: generic70000000: {decl: inst7000002F, bindings: inst_block7000000B, self_specific_id: specific70000000, decl_block_id: inst_block7000000D, definition_block_id: inst_block<none>}
// 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<none>, 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<none>, type: type(inst(FormType))}
// CHECK:STDOUT: inst7000001E: {kind: SymbolicBinding, arg0: entity_name70000002, arg1: inst<none>, 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<none>, 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<none>, 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: {}
+24 -34
View File
@@ -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: <instruction> = refine_form_action %Form [template]
// CHECK:STDOUT: %.80a: Core.Form = splice_inst %.33d [template]
// CHECK:STDOUT: %.af3: <instruction> = 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: <instruction> = 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: <instruction> = 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: <instruction> = 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: <namespace> = 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: <instruction> = 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: <instruction> = 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: <instruction> = 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: <instruction> = 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:
+2 -2
View File
@@ -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;
}
-1
View File
@@ -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)
-29
View File
@@ -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<Parse::NodeId>(
{.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 {