diff --git a/src/v2/compiler/body_lowering_fold.dag b/src/v2/compiler/body_lowering_fold.dag index 7db7630f653..b82e9342e4d 100644 --- a/src/v2/compiler/body_lowering_fold.dag +++ b/src/v2/compiler/body_lowering_fold.dag @@ -10030,8 +10030,8 @@ fn body_lower_type_decl_record_name_optional(shell: Node) -> Optional { // v2.compiler.normalized_tree NormalizedTree type_declaration_kinds. One value per declaration: a record // and a refinement are authored alternatives, so the carrier has no state naming one declaration as // both. A record is what body_lower_type_decl_record_name_optional says; otherwise a where clause -- -// here still its dag_surface_where_refinement_clause production shell, the parse-level form of the arm -// the by-body dispatch finds as a Named edge -- makes a refinement; anything else carries no kind, and +// the same host body_lower_type_decl_by_body finds (body_lower_find_where_host_conj), not a second +// walk that only recognises a production shell -- makes a refinement; anything else carries no kind, and // a plain Conj member without one is undecided downstream, never inferred. type DeclaredTypeKind = DeclaredRecord { name: Symbol } @@ -10045,7 +10045,7 @@ fn body_lower_type_decl_declared_kind_optional(shell: Node) -> Optional Absent Present { value: captured } => - match body_lower_find_production_shell_optional(root: captured, emitted: ^dag_surface_where_refinement_clause) { + match body_lower_find_where_host_conj(root: captured) { Absent => Absent Present { value: _ } => match dag_surface_kw_then_ident_from_captured(captured: captured) { diff --git a/src/v2/extdeps/languages/rust_test_fixtures.dag b/src/v2/extdeps/languages/rust_test_fixtures.dag index d39a8ce8804..145d4033d05 100644 --- a/src/v2/extdeps/languages/rust_test_fixtures.dag +++ b/src/v2/extdeps/languages/rust_test_fixtures.dag @@ -8,6 +8,7 @@ import std.algebra { Cons, Empty } import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } import v2.extdeps.languages.dag { dag_bind_arrow_with_body_fixture } +import v2.std.arrow_signature { declared_signature } import v2.extdeps.languages.rust { rust_add_declared_inhabitants_root, @@ -3429,10 +3430,12 @@ fn rust_arrow_with_body_node( return_type_binding: Symbol, body: Node ) -> Node { + let domain = rust_nullary_arrow_domain_conj_node() + let signature = declared_signature(params: domain.children, source: domain) Node { kind: TypeNode { connective: Arrow }, children: [ - Edge { label: Positional, target: rust_nullary_arrow_domain_conj_node() }, + signature.domain, Edge { label: Positional, target: rust_type_atom_node(identity: return_type_binding) @@ -3441,6 +3444,7 @@ fn rust_arrow_with_body_node( label: Positional, target: rust_type_atom_node(identity: return_type_binding) }, + signature.order, Edge { label: core_edge_label(marker: ArrowBodyEdge), target: body } ], occurrence_id: OccurrenceSynthetic diff --git a/src/v2/test/claim/emit/produced_item_parameter_order_test.dag b/src/v2/test/claim/emit/produced_item_parameter_order_test.dag index ac2a0986eb2..65d0d3e2194 100644 --- a/src/v2/test/claim/emit/produced_item_parameter_order_test.dag +++ b/src/v2/test/claim/emit/produced_item_parameter_order_test.dag @@ -6,7 +6,7 @@ import v2.std.arrow_signature { ArrowParameterOrderMalformed, arrow_declared_par import v2.std.compilers.target_model { ProducedDeclSignatureSubject, arrow_domain_binder_names, produced_decl_subject_from_name_and_arrow } import v2.std.diagnostic { Accepted, Rejected, diagnostics_fatal_reason } import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } -import v2.std.node_query { binder_edge } +import v2.std.node_query { binder_edge, declared_field_from_edge } import v2.std.node { Arrow, Atom, @@ -97,20 +97,22 @@ fn ipo_without_order(arrow: Node) -> Node { } } -// Each parameter as its label then its type atom, so the claim reads order AND the binding of each -// label to its own type. +// Each parameter as its label then its declared type atom, so the claim reads order AND the binding +// of each label to its own type. The renderer’s param edges are binders (v2.std.node_query +// binder_edge): the type lives on the binder, not as the edge target’s connective. Reading the +// target as an Atom is the pre-XL-2 shape and would accept a renderer that dropped the type into +// the edge target while refusing the production encoding. fn ipo_param_symbols(params: List) -> List { fold(params, init: [], f: fn(acc, e) { - let name = match e.label { - StructuralLabel { label: _ } => ^ipo_structural - Authored { name: n } => n - Positional => ^ipo_positional - } - let ty = match e.target.kind { - TypeNode { connective: Atom { identity: t } } => t - _ => ^ipo_not_an_atom + match declared_field_from_edge(e: e) { + Present { value: field } => + let ty = match field.type_node.kind { + TypeNode { connective: Atom { identity: t } } => t + _ => ^ipo_not_an_atom + } + concat(acc, [field.name, ty]) + Absent => concat(acc, [^ipo_not_a_binder, ^ipo_not_an_atom]) } - concat(acc, [name, ty]) }) }