From f5f9ff96ad1c3f0233b2896fb856ba50d7cab0f8 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sun, 5 Jul 2026 18:41:32 +0000 Subject: [PATCH 1/6] WIP: Optional-return emission fix (05_emit_rust.dag): T? fn returns emit bare --- src/v1/05_emit_rust.dag | 22 +++++++++++-------- .../src/optional_carrier_signature_test.rs | 22 +++++++++++++++++++ 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/v1/05_emit_rust.dag b/src/v1/05_emit_rust.dag index fd294b0f617..e9dfa469901 100644 --- a/src/v1/05_emit_rust.dag +++ b/src/v1/05_emit_rust.dag @@ -510,10 +510,14 @@ fn render_rust_shared_type_if_needed(type_name: String, rendered: String, shared } else { rendered } } +fn render_rust_shared_type_with_optional(n: Node, type_name: String, rendered: String, shared_types: Set) -> String { + rust_carrier_optional_wrap(n: n, rendered: render_rust_shared_type_if_needed(type_name: type_name, rendered: rendered, shared_types: shared_types)) +} + fn render_rust_applied_type_shared(n: Node, generic_param_names: List, shared_types: Set, corpus_repr: RustCorpusRepr, source_indices: Map, variant_to_enum: Map, env: TypeEnv) -> String { let rendered = render_rust_applied_type(n: n, generic_param_names: generic_param_names, shared_types: shared_types, corpus_repr: corpus_repr, source_indices: source_indices, variant_to_enum: variant_to_enum, env: env) let type_name = authored_name_at(source_indices: source_indices, node: n) - render_rust_shared_type_if_needed(type_name: type_name, rendered: rendered, shared_types: shared_types) + render_rust_shared_type_with_optional(n: n, type_name: type_name, rendered: rendered, shared_types: shared_types) } fn render_rust_decl_type(n: Node, generic_param_names: List, shared_types: Set, corpus_repr: RustCorpusRepr, source_indices: Map, variant_to_enum: Map, env: TypeEnv) -> String { @@ -535,10 +539,10 @@ fn render_rust_decl_type(n: Node, generic_param_names: List, shared_type rust_carrier_optional_wrap(n: n, rendered: render_rust_text_carrier(shared_types: shared_types)) } else if n.connective == NoConnective && n.children |> count == 0 && applied_prop == none && set_contains(shared_types, name) { let rendered = rust_render_type_leaf_name(name: name, variant_to_enum: variant_to_enum) - render_rust_shared_type_if_needed(type_name: name, rendered: rendered, shared_types: shared_types) + render_rust_shared_type_with_optional(n: n, type_name: name, rendered: rendered, shared_types: shared_types) } else if n.connective == NoConnective && n.children |> count > 0 { if !is_container_type(name: name) && rust_fn_sig_peel_closed_alias(env: env, n: n) { - render_rust_shared_type_if_needed(type_name: name, rendered: name, shared_types: shared_types) + render_rust_shared_type_with_optional(n: n, type_name: name, rendered: name, shared_types: shared_types) } else { let base = rust_applied_type_base(name: name, corpus_repr: corpus_repr) let peel = is_parametric_opaque_type_by_name(env: env, type_name: name) @@ -569,7 +573,7 @@ fn render_rust_decl_type(n: Node, generic_param_names: List, shared_type } else { concat(base, "<", arg_list |> join(separator: ", "), ">") } - render_rust_shared_type_if_needed(type_name: name, rendered: applied_ty, shared_types: shared_types) + render_rust_shared_type_with_optional(n: n, type_name: name, rendered: applied_ty, shared_types: shared_types) } } else { render_rust_type_with_applied_binding(n: n, shared_types: shared_types, corpus_repr: corpus_repr, source_indices: source_indices) @@ -622,9 +626,9 @@ fn render_rust_fn_sig_type(n: Node, generic_param_names: List, shared_ty if n.connective == NoConnective && n.children |> count == 0 && name == "String" && corpus_repr_is_faithful(corpus_repr: corpus_repr) { rust_carrier_optional_wrap(n: n, rendered: render_rust_text_carrier(shared_types: shared_types)) } else if n.connective == NoConnective && n.children |> count == 0 && name != "" && name != "String" && !is_container_type(name: name) && rust_fn_sig_peel_closed_alias(env: env, n: n) && rust_fn_sig_preserves_authored_alias_leaf(name: name, corpus_repr: corpus_repr) { - render_rust_shared_type_if_needed(type_name: name, rendered: name, shared_types: shared_types) + render_rust_shared_type_with_optional(n: n, type_name: name, rendered: name, shared_types: shared_types) } else if n.connective == NoConnective && n.children |> count > 0 && !is_container_type(name: name) && rust_fn_sig_peel_closed_alias(env: env, n: n) { - render_rust_shared_type_if_needed(type_name: name, rendered: name, shared_types: shared_types) + render_rust_shared_type_with_optional(n: n, type_name: name, rendered: name, shared_types: shared_types) } else if generic_param_names |> count > 0 { render_rust_decl_type(n: n, generic_param_names: generic_param_names, shared_types: shared_types, corpus_repr: corpus_repr, source_indices: source_indices, variant_to_enum: variant_to_enum, env: env) } else { @@ -638,7 +642,7 @@ fn render_rust_fn_sig_type_applied_binding(n: Node, shared_types: Set, c if applied.children |> count > 0 { let outer_name = authored_name_at(source_indices: source_indices, node: n) if outer_name != "" && n.connective == NoConnective && (n.children |> count) == 0 && rust_fn_sig_peel_closed_alias(env: env, n: n) && rust_fn_sig_preserves_authored_alias_leaf(name: outer_name, corpus_repr: corpus_repr) { - render_rust_shared_type_if_needed(type_name: outer_name, rendered: outer_name, shared_types: shared_types) + render_rust_shared_type_with_optional(n: n, type_name: outer_name, rendered: outer_name, shared_types: shared_types) } else { render_rust_type_with_applied_binding(n: n, shared_types: shared_types, corpus_repr: corpus_repr, source_indices: source_indices) } @@ -3391,9 +3395,9 @@ fn render_rust_type_with_applied_binding(n: Node, shared_types: Set, cor let applied_name = authored_name_at(source_indices: source_indices, node: applied) if outer_name != "" && n.connective == NoConnective && (n.children |> count) == 0 { if outer_name != applied_name { - render_rust_shared_type_if_needed(type_name: outer_name, rendered: outer_name, shared_types: shared_types) + render_rust_shared_type_with_optional(n: n, type_name: outer_name, rendered: outer_name, shared_types: shared_types) } else if set_contains(shared_types, outer_name) { - render_rust_shared_type_if_needed(type_name: outer_name, rendered: outer_name, shared_types: shared_types) + render_rust_shared_type_with_optional(n: n, type_name: outer_name, rendered: outer_name, shared_types: shared_types) } else { render_rust_applied_type_shared(n: applied, generic_param_names: [], shared_types: shared_types, corpus_repr: corpus_repr, source_indices: source_indices, variant_to_enum: empty_map(), env: TypeEnv { bindings: empty_map(), str_bindings: empty_map(), ancestry_str_bindings: empty_map(), parents: [], recursive_types: [], recursive_type_set: empty_map(), inductive_fields: empty_map(), source_indices: source_indices, intern_table: empty_intern_table() }) } diff --git a/src/v1/tests/src/optional_carrier_signature_test.rs b/src/v1/tests/src/optional_carrier_signature_test.rs index 177eab13263..7a918b94321 100644 --- a/src/v1/tests/src/optional_carrier_signature_test.rs +++ b/src/v1/tests/src/optional_carrier_signature_test.rs @@ -60,3 +60,25 @@ fn non_optional_string_return_stays_bare() { "a non-optional `-> String` must NOT be wrapped in Option, got:\n{sig}" ); } + +#[test] +fn optional_shared_type_return_renders_option_rc_signature() { + let source = "module optsig.fixture\n\ntype Node = Product { }\n\nfn maybe_node(flag: Bool) -> Node? {\n if flag { Present { value: Node { } } } else { none }\n}\n"; + let emitted = emit(source); + let sig = return_sig(&emitted, "maybe_node"); + assert!( + sig.contains("Option<") && sig.contains("Rc<"), + "a `-> Node?` return on a shared type must render `Option>`, got:\n{sig}" + ); +} + +#[test] +fn non_optional_shared_type_return_stays_bare_rc() { + let source = "module optsig.fixture\n\ntype Node = Product { }\n\nfn always_node(flag: Bool) -> Node {\n Node { }\n}\n"; + let emitted = emit(source); + let sig = return_sig(&emitted, "always_node"); + assert!( + sig.contains("Rc<") && !sig.contains("Option<"), + "a non-optional `-> Node` must render bare `Rc<..>` without Option, got:\n{sig}" + ); +} From c0332f42ed025090b9754845380662ff1d48de4f Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sun, 5 Jul 2026 18:53:34 +0000 Subject: [PATCH 2/6] WIP: Optional-return emission fix (05_emit_rust.dag): T? fn returns emit bare --- src/v1/stage0/src/v1_compiler_emit_rust.rs | 46 +++++++++++++++++----- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/src/v1/stage0/src/v1_compiler_emit_rust.rs b/src/v1/stage0/src/v1_compiler_emit_rust.rs index 60155a09595..e0389607b1e 100644 --- a/src/v1/stage0/src/v1_compiler_emit_rust.rs +++ b/src/v1/stage0/src/v1_compiler_emit_rust.rs @@ -892,6 +892,18 @@ pub fn render_rust_shared_type_if_needed( } } +pub fn render_rust_shared_type_with_optional( + n: Rc, + type_name: String, + rendered: String, + shared_types: Rc>, +) -> String { + rust_carrier_optional_wrap( + n.clone(), + render_rust_shared_type_if_needed(type_name, rendered, shared_types), + ) +} + pub fn render_rust_applied_type_shared( n: Rc, generic_param_names: Rc>, @@ -912,7 +924,7 @@ pub fn render_rust_applied_type_shared( env, ); let type_name = authored_name_at(source_indices.clone(), n.clone()); - render_rust_shared_type_if_needed(type_name, rendered, shared_types.clone()) + render_rust_shared_type_with_optional(n.clone(), type_name, rendered, shared_types.clone()) } } @@ -992,7 +1004,8 @@ pub fn render_rust_decl_type( name.clone(), variant_to_enum.clone(), ); - render_rust_shared_type_if_needed( + render_rust_shared_type_with_optional( + n.clone(), name.clone(), rendered, shared_types.clone(), @@ -1005,7 +1018,8 @@ pub fn render_rust_decl_type( if (!is_container_type(name.clone()) && rust_fn_sig_peel_closed_alias(env.clone(), n.clone())) { - render_rust_shared_type_if_needed( + render_rust_shared_type_with_optional( + n.clone(), name.clone(), name.clone(), shared_types.clone(), @@ -1135,7 +1149,8 @@ pub fn render_rust_decl_type( } } }; - render_rust_shared_type_if_needed( + render_rust_shared_type_with_optional( + n.clone(), name.clone(), applied_ty, shared_types.clone(), @@ -1249,13 +1264,23 @@ pub fn render_rust_fn_sig_type( && rust_fn_sig_peel_closed_alias(env.clone(), n.clone()) && rust_fn_sig_preserves_authored_alias_leaf(name.clone(), corpus_repr.clone()) { - render_rust_shared_type_if_needed(name.clone(), name.clone(), shared_types.clone()) + render_rust_shared_type_with_optional( + n.clone(), + name.clone(), + name.clone(), + shared_types.clone(), + ) } else if (n.connective.clone() == Connective::NoConnective) && ((n.children.clone().len() as i64) > 0) && !is_container_type(name.clone()) && rust_fn_sig_peel_closed_alias(env.clone(), n.clone()) { - render_rust_shared_type_if_needed(name.clone(), name.clone(), shared_types.clone()) + render_rust_shared_type_with_optional( + n.clone(), + name.clone(), + name.clone(), + shared_types.clone(), + ) } else if ((generic_param_names.clone().len() as i64) > 0) { render_rust_decl_type( n.clone(), @@ -1303,7 +1328,8 @@ pub fn render_rust_fn_sig_type_applied_binding( corpus_repr.clone(), ) { - render_rust_shared_type_if_needed( + render_rust_shared_type_with_optional( + n.clone(), outer_name.clone(), outer_name.clone(), shared_types, @@ -8173,14 +8199,16 @@ pub fn render_rust_type_with_applied_binding( && ((n.children.clone().len() as i64) == 0)) { if (outer_name.clone() != applied_name) { - render_rust_shared_type_if_needed( + render_rust_shared_type_with_optional( + n.clone(), outer_name.clone(), outer_name.clone(), shared_types.clone(), ) } else { if v1_rt::set_contains(&shared_types, outer_name.clone()) { - render_rust_shared_type_if_needed( + render_rust_shared_type_with_optional( + n.clone(), outer_name.clone(), outer_name.clone(), shared_types.clone(), From 2cf3420e9ae0a4de6dc727f4b196f04c408a2851 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sun, 5 Jul 2026 19:00:58 +0000 Subject: [PATCH 3/6] Fix optional shared-type signature tests to use recursive fixtures. Empty Product types are type-constants and skip shared_types Rc wrapping; use a self-referential Node so the witness exercises Option> emission. Co-authored-by: Cursor --- src/v1/tests/src/optional_carrier_signature_test.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/v1/tests/src/optional_carrier_signature_test.rs b/src/v1/tests/src/optional_carrier_signature_test.rs index 7a918b94321..55db36b6cf0 100644 --- a/src/v1/tests/src/optional_carrier_signature_test.rs +++ b/src/v1/tests/src/optional_carrier_signature_test.rs @@ -63,7 +63,8 @@ fn non_optional_string_return_stays_bare() { #[test] fn optional_shared_type_return_renders_option_rc_signature() { - let source = "module optsig.fixture\n\ntype Node = Product { }\n\nfn maybe_node(flag: Bool) -> Node? {\n if flag { Present { value: Node { } } } else { none }\n}\n"; + // Recursive struct so `Node` is in `shared_types` and fn-sig emission applies Rc. + let source = "module optsig.fixture\n\ntype Node = Product { child: Node? }\n\nfn maybe_node(flag: Bool) -> Node? {\n if flag { Present { value: Node { child: none } } } else { none }\n}\n"; let emitted = emit(source); let sig = return_sig(&emitted, "maybe_node"); assert!( @@ -74,7 +75,7 @@ fn optional_shared_type_return_renders_option_rc_signature() { #[test] fn non_optional_shared_type_return_stays_bare_rc() { - let source = "module optsig.fixture\n\ntype Node = Product { }\n\nfn always_node(flag: Bool) -> Node {\n Node { }\n}\n"; + let source = "module optsig.fixture\n\ntype Node = Product { child: Node? }\n\nfn always_node(_flag: Bool) -> Node {\n Node { child: none }\n}\n"; let emitted = emit(source); let sig = return_sig(&emitted, "always_node"); assert!( From cfc3ecf6c7a76705560b135cfd7155d9e917c225 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sun, 5 Jul 2026 19:32:04 +0000 Subject: [PATCH 4/6] ci: re-trigger rust_tests after 15m nextest timeout on cold sccache. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No code change — fmt/clippy/optional_carrier_signature verified green locally. Co-authored-by: Cursor From bf29ebfa7e17862fc3a9e9c0e88bb3328da4fc0c Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sun, 5 Jul 2026 19:38:31 +0000 Subject: [PATCH 5/6] WIP: Optional-return emission fix (05_emit_rust.dag): T? fn returns emit bare --- src/v1/05_emit_rust.dag | 22 +++++------ src/v1/stage0/src/v1_compiler_emit_rust.rs | 46 +++++----------------- 2 files changed, 18 insertions(+), 50 deletions(-) diff --git a/src/v1/05_emit_rust.dag b/src/v1/05_emit_rust.dag index e9dfa469901..fd294b0f617 100644 --- a/src/v1/05_emit_rust.dag +++ b/src/v1/05_emit_rust.dag @@ -510,14 +510,10 @@ fn render_rust_shared_type_if_needed(type_name: String, rendered: String, shared } else { rendered } } -fn render_rust_shared_type_with_optional(n: Node, type_name: String, rendered: String, shared_types: Set) -> String { - rust_carrier_optional_wrap(n: n, rendered: render_rust_shared_type_if_needed(type_name: type_name, rendered: rendered, shared_types: shared_types)) -} - fn render_rust_applied_type_shared(n: Node, generic_param_names: List, shared_types: Set, corpus_repr: RustCorpusRepr, source_indices: Map, variant_to_enum: Map, env: TypeEnv) -> String { let rendered = render_rust_applied_type(n: n, generic_param_names: generic_param_names, shared_types: shared_types, corpus_repr: corpus_repr, source_indices: source_indices, variant_to_enum: variant_to_enum, env: env) let type_name = authored_name_at(source_indices: source_indices, node: n) - render_rust_shared_type_with_optional(n: n, type_name: type_name, rendered: rendered, shared_types: shared_types) + render_rust_shared_type_if_needed(type_name: type_name, rendered: rendered, shared_types: shared_types) } fn render_rust_decl_type(n: Node, generic_param_names: List, shared_types: Set, corpus_repr: RustCorpusRepr, source_indices: Map, variant_to_enum: Map, env: TypeEnv) -> String { @@ -539,10 +535,10 @@ fn render_rust_decl_type(n: Node, generic_param_names: List, shared_type rust_carrier_optional_wrap(n: n, rendered: render_rust_text_carrier(shared_types: shared_types)) } else if n.connective == NoConnective && n.children |> count == 0 && applied_prop == none && set_contains(shared_types, name) { let rendered = rust_render_type_leaf_name(name: name, variant_to_enum: variant_to_enum) - render_rust_shared_type_with_optional(n: n, type_name: name, rendered: rendered, shared_types: shared_types) + render_rust_shared_type_if_needed(type_name: name, rendered: rendered, shared_types: shared_types) } else if n.connective == NoConnective && n.children |> count > 0 { if !is_container_type(name: name) && rust_fn_sig_peel_closed_alias(env: env, n: n) { - render_rust_shared_type_with_optional(n: n, type_name: name, rendered: name, shared_types: shared_types) + render_rust_shared_type_if_needed(type_name: name, rendered: name, shared_types: shared_types) } else { let base = rust_applied_type_base(name: name, corpus_repr: corpus_repr) let peel = is_parametric_opaque_type_by_name(env: env, type_name: name) @@ -573,7 +569,7 @@ fn render_rust_decl_type(n: Node, generic_param_names: List, shared_type } else { concat(base, "<", arg_list |> join(separator: ", "), ">") } - render_rust_shared_type_with_optional(n: n, type_name: name, rendered: applied_ty, shared_types: shared_types) + render_rust_shared_type_if_needed(type_name: name, rendered: applied_ty, shared_types: shared_types) } } else { render_rust_type_with_applied_binding(n: n, shared_types: shared_types, corpus_repr: corpus_repr, source_indices: source_indices) @@ -626,9 +622,9 @@ fn render_rust_fn_sig_type(n: Node, generic_param_names: List, shared_ty if n.connective == NoConnective && n.children |> count == 0 && name == "String" && corpus_repr_is_faithful(corpus_repr: corpus_repr) { rust_carrier_optional_wrap(n: n, rendered: render_rust_text_carrier(shared_types: shared_types)) } else if n.connective == NoConnective && n.children |> count == 0 && name != "" && name != "String" && !is_container_type(name: name) && rust_fn_sig_peel_closed_alias(env: env, n: n) && rust_fn_sig_preserves_authored_alias_leaf(name: name, corpus_repr: corpus_repr) { - render_rust_shared_type_with_optional(n: n, type_name: name, rendered: name, shared_types: shared_types) + render_rust_shared_type_if_needed(type_name: name, rendered: name, shared_types: shared_types) } else if n.connective == NoConnective && n.children |> count > 0 && !is_container_type(name: name) && rust_fn_sig_peel_closed_alias(env: env, n: n) { - render_rust_shared_type_with_optional(n: n, type_name: name, rendered: name, shared_types: shared_types) + render_rust_shared_type_if_needed(type_name: name, rendered: name, shared_types: shared_types) } else if generic_param_names |> count > 0 { render_rust_decl_type(n: n, generic_param_names: generic_param_names, shared_types: shared_types, corpus_repr: corpus_repr, source_indices: source_indices, variant_to_enum: variant_to_enum, env: env) } else { @@ -642,7 +638,7 @@ fn render_rust_fn_sig_type_applied_binding(n: Node, shared_types: Set, c if applied.children |> count > 0 { let outer_name = authored_name_at(source_indices: source_indices, node: n) if outer_name != "" && n.connective == NoConnective && (n.children |> count) == 0 && rust_fn_sig_peel_closed_alias(env: env, n: n) && rust_fn_sig_preserves_authored_alias_leaf(name: outer_name, corpus_repr: corpus_repr) { - render_rust_shared_type_with_optional(n: n, type_name: outer_name, rendered: outer_name, shared_types: shared_types) + render_rust_shared_type_if_needed(type_name: outer_name, rendered: outer_name, shared_types: shared_types) } else { render_rust_type_with_applied_binding(n: n, shared_types: shared_types, corpus_repr: corpus_repr, source_indices: source_indices) } @@ -3395,9 +3391,9 @@ fn render_rust_type_with_applied_binding(n: Node, shared_types: Set, cor let applied_name = authored_name_at(source_indices: source_indices, node: applied) if outer_name != "" && n.connective == NoConnective && (n.children |> count) == 0 { if outer_name != applied_name { - render_rust_shared_type_with_optional(n: n, type_name: outer_name, rendered: outer_name, shared_types: shared_types) + render_rust_shared_type_if_needed(type_name: outer_name, rendered: outer_name, shared_types: shared_types) } else if set_contains(shared_types, outer_name) { - render_rust_shared_type_with_optional(n: n, type_name: outer_name, rendered: outer_name, shared_types: shared_types) + render_rust_shared_type_if_needed(type_name: outer_name, rendered: outer_name, shared_types: shared_types) } else { render_rust_applied_type_shared(n: applied, generic_param_names: [], shared_types: shared_types, corpus_repr: corpus_repr, source_indices: source_indices, variant_to_enum: empty_map(), env: TypeEnv { bindings: empty_map(), str_bindings: empty_map(), ancestry_str_bindings: empty_map(), parents: [], recursive_types: [], recursive_type_set: empty_map(), inductive_fields: empty_map(), source_indices: source_indices, intern_table: empty_intern_table() }) } diff --git a/src/v1/stage0/src/v1_compiler_emit_rust.rs b/src/v1/stage0/src/v1_compiler_emit_rust.rs index e0389607b1e..60155a09595 100644 --- a/src/v1/stage0/src/v1_compiler_emit_rust.rs +++ b/src/v1/stage0/src/v1_compiler_emit_rust.rs @@ -892,18 +892,6 @@ pub fn render_rust_shared_type_if_needed( } } -pub fn render_rust_shared_type_with_optional( - n: Rc, - type_name: String, - rendered: String, - shared_types: Rc>, -) -> String { - rust_carrier_optional_wrap( - n.clone(), - render_rust_shared_type_if_needed(type_name, rendered, shared_types), - ) -} - pub fn render_rust_applied_type_shared( n: Rc, generic_param_names: Rc>, @@ -924,7 +912,7 @@ pub fn render_rust_applied_type_shared( env, ); let type_name = authored_name_at(source_indices.clone(), n.clone()); - render_rust_shared_type_with_optional(n.clone(), type_name, rendered, shared_types.clone()) + render_rust_shared_type_if_needed(type_name, rendered, shared_types.clone()) } } @@ -1004,8 +992,7 @@ pub fn render_rust_decl_type( name.clone(), variant_to_enum.clone(), ); - render_rust_shared_type_with_optional( - n.clone(), + render_rust_shared_type_if_needed( name.clone(), rendered, shared_types.clone(), @@ -1018,8 +1005,7 @@ pub fn render_rust_decl_type( if (!is_container_type(name.clone()) && rust_fn_sig_peel_closed_alias(env.clone(), n.clone())) { - render_rust_shared_type_with_optional( - n.clone(), + render_rust_shared_type_if_needed( name.clone(), name.clone(), shared_types.clone(), @@ -1149,8 +1135,7 @@ pub fn render_rust_decl_type( } } }; - render_rust_shared_type_with_optional( - n.clone(), + render_rust_shared_type_if_needed( name.clone(), applied_ty, shared_types.clone(), @@ -1264,23 +1249,13 @@ pub fn render_rust_fn_sig_type( && rust_fn_sig_peel_closed_alias(env.clone(), n.clone()) && rust_fn_sig_preserves_authored_alias_leaf(name.clone(), corpus_repr.clone()) { - render_rust_shared_type_with_optional( - n.clone(), - name.clone(), - name.clone(), - shared_types.clone(), - ) + render_rust_shared_type_if_needed(name.clone(), name.clone(), shared_types.clone()) } else if (n.connective.clone() == Connective::NoConnective) && ((n.children.clone().len() as i64) > 0) && !is_container_type(name.clone()) && rust_fn_sig_peel_closed_alias(env.clone(), n.clone()) { - render_rust_shared_type_with_optional( - n.clone(), - name.clone(), - name.clone(), - shared_types.clone(), - ) + render_rust_shared_type_if_needed(name.clone(), name.clone(), shared_types.clone()) } else if ((generic_param_names.clone().len() as i64) > 0) { render_rust_decl_type( n.clone(), @@ -1328,8 +1303,7 @@ pub fn render_rust_fn_sig_type_applied_binding( corpus_repr.clone(), ) { - render_rust_shared_type_with_optional( - n.clone(), + render_rust_shared_type_if_needed( outer_name.clone(), outer_name.clone(), shared_types, @@ -8199,16 +8173,14 @@ pub fn render_rust_type_with_applied_binding( && ((n.children.clone().len() as i64) == 0)) { if (outer_name.clone() != applied_name) { - render_rust_shared_type_with_optional( - n.clone(), + render_rust_shared_type_if_needed( outer_name.clone(), outer_name.clone(), shared_types.clone(), ) } else { if v1_rt::set_contains(&shared_types, outer_name.clone()) { - render_rust_shared_type_with_optional( - n.clone(), + render_rust_shared_type_if_needed( outer_name.clone(), outer_name.clone(), shared_types.clone(), From 8634ad953311426c8d1d42510abb532103da7144 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sun, 5 Jul 2026 19:50:30 +0000 Subject: [PATCH 6/6] WIP: Optional-return emission fix (05_emit_rust.dag): T? fn returns emit bare --- src/v1/05_emit_rust.dag | 22 ++++++----- src/v1/stage0/src/v1_compiler_emit_rust.rs | 46 +++++++++++++++++----- 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/v1/05_emit_rust.dag b/src/v1/05_emit_rust.dag index fd294b0f617..e9dfa469901 100644 --- a/src/v1/05_emit_rust.dag +++ b/src/v1/05_emit_rust.dag @@ -510,10 +510,14 @@ fn render_rust_shared_type_if_needed(type_name: String, rendered: String, shared } else { rendered } } +fn render_rust_shared_type_with_optional(n: Node, type_name: String, rendered: String, shared_types: Set) -> String { + rust_carrier_optional_wrap(n: n, rendered: render_rust_shared_type_if_needed(type_name: type_name, rendered: rendered, shared_types: shared_types)) +} + fn render_rust_applied_type_shared(n: Node, generic_param_names: List, shared_types: Set, corpus_repr: RustCorpusRepr, source_indices: Map, variant_to_enum: Map, env: TypeEnv) -> String { let rendered = render_rust_applied_type(n: n, generic_param_names: generic_param_names, shared_types: shared_types, corpus_repr: corpus_repr, source_indices: source_indices, variant_to_enum: variant_to_enum, env: env) let type_name = authored_name_at(source_indices: source_indices, node: n) - render_rust_shared_type_if_needed(type_name: type_name, rendered: rendered, shared_types: shared_types) + render_rust_shared_type_with_optional(n: n, type_name: type_name, rendered: rendered, shared_types: shared_types) } fn render_rust_decl_type(n: Node, generic_param_names: List, shared_types: Set, corpus_repr: RustCorpusRepr, source_indices: Map, variant_to_enum: Map, env: TypeEnv) -> String { @@ -535,10 +539,10 @@ fn render_rust_decl_type(n: Node, generic_param_names: List, shared_type rust_carrier_optional_wrap(n: n, rendered: render_rust_text_carrier(shared_types: shared_types)) } else if n.connective == NoConnective && n.children |> count == 0 && applied_prop == none && set_contains(shared_types, name) { let rendered = rust_render_type_leaf_name(name: name, variant_to_enum: variant_to_enum) - render_rust_shared_type_if_needed(type_name: name, rendered: rendered, shared_types: shared_types) + render_rust_shared_type_with_optional(n: n, type_name: name, rendered: rendered, shared_types: shared_types) } else if n.connective == NoConnective && n.children |> count > 0 { if !is_container_type(name: name) && rust_fn_sig_peel_closed_alias(env: env, n: n) { - render_rust_shared_type_if_needed(type_name: name, rendered: name, shared_types: shared_types) + render_rust_shared_type_with_optional(n: n, type_name: name, rendered: name, shared_types: shared_types) } else { let base = rust_applied_type_base(name: name, corpus_repr: corpus_repr) let peel = is_parametric_opaque_type_by_name(env: env, type_name: name) @@ -569,7 +573,7 @@ fn render_rust_decl_type(n: Node, generic_param_names: List, shared_type } else { concat(base, "<", arg_list |> join(separator: ", "), ">") } - render_rust_shared_type_if_needed(type_name: name, rendered: applied_ty, shared_types: shared_types) + render_rust_shared_type_with_optional(n: n, type_name: name, rendered: applied_ty, shared_types: shared_types) } } else { render_rust_type_with_applied_binding(n: n, shared_types: shared_types, corpus_repr: corpus_repr, source_indices: source_indices) @@ -622,9 +626,9 @@ fn render_rust_fn_sig_type(n: Node, generic_param_names: List, shared_ty if n.connective == NoConnective && n.children |> count == 0 && name == "String" && corpus_repr_is_faithful(corpus_repr: corpus_repr) { rust_carrier_optional_wrap(n: n, rendered: render_rust_text_carrier(shared_types: shared_types)) } else if n.connective == NoConnective && n.children |> count == 0 && name != "" && name != "String" && !is_container_type(name: name) && rust_fn_sig_peel_closed_alias(env: env, n: n) && rust_fn_sig_preserves_authored_alias_leaf(name: name, corpus_repr: corpus_repr) { - render_rust_shared_type_if_needed(type_name: name, rendered: name, shared_types: shared_types) + render_rust_shared_type_with_optional(n: n, type_name: name, rendered: name, shared_types: shared_types) } else if n.connective == NoConnective && n.children |> count > 0 && !is_container_type(name: name) && rust_fn_sig_peel_closed_alias(env: env, n: n) { - render_rust_shared_type_if_needed(type_name: name, rendered: name, shared_types: shared_types) + render_rust_shared_type_with_optional(n: n, type_name: name, rendered: name, shared_types: shared_types) } else if generic_param_names |> count > 0 { render_rust_decl_type(n: n, generic_param_names: generic_param_names, shared_types: shared_types, corpus_repr: corpus_repr, source_indices: source_indices, variant_to_enum: variant_to_enum, env: env) } else { @@ -638,7 +642,7 @@ fn render_rust_fn_sig_type_applied_binding(n: Node, shared_types: Set, c if applied.children |> count > 0 { let outer_name = authored_name_at(source_indices: source_indices, node: n) if outer_name != "" && n.connective == NoConnective && (n.children |> count) == 0 && rust_fn_sig_peel_closed_alias(env: env, n: n) && rust_fn_sig_preserves_authored_alias_leaf(name: outer_name, corpus_repr: corpus_repr) { - render_rust_shared_type_if_needed(type_name: outer_name, rendered: outer_name, shared_types: shared_types) + render_rust_shared_type_with_optional(n: n, type_name: outer_name, rendered: outer_name, shared_types: shared_types) } else { render_rust_type_with_applied_binding(n: n, shared_types: shared_types, corpus_repr: corpus_repr, source_indices: source_indices) } @@ -3391,9 +3395,9 @@ fn render_rust_type_with_applied_binding(n: Node, shared_types: Set, cor let applied_name = authored_name_at(source_indices: source_indices, node: applied) if outer_name != "" && n.connective == NoConnective && (n.children |> count) == 0 { if outer_name != applied_name { - render_rust_shared_type_if_needed(type_name: outer_name, rendered: outer_name, shared_types: shared_types) + render_rust_shared_type_with_optional(n: n, type_name: outer_name, rendered: outer_name, shared_types: shared_types) } else if set_contains(shared_types, outer_name) { - render_rust_shared_type_if_needed(type_name: outer_name, rendered: outer_name, shared_types: shared_types) + render_rust_shared_type_with_optional(n: n, type_name: outer_name, rendered: outer_name, shared_types: shared_types) } else { render_rust_applied_type_shared(n: applied, generic_param_names: [], shared_types: shared_types, corpus_repr: corpus_repr, source_indices: source_indices, variant_to_enum: empty_map(), env: TypeEnv { bindings: empty_map(), str_bindings: empty_map(), ancestry_str_bindings: empty_map(), parents: [], recursive_types: [], recursive_type_set: empty_map(), inductive_fields: empty_map(), source_indices: source_indices, intern_table: empty_intern_table() }) } diff --git a/src/v1/stage0/src/v1_compiler_emit_rust.rs b/src/v1/stage0/src/v1_compiler_emit_rust.rs index 60155a09595..e0389607b1e 100644 --- a/src/v1/stage0/src/v1_compiler_emit_rust.rs +++ b/src/v1/stage0/src/v1_compiler_emit_rust.rs @@ -892,6 +892,18 @@ pub fn render_rust_shared_type_if_needed( } } +pub fn render_rust_shared_type_with_optional( + n: Rc, + type_name: String, + rendered: String, + shared_types: Rc>, +) -> String { + rust_carrier_optional_wrap( + n.clone(), + render_rust_shared_type_if_needed(type_name, rendered, shared_types), + ) +} + pub fn render_rust_applied_type_shared( n: Rc, generic_param_names: Rc>, @@ -912,7 +924,7 @@ pub fn render_rust_applied_type_shared( env, ); let type_name = authored_name_at(source_indices.clone(), n.clone()); - render_rust_shared_type_if_needed(type_name, rendered, shared_types.clone()) + render_rust_shared_type_with_optional(n.clone(), type_name, rendered, shared_types.clone()) } } @@ -992,7 +1004,8 @@ pub fn render_rust_decl_type( name.clone(), variant_to_enum.clone(), ); - render_rust_shared_type_if_needed( + render_rust_shared_type_with_optional( + n.clone(), name.clone(), rendered, shared_types.clone(), @@ -1005,7 +1018,8 @@ pub fn render_rust_decl_type( if (!is_container_type(name.clone()) && rust_fn_sig_peel_closed_alias(env.clone(), n.clone())) { - render_rust_shared_type_if_needed( + render_rust_shared_type_with_optional( + n.clone(), name.clone(), name.clone(), shared_types.clone(), @@ -1135,7 +1149,8 @@ pub fn render_rust_decl_type( } } }; - render_rust_shared_type_if_needed( + render_rust_shared_type_with_optional( + n.clone(), name.clone(), applied_ty, shared_types.clone(), @@ -1249,13 +1264,23 @@ pub fn render_rust_fn_sig_type( && rust_fn_sig_peel_closed_alias(env.clone(), n.clone()) && rust_fn_sig_preserves_authored_alias_leaf(name.clone(), corpus_repr.clone()) { - render_rust_shared_type_if_needed(name.clone(), name.clone(), shared_types.clone()) + render_rust_shared_type_with_optional( + n.clone(), + name.clone(), + name.clone(), + shared_types.clone(), + ) } else if (n.connective.clone() == Connective::NoConnective) && ((n.children.clone().len() as i64) > 0) && !is_container_type(name.clone()) && rust_fn_sig_peel_closed_alias(env.clone(), n.clone()) { - render_rust_shared_type_if_needed(name.clone(), name.clone(), shared_types.clone()) + render_rust_shared_type_with_optional( + n.clone(), + name.clone(), + name.clone(), + shared_types.clone(), + ) } else if ((generic_param_names.clone().len() as i64) > 0) { render_rust_decl_type( n.clone(), @@ -1303,7 +1328,8 @@ pub fn render_rust_fn_sig_type_applied_binding( corpus_repr.clone(), ) { - render_rust_shared_type_if_needed( + render_rust_shared_type_with_optional( + n.clone(), outer_name.clone(), outer_name.clone(), shared_types, @@ -8173,14 +8199,16 @@ pub fn render_rust_type_with_applied_binding( && ((n.children.clone().len() as i64) == 0)) { if (outer_name.clone() != applied_name) { - render_rust_shared_type_if_needed( + render_rust_shared_type_with_optional( + n.clone(), outer_name.clone(), outer_name.clone(), shared_types.clone(), ) } else { if v1_rt::set_contains(&shared_types, outer_name.clone()) { - render_rust_shared_type_if_needed( + render_rust_shared_type_with_optional( + n.clone(), outer_name.clone(), outer_name.clone(), shared_types.clone(),