From a126257de83436ea5019de3565be546835b217a3 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Jul 2026 02:02:39 +0000 Subject: [PATCH 1/7] WIP: Type-ref roots 1-3: clear the six-module shared histogram (post-7097) --- src/v1/05_emit_rust.dag | 56 ++++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/src/v1/05_emit_rust.dag b/src/v1/05_emit_rust.dag index a835c1912eb..fe61b635e85 100644 --- a/src/v1/05_emit_rust.dag +++ b/src/v1/05_emit_rust.dag @@ -1984,22 +1984,57 @@ fn build_module_export_sets(modules: List) -> Map) -> String { + match n.inferred { + Present { value: Resolved { node: rt } } => + let is_optional = rt.return_cardinality == CardOptional + if is_optional { + authored_name_at(source_indices: source_indices, node: with_required_cardinality(n: rt)) + } else { authored_name_at(source_indices: source_indices, node: rt) } + _ => "" + } +} + fn record_lit_ref_names(n: Node, source_indices: Map) -> List { match n.expr_data { ExprRecordLit { parent_enum: pe } => let tn_list = match record_lit_type_name_at(texpr: n, source_indices: source_indices) { Present { value: t } => if t != "" { [t] } else { [] } - Absent => [] + Absent => + let inferred = emit_inferred_type_leaf_name(n: n, source_indices: source_indices) + if inferred != "" { [inferred] } else { [] } } let pe_list = match pe { Present { value: p } => if p != "" { [p] } else { [] } Absent => [] } - concat(tn_list, pe_list) + unique_strings(items: concat(tn_list, pe_list)) _ => [] } } +fn collect_items_field_import_surface_names(items: List, type_summaries: Map, variant_to_enum: Map, source_indices: Map) -> List { + items |> flat_map(item => + collect_item_emit_surface_names(item: item, source_indices: source_indices, variant_to_enum: variant_to_enum, type_summaries: type_summaries) + |> flat_map(type_name => + match map_get(type_summaries, type_name) { + Present { value: summary } => + summary.field_import_surface_names |> filter(field_type => + field_type != "" && match map_get(type_summaries, field_type) { + Present { value: ft } => + match ft.repr { + StructRepr => true + _ => false + } + Absent => false + } + ) + Absent => [] + } + ) + ) |> unique_strings +} + fn collect_value_ref_names(n: Node, source_indices: Map) -> List { let self_name = match n.expr_data { ExprVar { binding_kind: bk } => @@ -2052,14 +2087,7 @@ fn collect_item_type_surface_names(item: Node, source_indices: Map) -> String { - match scrutinee.inferred { - Present { value: Resolved { node: rt } } => - let is_optional = rt.return_cardinality == CardOptional - if is_optional { - authored_name_at(source_indices: source_indices, node: with_required_cardinality(n: rt)) - } else { authored_name_at(source_indices: source_indices, node: rt) } - _ => "" - } + emit_inferred_type_leaf_name(n: scrutinee, source_indices: source_indices) } fn collect_match_pattern_parent_enums(expr: Node, source_indices: Map, variant_to_enum: Map, type_summaries: Map) -> List { @@ -2084,11 +2112,14 @@ fn collect_value_emit_type_surface_names(n: Node, source_indices: Map record_lit_ref_names(n: n, source_indices: source_indices) ExprMatch => collect_match_pattern_parent_enums(expr: n, source_indices: source_indices, variant_to_enum: variant_to_enum, type_summaries: type_summaries) _ => + let from_inferred = emit_inferred_type_leaf_name(n: n, source_indices: source_indices) + let from_inferred_list = if from_inferred != "" { [from_inferred] } else { [] } let nm = authored_name_at(source_indices: source_indices, node: n) - match map_get(variant_to_enum, nm) { + let from_variant = match map_get(variant_to_enum, nm) { Present { value: parent } => if parent != "" { [parent] } else { [] } Absent => [] } + unique_strings(items: concat(from_inferred_list, from_variant)) } let child_names = concat( concat( @@ -2142,7 +2173,8 @@ fn reference_derived_use_lines(items: List, unlisted_type_names: List flat_map(item => collect_value_ref_names(n: item, source_indices: source_indices))) let type_surface_names = unique_strings(items: items |> flat_map(item => collect_item_emit_surface_names(item: item, source_indices: source_indices, variant_to_enum: emit_info.variant_to_enum, type_summaries: emit_info.type_summaries))) - let candidates = unique_strings(items: concat(concat(unlisted_type_names, value_names), type_surface_names)) + let field_surface_names = collect_items_field_import_surface_names(items: items, type_summaries: emit_info.type_summaries, variant_to_enum: emit_info.variant_to_enum, source_indices: source_indices) + let candidates = unique_strings(items: concat(concat(concat(unlisted_type_names, value_names), type_surface_names), field_surface_names)) let local_decl_names = items |> flat_map(item => let nm = authored_name_at(source_indices: source_indices, node: item) if nm == "" { [] } else { [nm] } From 91b81f5304d647be5ca4fb2f0e22caf900dd0836 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Jul 2026 02:31:08 +0000 Subject: [PATCH 2/7] WIP: Type-ref roots 1-3: clear the six-module shared histogram (post-7097) --- src/v1/stage0/src/v1_compiler_emit_rust.rs | 135 ++++++++++++++++++--- 1 file changed, 115 insertions(+), 20 deletions(-) diff --git a/src/v1/stage0/src/v1_compiler_emit_rust.rs b/src/v1/stage0/src/v1_compiler_emit_rust.rs index 731aac25a3f..93b1e0e7733 100644 --- a/src/v1/stage0/src/v1_compiler_emit_rust.rs +++ b/src/v1/stage0/src/v1_compiler_emit_rust.rs @@ -4517,6 +4517,26 @@ pub fn build_module_export_sets( ) } +pub fn emit_inferred_type_leaf_name( + n: Rc, + source_indices: Rc>>, +) -> String { + match n.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { node: rt, .. }) => { + let is_optional = (rt.return_cardinality.clone() == Cardinality::CardOptional); + if is_optional.clone() { + authored_name_at( + source_indices.clone(), + with_required_cardinality(rt.clone()), + ) + } else { + authored_name_at(source_indices.clone(), rt.clone()) + } + } + _ => "".to_string(), + } +} + pub fn record_lit_ref_names( n: Rc, source_indices: Rc>>, @@ -4533,7 +4553,14 @@ pub fn record_lit_ref_names( Rc::new(vec![]) } } - None => Rc::new(vec![]), + None => { + let inferred = emit_inferred_type_leaf_name(n.clone(), source_indices.clone()); + if (inferred.clone() != "".to_string()) { + Rc::new(vec![inferred.clone()]) + } else { + Rc::new(vec![]) + } + } }; let pe_list = match pe.clone() { Some(p) => { @@ -4545,12 +4572,74 @@ pub fn record_lit_ref_names( } None => Rc::new(vec![]), }; - v1_rt::concat(tn_list.clone(), pe_list.clone()) + unique_strings(v1_rt::concat(tn_list.clone(), pe_list.clone())) } _ => Rc::new(vec![]), } } +pub fn collect_items_field_import_surface_names( + items: Rc>>, + type_summaries: Rc>>, + variant_to_enum: Rc>, + source_indices: Rc>>, +) -> Rc> { + Rc::new({ + let mut __result = Vec::new(); + for item in items.clone().iter().cloned() { + __result.extend( + (*Rc::new({ + let mut __result = Vec::new(); + for type_name in collect_item_emit_surface_names( + item.clone(), + source_indices.clone(), + variant_to_enum.clone(), + type_summaries.clone(), + ) + .iter() + .cloned() + { + __result.extend( + (*match v1_rt::map_get(&type_summaries, type_name.clone()) { + Some(summary) => Rc::new({ + let mut __result = Vec::new(); + for field_type in + summary.field_import_surface_names.clone().iter().cloned() + { + if ((field_type.clone() != "".to_string()) + && match v1_rt::map_get( + &type_summaries, + field_type.clone(), + ) { + Some(ft) => match (*ft.repr.clone()).clone() { + TypeRepr::StructRepr => true, + _ => false, + }, + None => false, + }) + { + __result.push(field_type); + } + } + __result + }), + None => Rc::new(vec![]), + }) + .iter() + .cloned(), + ); + } + __result + })) + .iter() + .cloned(), + ); + } + __result + }) + .unique_strings() +} + pub fn collect_value_ref_names( n: Rc, source_indices: Rc>>, @@ -4696,20 +4785,7 @@ pub fn emit_scrutinee_type_name( scrutinee: Rc, source_indices: Rc>>, ) -> String { - match scrutinee.inferred.clone().as_deref().cloned() { - Some(InferredNode::Resolved { node: rt, .. }) => { - let is_optional = (rt.return_cardinality.clone() == Cardinality::CardOptional); - if is_optional.clone() { - authored_name_at( - source_indices.clone(), - with_required_cardinality(rt.clone()), - ) - } else { - authored_name_at(source_indices.clone(), rt.clone()) - } - } - _ => "".to_string(), - } + emit_inferred_type_leaf_name(scrutinee.clone(), source_indices.clone()) } pub fn collect_match_pattern_parent_enums( @@ -4775,8 +4851,14 @@ pub fn collect_value_emit_type_surface_names( type_summaries.clone(), ), _ => { + let from_inferred = emit_inferred_type_leaf_name(n.clone(), source_indices.clone()); + let from_inferred_list = if (from_inferred.clone() != "".to_string()) { + Rc::new(vec![from_inferred.clone()]) + } else { + Rc::new(vec![]) + }; let nm = authored_name_at(source_indices.clone(), n.clone()); - match v1_rt::map_get(&variant_to_enum, nm.clone()) { + let from_variant = match v1_rt::map_get(&variant_to_enum, nm.clone()) { Some(parent) => { if (parent.clone() != "".to_string()) { Rc::new(vec![parent.clone()]) @@ -4785,7 +4867,11 @@ pub fn collect_value_emit_type_surface_names( } } None => Rc::new(vec![]), - } + }; + unique_strings(v1_rt::concat( + from_inferred_list.clone(), + from_variant.clone(), + )) } }; let child_names = v1_rt::concat( @@ -5044,9 +5130,18 @@ pub fn reference_derived_use_lines( } __result })); + let field_surface_names = collect_items_field_import_surface_names( + items.clone(), + emit_info.type_summaries.clone(), + emit_info.variant_to_enum.clone(), + source_indices.clone(), + ); let candidates = unique_strings(v1_rt::concat( - v1_rt::concat(unlisted_type_names.clone(), value_names.clone()), - type_surface_names.clone(), + v1_rt::concat( + v1_rt::concat(unlisted_type_names.clone(), value_names.clone()), + type_surface_names.clone(), + ), + field_surface_names.clone(), )); let local_decl_names = Rc::new({ let mut __result = Vec::new(); From 7193971779d441bb338a5c08b1d8d3a60a824bbd Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Jul 2026 02:40:43 +0000 Subject: [PATCH 3/7] fix: unique_strings pipeline emit in field-import harvest `|> unique_strings` lowered to a method call on Rc> (E0599). Use unique_strings(items: ...) form; regen stage0 output included. Co-authored-by: Cursor --- src/v1/05_emit_rust.dag | 4 ++-- src/v1/stage0/src/v1_compiler_emit_rust.rs | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/v1/05_emit_rust.dag b/src/v1/05_emit_rust.dag index fe61b635e85..5e742e0e9e6 100644 --- a/src/v1/05_emit_rust.dag +++ b/src/v1/05_emit_rust.dag @@ -2014,7 +2014,7 @@ fn record_lit_ref_names(n: Node, source_indices: Map) -> L } fn collect_items_field_import_surface_names(items: List, type_summaries: Map, variant_to_enum: Map, source_indices: Map) -> List { - items |> flat_map(item => + unique_strings(items: items |> flat_map(item => collect_item_emit_surface_names(item: item, source_indices: source_indices, variant_to_enum: variant_to_enum, type_summaries: type_summaries) |> flat_map(type_name => match map_get(type_summaries, type_name) { @@ -2032,7 +2032,7 @@ fn collect_items_field_import_surface_names(items: List, type_summaries: M Absent => [] } ) - ) |> unique_strings + )) } fn collect_value_ref_names(n: Node, source_indices: Map) -> List { diff --git a/src/v1/stage0/src/v1_compiler_emit_rust.rs b/src/v1/stage0/src/v1_compiler_emit_rust.rs index 93b1e0e7733..e7eadca47d9 100644 --- a/src/v1/stage0/src/v1_compiler_emit_rust.rs +++ b/src/v1/stage0/src/v1_compiler_emit_rust.rs @@ -4584,7 +4584,7 @@ pub fn collect_items_field_import_surface_names( variant_to_enum: Rc>, source_indices: Rc>>, ) -> Rc> { - Rc::new({ + unique_strings(Rc::new({ let mut __result = Vec::new(); for item in items.clone().iter().cloned() { __result.extend( @@ -4636,8 +4636,7 @@ pub fn collect_items_field_import_surface_names( ); } __result - }) - .unique_strings() + })) } pub fn collect_value_ref_names( From 79a317e191de052bf9be450ceb1ed63f74917e91 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Jul 2026 04:17:42 +0000 Subject: [PATCH 4/7] WIP: Type-ref roots 1-3: clear the six-module shared histogram (post-7097) --- src/v1/05_emit_rust.dag | 53 ++++++-- src/v1/stage0/src/v1_compiler_emit_rust.rs | 144 ++++++++++++++++++--- 2 files changed, 163 insertions(+), 34 deletions(-) diff --git a/src/v1/05_emit_rust.dag b/src/v1/05_emit_rust.dag index 6d433a677cd..278f0c0623e 100644 --- a/src/v1/05_emit_rust.dag +++ b/src/v1/05_emit_rust.dag @@ -2035,14 +2035,41 @@ fn emit_inferred_type_leaf_name(n: Node, source_indices: Map) -> List { +fn anonymous_record_lit_surface_name(n: Node, source_indices: Map, type_summaries: Map) -> String { + let lit_field_names = n.children |> map(f => field_init_node_name_at(n: f, source_indices: source_indices)) + let field_type_hints = fold(n.children, init: empty_map(), f: (acc, f) => + let fname = field_init_node_name_at(n: f, source_indices: source_indices) + let fval = field_init_node_value(n: f) + match fval.inferred { + Present { value: Resolved { node: type_node } } => + map_insert(acc, fname, authored_name_at(source_indices: source_indices, node: type_node)) + _ => acc + } + ) + match find_struct_name_by_fields(field_names: lit_field_names, field_type_hints: field_type_hints, type_summaries: type_summaries) { + Present { value: sn } => sn + Absent => + match find_unique_struct_name_by_fields(field_names: lit_field_names, type_summaries: type_summaries) { + Present { value: sn } => sn + Absent => + let rt = resolved_type(n: n) + let rt_name = authored_name_at(source_indices: source_indices, node: rt) + if rt.ident_span != none && map_contains_key(type_summaries, rt_name) { rt_name } else { "" } + } + } +} + +fn record_lit_ref_names(n: Node, source_indices: Map, type_summaries: Map) -> List { match n.expr_data { ExprRecordLit { parent_enum: pe } => let tn_list = match record_lit_type_name_at(texpr: n, source_indices: source_indices) { Present { value: t } => if t != "" { [t] } else { [] } Absent => let inferred = emit_inferred_type_leaf_name(n: n, source_indices: source_indices) - if inferred != "" { [inferred] } else { [] } + if inferred != "" { [inferred] } else { + let anon = anonymous_record_lit_surface_name(n: n, source_indices: source_indices, type_summaries: type_summaries) + if anon != "" { [anon] } else { [] } + } } let pe_list = match pe { Present { value: p } => if p != "" { [p] } else { [] } @@ -2075,7 +2102,7 @@ fn collect_items_field_import_surface_names(items: List, type_summaries: M )) } -fn collect_value_ref_names(n: Node, source_indices: Map) -> List { +fn collect_value_ref_names(n: Node, source_indices: Map, type_summaries: Map) -> List { let self_name = match n.expr_data { ExprVar { binding_kind: bk } => match bk { @@ -2088,24 +2115,24 @@ fn collect_value_ref_names(n: Node, source_indices: Map) - let nm = authored_name_at(source_indices: source_indices, node: n) if nm != "" { [nm] } else { [] } ExprRecordLit { parent_enum: _ } => - record_lit_ref_names(n: n, source_indices: source_indices) + record_lit_ref_names(n: n, source_indices: source_indices, type_summaries: type_summaries) _ => [] } let list_fields = concat( concat( - n.children |> flat_map(c => collect_value_ref_names(n: c, source_indices: source_indices)), - n.params |> flat_map(c => collect_value_ref_names(n: c, source_indices: source_indices)) + n.children |> flat_map(c => collect_value_ref_names(n: c, source_indices: source_indices, type_summaries: type_summaries)), + n.params |> flat_map(c => collect_value_ref_names(n: c, source_indices: source_indices, type_summaries: type_summaries)) ), concat( - n.uses |> flat_map(c => collect_value_ref_names(n: c, source_indices: source_indices)), - n.properties |> flat_map(c => collect_value_ref_names(n: c, source_indices: source_indices)) + n.uses |> flat_map(c => collect_value_ref_names(n: c, source_indices: source_indices, type_summaries: type_summaries)), + n.properties |> flat_map(c => collect_value_ref_names(n: c, source_indices: source_indices, type_summaries: type_summaries)) ) ) let opt_fields = concat( - match n.body { Present { value: b } => collect_value_ref_names(n: b, source_indices: source_indices) Absent => [] }, + match n.body { Present { value: b } => collect_value_ref_names(n: b, source_indices: source_indices, type_summaries: type_summaries) Absent => [] }, concat( - match n.transport { Present { value: t } => collect_value_ref_names(n: t, source_indices: source_indices) Absent => [] }, - match n.type_annotation { Present { value: t } => collect_value_ref_names(n: t, source_indices: source_indices) Absent => [] } + match n.transport { Present { value: t } => collect_value_ref_names(n: t, source_indices: source_indices, type_summaries: type_summaries) Absent => [] }, + match n.type_annotation { Present { value: t } => collect_value_ref_names(n: t, source_indices: source_indices, type_summaries: type_summaries) Absent => [] } ) ) concat(self_name, concat(list_fields, opt_fields)) @@ -2149,7 +2176,7 @@ fn collect_match_pattern_parent_enums(expr: Node, source_indices: Map, variant_to_enum: Map, type_summaries: Map) -> List { let self_names = match n.expr_data { - ExprRecordLit { parent_enum: _ } => record_lit_ref_names(n: n, source_indices: source_indices) + ExprRecordLit { parent_enum: _ } => record_lit_ref_names(n: n, source_indices: source_indices, type_summaries: type_summaries) ExprMatch => collect_match_pattern_parent_enums(expr: n, source_indices: source_indices, variant_to_enum: variant_to_enum, type_summaries: type_summaries) _ => let from_inferred = emit_inferred_type_leaf_name(n: n, source_indices: source_indices) @@ -2211,7 +2238,7 @@ data reference_derived_use_lines_note: String = "emit_import_closure_root (§5). fn reference_derived_use_lines(items: List, unlisted_type_names: List, this_module_name: String, registry: Map, emit_info: EmitGraphInfo, local_type_names: List, already_imported_names: List, export_sets: Map>, typed_modules: List, source_indices: Map, module_index: ModuleIndex) -> List { { - let value_names = unique_strings(items: items |> flat_map(item => collect_value_ref_names(n: item, source_indices: source_indices))) + let value_names = unique_strings(items: items |> flat_map(item => collect_value_ref_names(n: item, source_indices: source_indices, type_summaries: emit_info.type_summaries))) let type_surface_names = unique_strings(items: items |> flat_map(item => collect_item_emit_surface_names(item: item, source_indices: source_indices, variant_to_enum: emit_info.variant_to_enum, type_summaries: emit_info.type_summaries))) let field_surface_names = collect_items_field_import_surface_names(items: items, type_summaries: emit_info.type_summaries, variant_to_enum: emit_info.variant_to_enum, source_indices: source_indices) let candidates = unique_strings(items: concat(concat(concat(unlisted_type_names, value_names), type_surface_names), field_surface_names)) diff --git a/src/v1/stage0/src/v1_compiler_emit_rust.rs b/src/v1/stage0/src/v1_compiler_emit_rust.rs index 60648f55925..903934ba3fd 100644 --- a/src/v1/stage0/src/v1_compiler_emit_rust.rs +++ b/src/v1/stage0/src/v1_compiler_emit_rust.rs @@ -4655,9 +4655,67 @@ pub fn emit_inferred_type_leaf_name( } } +pub fn anonymous_record_lit_surface_name( + n: Rc, + source_indices: Rc>>, + type_summaries: Rc>>, +) -> String { + { + let lit_field_names = Rc::new({ + let mut __result = Vec::new(); + for f in n.children.clone().iter().cloned() { + __result.push(field_init_node_name_at(f.clone(), source_indices.clone())); + } + __result + }); + let field_type_hints = n.children.clone().iter().cloned().fold( + v1_rt::rc_empty_map::(), + |acc: Rc>, f: Rc| { + let fname = field_init_node_name_at(f.clone(), source_indices.clone()); + let fval = field_init_node_value(f.clone()); + match fval.inferred.clone().as_deref().cloned() { + Some(InferredNode::Resolved { + node: type_node, .. + }) => v1_rt::rc_map_insert( + acc.clone(), + fname.clone(), + authored_name_at(source_indices.clone(), type_node.clone()), + ), + _ => acc.clone(), + } + }, + ); + match find_struct_name_by_fields( + lit_field_names.clone(), + field_type_hints.clone(), + type_summaries.clone(), + ) { + Some(sn) => sn.clone(), + None => match find_unique_struct_name_by_fields( + lit_field_names.clone(), + type_summaries.clone(), + ) { + Some(sn) => sn.clone(), + None => { + let rt = resolved_type(n.clone()); + let rt_name = authored_name_at(source_indices.clone(), rt.clone()); + if ((rt.ident_span.clone() != None) + && v1_rt::map_contains_key(&type_summaries, rt_name.clone())) + { + rt_name.clone() + } else { + "".to_string() + } + } + }, + } + } +} + pub fn record_lit_ref_names( n: Rc, source_indices: Rc>>, + type_summaries: Rc>>, ) -> Rc> { match (*n.expr_data.clone()).clone() { ExprData::ExprRecordLit { @@ -4676,7 +4734,18 @@ pub fn record_lit_ref_names( if (inferred.clone() != "".to_string()) { Rc::new(vec![inferred.clone()]) } else { - Rc::new(vec![]) + { + let anon = anonymous_record_lit_surface_name( + n.clone(), + source_indices.clone(), + type_summaries.clone(), + ); + if (anon.clone() != "".to_string()) { + Rc::new(vec![anon.clone()]) + } else { + Rc::new(vec![]) + } + } } } }; @@ -4760,6 +4829,7 @@ pub fn collect_items_field_import_surface_names( pub fn collect_value_ref_names( n: Rc, source_indices: Rc>>, + type_summaries: Rc>>, ) -> Rc> { stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { let self_name = match (*n.expr_data.clone()).clone() { @@ -4785,7 +4855,7 @@ pub fn collect_value_ref_names( } } ExprData::ExprRecordLit { parent_enum: _, .. } => { - record_lit_ref_names(n.clone(), source_indices.clone()) + record_lit_ref_names(n.clone(), source_indices.clone(), type_summaries.clone()) } _ => Rc::new(vec![]), }; @@ -4795,9 +4865,13 @@ pub fn collect_value_ref_names( let mut __result = Vec::new(); for c in n.children.clone().iter().cloned() { __result.extend( - (*collect_value_ref_names(c.clone(), source_indices.clone())) - .iter() - .cloned(), + (*collect_value_ref_names( + c.clone(), + source_indices.clone(), + type_summaries.clone(), + )) + .iter() + .cloned(), ); } __result @@ -4806,9 +4880,13 @@ pub fn collect_value_ref_names( let mut __result = Vec::new(); for c in n.params.clone().iter().cloned() { __result.extend( - (*collect_value_ref_names(c.clone(), source_indices.clone())) - .iter() - .cloned(), + (*collect_value_ref_names( + c.clone(), + source_indices.clone(), + type_summaries.clone(), + )) + .iter() + .cloned(), ); } __result @@ -4819,9 +4897,13 @@ pub fn collect_value_ref_names( let mut __result = Vec::new(); for c in n.uses.clone().iter().cloned() { __result.extend( - (*collect_value_ref_names(c.clone(), source_indices.clone())) - .iter() - .cloned(), + (*collect_value_ref_names( + c.clone(), + source_indices.clone(), + type_summaries.clone(), + )) + .iter() + .cloned(), ); } __result @@ -4830,9 +4912,13 @@ pub fn collect_value_ref_names( let mut __result = Vec::new(); for c in n.properties.clone().iter().cloned() { __result.extend( - (*collect_value_ref_names(c.clone(), source_indices.clone())) - .iter() - .cloned(), + (*collect_value_ref_names( + c.clone(), + source_indices.clone(), + type_summaries.clone(), + )) + .iter() + .cloned(), ); } __result @@ -4841,16 +4927,28 @@ pub fn collect_value_ref_names( ); let opt_fields = v1_rt::concat( match n.body.clone() { - Some(b) => collect_value_ref_names(b.clone(), source_indices.clone()), + Some(b) => collect_value_ref_names( + b.clone(), + source_indices.clone(), + type_summaries.clone(), + ), None => Rc::new(vec![]), }, v1_rt::concat( match n.transport.clone() { - Some(t) => collect_value_ref_names(t.clone(), source_indices.clone()), + Some(t) => collect_value_ref_names( + t.clone(), + source_indices.clone(), + type_summaries.clone(), + ), None => Rc::new(vec![]), }, match n.type_annotation.clone() { - Some(t) => collect_value_ref_names(t.clone(), source_indices.clone()), + Some(t) => collect_value_ref_names( + t.clone(), + source_indices.clone(), + type_summaries.clone(), + ), None => Rc::new(vec![]), }, ), @@ -4959,7 +5057,7 @@ pub fn collect_value_emit_type_surface_names( stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { let self_names = match (*n.expr_data.clone()).clone() { ExprData::ExprRecordLit { parent_enum: _, .. } => { - record_lit_ref_names(n.clone(), source_indices.clone()) + record_lit_ref_names(n.clone(), source_indices.clone(), type_summaries.clone()) } ExprData::ExprMatch => collect_match_pattern_parent_enums( n.clone(), @@ -5224,9 +5322,13 @@ pub fn reference_derived_use_lines( let mut __result = Vec::new(); for item in items.clone().iter().cloned() { __result.extend( - (*collect_value_ref_names(item.clone(), source_indices.clone())) - .iter() - .cloned(), + (*collect_value_ref_names( + item.clone(), + source_indices.clone(), + emit_info.type_summaries.clone(), + )) + .iter() + .cloned(), ); } __result From 181ebce7fb962c6d6bf3a29b655bee252c1e8471 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Jul 2026 04:28:13 +0000 Subject: [PATCH 5/7] WIP: Type-ref roots 1-3: clear the six-module shared histogram (post-7097) --- src/v1/05_emit_rust.dag | 80 +++++++- src/v1/stage0/src/v1_compiler_emit_rust.rs | 204 +++++++++++++++++---- 2 files changed, 234 insertions(+), 50 deletions(-) diff --git a/src/v1/05_emit_rust.dag b/src/v1/05_emit_rust.dag index 278f0c0623e..7d31f80daa3 100644 --- a/src/v1/05_emit_rust.dag +++ b/src/v1/05_emit_rust.dag @@ -2174,6 +2174,58 @@ fn collect_match_pattern_parent_enums(expr: Node, source_indices: Map, variant_to_enum: Map) -> String { + match n.expr_data { + ExprRecordLit { parent_enum: pe } => + let variant_name = match record_lit_type_name_at(texpr: n, source_indices: source_indices) { + Present { value: v } => v + Absent => authored_name_at(source_indices: source_indices, node: n) + } + let enum_name = match pe { + Present { value: e } => e + Absent => + match map_get(variant_to_enum, variant_name) { + Present { value: p } => p + Absent => "" + } + } + if enum_name != "" && variant_name != "" { + variant_summary_key(enum_name: enum_name, variant_name: variant_name) + } else { "" } + _ => "" + } +} + +fn collect_record_lit_field_struct_surfaces(parent: Node, field_init: Node, source_indices: Map, type_summaries: Map, variant_to_enum: Map) -> List { + let field_name = field_init_node_name_at(n: field_init, source_indices: source_indices) + if field_name == "" { [] } else { + let field_value = field_init_node_value(n: field_init) + match field_value.expr_data { + ExprRecordLit { parent_enum: _ } => + let summary_key = variant_record_lit_summary_key(n: parent, source_indices: source_indices, variant_to_enum: variant_to_enum) + if summary_key == "" { [] } else { + match map_get(type_summaries, summary_key) { + Present { value: summary } => + match map_get(summary.field_type_map, field_name) { + Present { value: ft } => + if ft != "" && match map_get(type_summaries, ft) { + Present { value: fts } => + match fts.repr { + StructRepr => true + _ => false + } + Absent => false + } { [ft] } else { [] } + Absent => [] + } + Absent => [] + } + } + _ => [] + } + } +} + fn collect_value_emit_type_surface_names(n: Node, source_indices: Map, variant_to_enum: Map, type_summaries: Map) -> List { let self_names = match n.expr_data { ExprRecordLit { parent_enum: _ } => record_lit_ref_names(n: n, source_indices: source_indices, type_summaries: type_summaries) @@ -2188,16 +2240,24 @@ fn collect_value_emit_type_surface_names(n: Node, source_indices: Map flat_map(c => collect_value_emit_type_surface_names(n: c, source_indices: source_indices, variant_to_enum: variant_to_enum, type_summaries: type_summaries)), - n.params |> flat_map(c => collect_value_emit_type_surface_names(n: c, source_indices: source_indices, variant_to_enum: variant_to_enum, type_summaries: type_summaries)) - ), - concat( - n.uses |> flat_map(c => collect_value_emit_type_surface_names(n: c, source_indices: source_indices, variant_to_enum: variant_to_enum, type_summaries: type_summaries)), - n.properties |> flat_map(c => collect_value_emit_type_surface_names(n: c, source_indices: source_indices, variant_to_enum: variant_to_enum, type_summaries: type_summaries)) - ) - ) + let child_names = match n.expr_data { + ExprRecordLit { parent_enum: _ } => + concat( + n.children |> flat_map(c => collect_record_lit_field_struct_surfaces(parent: n, field_init: c, source_indices: source_indices, type_summaries: type_summaries, variant_to_enum: variant_to_enum)), + n.children |> flat_map(c => collect_value_emit_type_surface_names(n: field_init_node_value(n: c), source_indices: source_indices, variant_to_enum: variant_to_enum, type_summaries: type_summaries)) + ) + _ => + concat( + concat( + n.children |> flat_map(c => collect_value_emit_type_surface_names(n: c, source_indices: source_indices, variant_to_enum: variant_to_enum, type_summaries: type_summaries)), + n.params |> flat_map(c => collect_value_emit_type_surface_names(n: c, source_indices: source_indices, variant_to_enum: variant_to_enum, type_summaries: type_summaries)) + ), + concat( + n.uses |> flat_map(c => collect_value_emit_type_surface_names(n: c, source_indices: source_indices, variant_to_enum: variant_to_enum, type_summaries: type_summaries)), + n.properties |> flat_map(c => collect_value_emit_type_surface_names(n: c, source_indices: source_indices, variant_to_enum: variant_to_enum, type_summaries: type_summaries)) + ) + ) + } let opt_names = concat( match n.body { Present { value: b } => collect_value_emit_type_surface_names(n: b, source_indices: source_indices, variant_to_enum: variant_to_enum, type_summaries: type_summaries) Absent => [] }, concat( diff --git a/src/v1/stage0/src/v1_compiler_emit_rust.rs b/src/v1/stage0/src/v1_compiler_emit_rust.rs index 903934ba3fd..33270448ad9 100644 --- a/src/v1/stage0/src/v1_compiler_emit_rust.rs +++ b/src/v1/stage0/src/v1_compiler_emit_rust.rs @@ -5048,6 +5048,93 @@ pub fn collect_match_pattern_parent_enums( } } +pub fn variant_record_lit_summary_key( + n: Rc, + source_indices: Rc>>, + variant_to_enum: Rc>, +) -> String { + match (*n.expr_data.clone()).clone() { + ExprData::ExprRecordLit { + parent_enum: pe, .. + } => { + let variant_name = match record_lit_type_name_at(n.clone(), source_indices.clone()) { + Some(v) => v.clone(), + None => authored_name_at(source_indices.clone(), n.clone()), + }; + let enum_name = match pe.clone() { + Some(e) => e.clone(), + None => match v1_rt::map_get(&variant_to_enum, variant_name.clone()) { + Some(p) => p.clone(), + None => "".to_string(), + }, + }; + if ((enum_name.clone() != "".to_string()) && (variant_name.clone() != "".to_string())) { + variant_summary_key(enum_name.clone(), variant_name.clone()) + } else { + "".to_string() + } + } + _ => "".to_string(), + } +} + +pub fn collect_record_lit_field_struct_surfaces( + parent: Rc, + field_init: Rc, + source_indices: Rc>>, + type_summaries: Rc>>, + variant_to_enum: Rc>, +) -> Rc> { + { + let field_name = field_init_node_name_at(field_init.clone(), source_indices.clone()); + if (field_name.clone() == "".to_string()) { + Rc::new(vec![]) + } else { + { + let field_value = field_init_node_value(field_init.clone()); + match (*field_value.expr_data.clone()).clone() { + ExprData::ExprRecordLit { parent_enum: _, .. } => { + let summary_key = variant_record_lit_summary_key( + parent.clone(), + source_indices.clone(), + variant_to_enum.clone(), + ); + if (summary_key.clone() == "".to_string()) { + Rc::new(vec![]) + } else { + match v1_rt::map_get(&type_summaries, summary_key.clone()) { + Some(summary) => match v1_rt::map_get( + &summary.field_type_map.clone(), + field_name.clone(), + ) { + Some(ft) => { + if ((ft.clone() != "".to_string()) + && match v1_rt::map_get(&type_summaries, ft.clone()) { + Some(fts) => match (*fts.repr.clone()).clone() { + TypeRepr::StructRepr => true, + _ => false, + }, + None => false, + }) + { + Rc::new(vec![ft.clone()]) + } else { + Rc::new(vec![]) + } + } + None => Rc::new(vec![]), + }, + None => Rc::new(vec![]), + } + } + } + _ => Rc::new(vec![]), + } + } + } + } +} + pub fn collect_value_emit_type_surface_names( n: Rc, source_indices: Rc>>, @@ -5089,51 +5176,18 @@ pub fn collect_value_emit_type_surface_names( )) } }; - let child_names = v1_rt::concat( - v1_rt::concat( + let child_names = match (*n.expr_data.clone()).clone() { + ExprData::ExprRecordLit { parent_enum: _, .. } => v1_rt::concat( Rc::new({ let mut __result = Vec::new(); for c in n.children.clone().iter().cloned() { __result.extend( - (*collect_value_emit_type_surface_names( - c.clone(), - source_indices.clone(), - variant_to_enum.clone(), - type_summaries.clone(), - )) - .iter() - .cloned(), - ); - } - __result - }), - Rc::new({ - let mut __result = Vec::new(); - for c in n.params.clone().iter().cloned() { - __result.extend( - (*collect_value_emit_type_surface_names( + (*collect_record_lit_field_struct_surfaces( + n.clone(), c.clone(), source_indices.clone(), - variant_to_enum.clone(), type_summaries.clone(), - )) - .iter() - .cloned(), - ); - } - __result - }), - ), - v1_rt::concat( - Rc::new({ - let mut __result = Vec::new(); - for c in n.uses.clone().iter().cloned() { - __result.extend( - (*collect_value_emit_type_surface_names( - c.clone(), - source_indices.clone(), variant_to_enum.clone(), - type_summaries.clone(), )) .iter() .cloned(), @@ -5143,10 +5197,10 @@ pub fn collect_value_emit_type_surface_names( }), Rc::new({ let mut __result = Vec::new(); - for c in n.properties.clone().iter().cloned() { + for c in n.children.clone().iter().cloned() { __result.extend( (*collect_value_emit_type_surface_names( - c.clone(), + field_init_node_value(c.clone()), source_indices.clone(), variant_to_enum.clone(), type_summaries.clone(), @@ -5158,7 +5212,77 @@ pub fn collect_value_emit_type_surface_names( __result }), ), - ); + _ => v1_rt::concat( + v1_rt::concat( + Rc::new({ + let mut __result = Vec::new(); + for c in n.children.clone().iter().cloned() { + __result.extend( + (*collect_value_emit_type_surface_names( + c.clone(), + source_indices.clone(), + variant_to_enum.clone(), + type_summaries.clone(), + )) + .iter() + .cloned(), + ); + } + __result + }), + Rc::new({ + let mut __result = Vec::new(); + for c in n.params.clone().iter().cloned() { + __result.extend( + (*collect_value_emit_type_surface_names( + c.clone(), + source_indices.clone(), + variant_to_enum.clone(), + type_summaries.clone(), + )) + .iter() + .cloned(), + ); + } + __result + }), + ), + v1_rt::concat( + Rc::new({ + let mut __result = Vec::new(); + for c in n.uses.clone().iter().cloned() { + __result.extend( + (*collect_value_emit_type_surface_names( + c.clone(), + source_indices.clone(), + variant_to_enum.clone(), + type_summaries.clone(), + )) + .iter() + .cloned(), + ); + } + __result + }), + Rc::new({ + let mut __result = Vec::new(); + for c in n.properties.clone().iter().cloned() { + __result.extend( + (*collect_value_emit_type_surface_names( + c.clone(), + source_indices.clone(), + variant_to_enum.clone(), + type_summaries.clone(), + )) + .iter() + .cloned(), + ); + } + __result + }), + ), + ), + }; let opt_names = v1_rt::concat( match n.body.clone() { Some(b) => collect_value_emit_type_surface_names( From b76e735f156732a41842e2ef6bae514a29920d88 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Jul 2026 04:39:04 +0000 Subject: [PATCH 6/7] WIP: Type-ref roots 1-3: clear the six-module shared histogram (post-7097) --- src/v1/05_emit_rust.dag | 57 ++++++++++--- src/v1/stage0/src/v1_compiler_emit_rust.rs | 93 ++++++++++++++++++++-- 2 files changed, 130 insertions(+), 20 deletions(-) diff --git a/src/v1/05_emit_rust.dag b/src/v1/05_emit_rust.dag index 7d31f80daa3..0152b23c1b9 100644 --- a/src/v1/05_emit_rust.dag +++ b/src/v1/05_emit_rust.dag @@ -2059,7 +2059,36 @@ fn anonymous_record_lit_surface_name(n: Node, source_indices: Map, type_summaries: Map) -> List { +fn record_lit_variant_payload_struct_surfaces(n: Node, source_indices: Map, type_summaries: Map, variant_to_enum: Map) -> List { + let variant_name = match record_lit_type_name_at(texpr: n, source_indices: source_indices) { + Present { value: v } => v + Absent => authored_name_at(source_indices: source_indices, node: n) + } + if variant_name == "" { [] } else { + let enum_name = match map_get(variant_to_enum, variant_name) { + Present { value: e } => e + Absent => "" + } + if enum_name == "" { [] } else { + match map_get(type_summaries, variant_summary_key(enum_name: enum_name, variant_name: variant_name)) { + Present { value: summary } => + map_values(summary.field_type_map) |> filter(ft => + ft != "" && match map_get(type_summaries, ft) { + Present { value: fts } => + match fts.repr { + StructRepr => true + _ => false + } + Absent => false + } + ) + Absent => [] + } + } + } +} + +fn record_lit_ref_names(n: Node, source_indices: Map, type_summaries: Map, variant_to_enum: Map) -> List { match n.expr_data { ExprRecordLit { parent_enum: pe } => let tn_list = match record_lit_type_name_at(texpr: n, source_indices: source_indices) { @@ -2075,7 +2104,8 @@ fn record_lit_ref_names(n: Node, source_indices: Map, type Present { value: p } => if p != "" { [p] } else { [] } Absent => [] } - unique_strings(items: concat(tn_list, pe_list)) + let payload_structs = record_lit_variant_payload_struct_surfaces(n: n, source_indices: source_indices, type_summaries: type_summaries, variant_to_enum: variant_to_enum) + unique_strings(items: concat(concat(tn_list, pe_list), payload_structs)) _ => [] } } @@ -2102,7 +2132,7 @@ fn collect_items_field_import_surface_names(items: List, type_summaries: M )) } -fn collect_value_ref_names(n: Node, source_indices: Map, type_summaries: Map) -> List { +fn collect_value_ref_names(n: Node, source_indices: Map, type_summaries: Map, variant_to_enum: Map) -> List { let self_name = match n.expr_data { ExprVar { binding_kind: bk } => match bk { @@ -2115,24 +2145,24 @@ fn collect_value_ref_names(n: Node, source_indices: Map, t let nm = authored_name_at(source_indices: source_indices, node: n) if nm != "" { [nm] } else { [] } ExprRecordLit { parent_enum: _ } => - record_lit_ref_names(n: n, source_indices: source_indices, type_summaries: type_summaries) + record_lit_ref_names(n: n, source_indices: source_indices, type_summaries: type_summaries, variant_to_enum: variant_to_enum) _ => [] } let list_fields = concat( concat( - n.children |> flat_map(c => collect_value_ref_names(n: c, source_indices: source_indices, type_summaries: type_summaries)), - n.params |> flat_map(c => collect_value_ref_names(n: c, source_indices: source_indices, type_summaries: type_summaries)) + n.children |> flat_map(c => collect_value_ref_names(n: c, source_indices: source_indices, type_summaries: type_summaries, variant_to_enum: variant_to_enum)), + n.params |> flat_map(c => collect_value_ref_names(n: c, source_indices: source_indices, type_summaries: type_summaries, variant_to_enum: variant_to_enum)) ), concat( - n.uses |> flat_map(c => collect_value_ref_names(n: c, source_indices: source_indices, type_summaries: type_summaries)), - n.properties |> flat_map(c => collect_value_ref_names(n: c, source_indices: source_indices, type_summaries: type_summaries)) + n.uses |> flat_map(c => collect_value_ref_names(n: c, source_indices: source_indices, type_summaries: type_summaries, variant_to_enum: variant_to_enum)), + n.properties |> flat_map(c => collect_value_ref_names(n: c, source_indices: source_indices, type_summaries: type_summaries, variant_to_enum: variant_to_enum)) ) ) let opt_fields = concat( - match n.body { Present { value: b } => collect_value_ref_names(n: b, source_indices: source_indices, type_summaries: type_summaries) Absent => [] }, + match n.body { Present { value: b } => collect_value_ref_names(n: b, source_indices: source_indices, type_summaries: type_summaries, variant_to_enum: variant_to_enum) Absent => [] }, concat( - match n.transport { Present { value: t } => collect_value_ref_names(n: t, source_indices: source_indices, type_summaries: type_summaries) Absent => [] }, - match n.type_annotation { Present { value: t } => collect_value_ref_names(n: t, source_indices: source_indices, type_summaries: type_summaries) Absent => [] } + match n.transport { Present { value: t } => collect_value_ref_names(n: t, source_indices: source_indices, type_summaries: type_summaries, variant_to_enum: variant_to_enum) Absent => [] }, + match n.type_annotation { Present { value: t } => collect_value_ref_names(n: t, source_indices: source_indices, type_summaries: type_summaries, variant_to_enum: variant_to_enum) Absent => [] } ) ) concat(self_name, concat(list_fields, opt_fields)) @@ -2228,7 +2258,8 @@ fn collect_record_lit_field_struct_surfaces(parent: Node, field_init: Node, sour fn collect_value_emit_type_surface_names(n: Node, source_indices: Map, variant_to_enum: Map, type_summaries: Map) -> List { let self_names = match n.expr_data { - ExprRecordLit { parent_enum: _ } => record_lit_ref_names(n: n, source_indices: source_indices, type_summaries: type_summaries) + ExprRecordLit { parent_enum: _ } => + record_lit_ref_names(n: n, source_indices: source_indices, type_summaries: type_summaries, variant_to_enum: variant_to_enum) ExprMatch => collect_match_pattern_parent_enums(expr: n, source_indices: source_indices, variant_to_enum: variant_to_enum, type_summaries: type_summaries) _ => let from_inferred = emit_inferred_type_leaf_name(n: n, source_indices: source_indices) @@ -2298,7 +2329,7 @@ data reference_derived_use_lines_note: String = "emit_import_closure_root (§5). fn reference_derived_use_lines(items: List, unlisted_type_names: List, this_module_name: String, registry: Map, emit_info: EmitGraphInfo, local_type_names: List, already_imported_names: List, export_sets: Map>, typed_modules: List, source_indices: Map, module_index: ModuleIndex) -> List { { - let value_names = unique_strings(items: items |> flat_map(item => collect_value_ref_names(n: item, source_indices: source_indices, type_summaries: emit_info.type_summaries))) + let value_names = unique_strings(items: items |> flat_map(item => collect_value_ref_names(n: item, source_indices: source_indices, type_summaries: emit_info.type_summaries, variant_to_enum: emit_info.variant_to_enum))) let type_surface_names = unique_strings(items: items |> flat_map(item => collect_item_emit_surface_names(item: item, source_indices: source_indices, variant_to_enum: emit_info.variant_to_enum, type_summaries: emit_info.type_summaries))) let field_surface_names = collect_items_field_import_surface_names(items: items, type_summaries: emit_info.type_summaries, variant_to_enum: emit_info.variant_to_enum, source_indices: source_indices) let candidates = unique_strings(items: concat(concat(concat(unlisted_type_names, value_names), type_surface_names), field_surface_names)) diff --git a/src/v1/stage0/src/v1_compiler_emit_rust.rs b/src/v1/stage0/src/v1_compiler_emit_rust.rs index 33270448ad9..0a29e4151de 100644 --- a/src/v1/stage0/src/v1_compiler_emit_rust.rs +++ b/src/v1/stage0/src/v1_compiler_emit_rust.rs @@ -4712,10 +4712,65 @@ pub fn anonymous_record_lit_surface_name( } } +pub fn record_lit_variant_payload_struct_surfaces( + n: Rc, + source_indices: Rc>>, + type_summaries: Rc>>, + variant_to_enum: Rc>, +) -> Rc> { + { + let variant_name = match record_lit_type_name_at(n.clone(), source_indices.clone()) { + Some(v) => v.clone(), + None => authored_name_at(source_indices.clone(), n.clone()), + }; + if (variant_name.clone() == "".to_string()) { + Rc::new(vec![]) + } else { + { + let enum_name = match v1_rt::map_get(&variant_to_enum, variant_name.clone()) { + Some(e) => e.clone(), + None => "".to_string(), + }; + if (enum_name.clone() == "".to_string()) { + Rc::new(vec![]) + } else { + match v1_rt::map_get( + &type_summaries, + variant_summary_key(enum_name.clone(), variant_name.clone()), + ) { + Some(summary) => Rc::new({ + let mut __result = Vec::new(); + for ft in Rc::new(v1_rt::map_values(&summary.field_type_map.clone())) + .iter() + .cloned() + { + if ((ft.clone() != "".to_string()) + && match v1_rt::map_get(&type_summaries, ft.clone()) { + Some(fts) => match (*fts.repr.clone()).clone() { + TypeRepr::StructRepr => true, + _ => false, + }, + None => false, + }) + { + __result.push(ft); + } + } + __result + }), + None => Rc::new(vec![]), + } + } + } + } + } +} + pub fn record_lit_ref_names( n: Rc, source_indices: Rc>>, type_summaries: Rc>>, + variant_to_enum: Rc>, ) -> Rc> { match (*n.expr_data.clone()).clone() { ExprData::ExprRecordLit { @@ -4759,7 +4814,16 @@ pub fn record_lit_ref_names( } None => Rc::new(vec![]), }; - unique_strings(v1_rt::concat(tn_list.clone(), pe_list.clone())) + let payload_structs = record_lit_variant_payload_struct_surfaces( + n.clone(), + source_indices.clone(), + type_summaries.clone(), + variant_to_enum.clone(), + ); + unique_strings(v1_rt::concat( + v1_rt::concat(tn_list.clone(), pe_list.clone()), + payload_structs.clone(), + )) } _ => Rc::new(vec![]), } @@ -4830,6 +4894,7 @@ pub fn collect_value_ref_names( n: Rc, source_indices: Rc>>, type_summaries: Rc>>, + variant_to_enum: Rc>, ) -> Rc> { stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { let self_name = match (*n.expr_data.clone()).clone() { @@ -4854,9 +4919,12 @@ pub fn collect_value_ref_names( Rc::new(vec![]) } } - ExprData::ExprRecordLit { parent_enum: _, .. } => { - record_lit_ref_names(n.clone(), source_indices.clone(), type_summaries.clone()) - } + ExprData::ExprRecordLit { parent_enum: _, .. } => record_lit_ref_names( + n.clone(), + source_indices.clone(), + type_summaries.clone(), + variant_to_enum.clone(), + ), _ => Rc::new(vec![]), }; let list_fields = v1_rt::concat( @@ -4869,6 +4937,7 @@ pub fn collect_value_ref_names( c.clone(), source_indices.clone(), type_summaries.clone(), + variant_to_enum.clone(), )) .iter() .cloned(), @@ -4884,6 +4953,7 @@ pub fn collect_value_ref_names( c.clone(), source_indices.clone(), type_summaries.clone(), + variant_to_enum.clone(), )) .iter() .cloned(), @@ -4901,6 +4971,7 @@ pub fn collect_value_ref_names( c.clone(), source_indices.clone(), type_summaries.clone(), + variant_to_enum.clone(), )) .iter() .cloned(), @@ -4916,6 +4987,7 @@ pub fn collect_value_ref_names( c.clone(), source_indices.clone(), type_summaries.clone(), + variant_to_enum.clone(), )) .iter() .cloned(), @@ -4931,6 +5003,7 @@ pub fn collect_value_ref_names( b.clone(), source_indices.clone(), type_summaries.clone(), + variant_to_enum.clone(), ), None => Rc::new(vec![]), }, @@ -4940,6 +5013,7 @@ pub fn collect_value_ref_names( t.clone(), source_indices.clone(), type_summaries.clone(), + variant_to_enum.clone(), ), None => Rc::new(vec![]), }, @@ -4948,6 +5022,7 @@ pub fn collect_value_ref_names( t.clone(), source_indices.clone(), type_summaries.clone(), + variant_to_enum.clone(), ), None => Rc::new(vec![]), }, @@ -5143,9 +5218,12 @@ pub fn collect_value_emit_type_surface_names( ) -> Rc> { stacker::maybe_grow(512 * 1024, 2 * 1024 * 1024, || { let self_names = match (*n.expr_data.clone()).clone() { - ExprData::ExprRecordLit { parent_enum: _, .. } => { - record_lit_ref_names(n.clone(), source_indices.clone(), type_summaries.clone()) - } + ExprData::ExprRecordLit { parent_enum: _, .. } => record_lit_ref_names( + n.clone(), + source_indices.clone(), + type_summaries.clone(), + variant_to_enum.clone(), + ), ExprData::ExprMatch => collect_match_pattern_parent_enums( n.clone(), source_indices.clone(), @@ -5450,6 +5528,7 @@ pub fn reference_derived_use_lines( item.clone(), source_indices.clone(), emit_info.type_summaries.clone(), + emit_info.variant_to_enum.clone(), )) .iter() .cloned(), From 0b0322a8e740c38bb97519e26d008426bc89d00b Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Jul 2026 04:49:34 +0000 Subject: [PATCH 7/7] WIP: Type-ref roots 1-3: clear the six-module shared histogram (post-7097) --- src/v1/05_emit_rust.dag | 41 +++++- src/v1/stage0/src/v1_compiler_emit_rust.rs | 139 +++++++++++++++++---- 2 files changed, 153 insertions(+), 27 deletions(-) diff --git a/src/v1/05_emit_rust.dag b/src/v1/05_emit_rust.dag index 0152b23c1b9..8c594e53038 100644 --- a/src/v1/05_emit_rust.dag +++ b/src/v1/05_emit_rust.dag @@ -2114,7 +2114,18 @@ fn collect_items_field_import_surface_names(items: List, type_summaries: M unique_strings(items: items |> flat_map(item => collect_item_emit_surface_names(item: item, source_indices: source_indices, variant_to_enum: variant_to_enum, type_summaries: type_summaries) |> flat_map(type_name => - match map_get(type_summaries, type_name) { + let summary_lookup = match map_get(type_summaries, type_name) { + Present { value: summary } => Present { value: summary } + Absent => + match map_get(variant_to_enum, type_name) { + Present { value: enum_name } => + if enum_name == "" { none } else { + map_get(type_summaries, variant_summary_key(enum_name: enum_name, variant_name: type_name)) + } + Absent => none + } + } + match summary_lookup { Present { value: summary } => summary.field_import_surface_names |> filter(field_type => field_type != "" && match map_get(type_summaries, field_type) { @@ -2327,12 +2338,38 @@ fn imported_names_in_use_line(line: String) -> List { data reference_derived_use_lines_note: String = "emit_import_closure_root (§5). emit_imports wires a per-module use-line only for names in an authored import list. Namespace-only resolution (post-PR 6848) references cross-module names WITHOUT importing them, so the ref is KNOWN but the use-line is declined (advisory UnlistedImportUse, is_error_diagnostic=false) — a §5 fail-open (⊤-as-ignorance) that emits invalid Rust (E0422/E0433/E0425 downstream). This pass derives the missing use-lines from the SAME resolver signal, split by reference kind onto its precise authority (§2 Realization: one closure, two consumers): (1) TYPE refs come from the resolver's UnlistedImportUse diagnostics (04_resolve.dag resolve_node, masked && not-in-SVN at type positions) threaded through ResolvedGraph.diagnostics — zero-drift by construction, the resolver already applied its SVN mask AT RESOLVE TIME; (2) VALUE-position refs come from collect_value_ref_names, a NARROW walk that structurally excludes the type over-collection classes (container heads, field labels, deep-inferred type names): fn/data refs (FunctionValueBinding ExprVar + ExprCall callee names) AND record-literal type constructions (ExprRecordLit type name + its parent_enum) — the latter matter because a GENERIC user type constructed as `T{..}` (e.g. RealizedStep) is grounded by resolve_node (masked flips false into the defining-module descent) so it NEVER fires UnlistedImportUse, yet its bare `T` still needs a use-line; (3) TYPE-surface refs on item signatures come from collect_item_emit_surface_names (collect_item_type_surface_names + collect_value_emit_type_surface_names over data bodies) over each item's type_annotation, param types, inferred Resolved return/signature, AND value-position record-literal / variant-parent-enum surfaces the emitter will qualify (e.g. UriScheme::Https in a data anchor) — covering masked-at-resolve TYPE positions (e.g. partial-import return type PilotWidget) that never enter UnlistedImportUse and are not ExprVar/ExprCall harvests. Registry cross-module resolve + is_known_variant fallback keep variant constructors routed through their parent's import. CONSTRUCTION WALL (ROOT 3, §5): a candidate that registry-resolves to a provider module MUST also pass provider_proven_exports_symbol (name_in_transitive_export_surface) before any use-line is synthesized — never a plausible guess from the bare-name registry alone (the v1_rt::member fabrication class: registry homonym without export proof). NOTE the SVN authority is resolve-time-only: env.source_visible_names is built in 04_infer's unresolved_env and consumed by resolve_node, but is NOT persisted onto TypedModule.type_env (emit reads empty_map), so emit MUST NOT re-apply an SVN filter — it would be a no-op that (worse, when non-empty) diverges from the resolve-time mask. The union is instead already-imported filtered (a name already carried by an authored import / prelude / carrier use-line is skipped — this is what keeps a fully-imported SEED module zero-drift: its refs are all in an import line) and kernel filtered (no E0252 against the runtime prelude), then LOCAL-DECL filtered (any name the module itself declares — local_decl_names from authored_name_at over items, plus local_type_names aliases/phantoms — is never an import candidate: the containment tree binds a bare ref to the module's own declaration before any cross-module lookup, and the bare-name registry is last-write-wins, so a dual-tree homonym — dag/std List/Map/GroupCompletion vs their src/v2/std twins — steals the registry row and would otherwise synthesize a SELF-COLLIDING pub-use, the E0255 std_dup class measured on the 2026-07-22 curated 4-module baseline), then cross-module registry-resolved (a ref the registry maps to this same module is skipped), then reuses emit_specific_import_block for variant/reexport correctness with a §5 direct-emit fallback (arm (c): the name resolved via registry to provider AND export-proven). A candidate that registry-resolves to nothing, or resolves but fails export proof, is left unsynthesized (typed refusal at step-2 is future work); it never fabricates a use-line. SCOPE (emit_module_full): import-free modules run the full union (TYPE unlisted + VALUE refs) — the namespace-resolution case the post-PR-6848 regression is about. Import-bearing modules run reference_derived_use_lines ONLY when corpus_repr_is_faithful (FaithfulFreeMonoid / v2 namespace corpus): a partial-import namespace module (e.g. v2.std.node_query importing Outcome but calling outcome_with_diagnostics, or importing Outcome but annotating NamedEdgeTargetLookup) must synthesize BOTH the missing fn-value use-line AND the missing type use-line without duplicating names emit_imports already owns. HostNative import-bearing modules (v1 seed) get [] — running the walk there adds spurious/wrong use-lines (registry homonyms like kernel_span/is_type_variable) and breaks zero-drift seed regen." +fn expand_variant_payload_struct_imports(names: List, type_summaries: Map, variant_to_enum: Map) -> List { + names |> flat_map(n => + match map_get(variant_to_enum, n) { + Present { value: enum_name } => + if enum_name == "" { [] } else { + match map_get(type_summaries, variant_summary_key(enum_name: enum_name, variant_name: n)) { + Present { value: summary } => + map_values(summary.field_type_map) |> filter(ft => + ft != "" && match map_get(type_summaries, ft) { + Present { value: fts } => + match fts.repr { + StructRepr => true + _ => false + } + Absent => false + } + ) + Absent => [] + } + } + Absent => [] + } + ) +} + fn reference_derived_use_lines(items: List, unlisted_type_names: List, this_module_name: String, registry: Map, emit_info: EmitGraphInfo, local_type_names: List, already_imported_names: List, export_sets: Map>, typed_modules: List, source_indices: Map, module_index: ModuleIndex) -> List { { let value_names = unique_strings(items: items |> flat_map(item => collect_value_ref_names(n: item, source_indices: source_indices, type_summaries: emit_info.type_summaries, variant_to_enum: emit_info.variant_to_enum))) let type_surface_names = unique_strings(items: items |> flat_map(item => collect_item_emit_surface_names(item: item, source_indices: source_indices, variant_to_enum: emit_info.variant_to_enum, type_summaries: emit_info.type_summaries))) let field_surface_names = collect_items_field_import_surface_names(items: items, type_summaries: emit_info.type_summaries, variant_to_enum: emit_info.variant_to_enum, source_indices: source_indices) - let candidates = unique_strings(items: concat(concat(concat(unlisted_type_names, value_names), type_surface_names), field_surface_names)) + let variant_payload_structs = expand_variant_payload_struct_imports(names: type_surface_names, type_summaries: emit_info.type_summaries, variant_to_enum: emit_info.variant_to_enum) + let candidates = unique_strings(items: concat(concat(concat(concat(unlisted_type_names, value_names), type_surface_names), field_surface_names), variant_payload_structs)) let local_decl_names = items |> flat_map(item => let nm = authored_name_at(source_indices: source_indices, node: item) if nm == "" { [] } else { [nm] } diff --git a/src/v1/stage0/src/v1_compiler_emit_rust.rs b/src/v1/stage0/src/v1_compiler_emit_rust.rs index 0a29e4151de..49d29dfbb1c 100644 --- a/src/v1/stage0/src/v1_compiler_emit_rust.rs +++ b/src/v1/stage0/src/v1_compiler_emit_rust.rs @@ -4851,30 +4851,58 @@ pub fn collect_items_field_import_surface_names( .cloned() { __result.extend( - (*match v1_rt::map_get(&type_summaries, type_name.clone()) { - Some(summary) => Rc::new({ - let mut __result = Vec::new(); - for field_type in - summary.field_import_surface_names.clone().iter().cloned() - { - if ((field_type.clone() != "".to_string()) - && match v1_rt::map_get( - &type_summaries, - field_type.clone(), - ) { - Some(ft) => match (*ft.repr.clone()).clone() { - TypeRepr::StructRepr => true, - _ => false, - }, - None => false, - }) + (*{ + let summary_lookup = + match v1_rt::map_get(&type_summaries, type_name.clone()) { + Some(summary) => Some(summary.clone()), + None => match v1_rt::map_get( + &variant_to_enum, + type_name.clone(), + ) { + Some(enum_name) => { + if (enum_name.clone() == "".to_string()) { + None + } else { + v1_rt::map_get( + &type_summaries, + variant_summary_key( + enum_name.clone(), + type_name.clone(), + ), + ) + } + } + None => None, + }, + }; + match summary_lookup.clone() { + Some(summary) => Rc::new({ + let mut __result = Vec::new(); + for field_type in summary + .field_import_surface_names + .clone() + .iter() + .cloned() { - __result.push(field_type); + if ((field_type.clone() != "".to_string()) + && match v1_rt::map_get( + &type_summaries, + field_type.clone(), + ) { + Some(ft) => match (*ft.repr.clone()).clone() { + TypeRepr::StructRepr => true, + _ => false, + }, + None => false, + }) + { + __result.push(field_type); + } } - } - __result - }), - None => Rc::new(vec![]), + __result + }), + None => Rc::new(vec![]), + } }) .iter() .cloned(), @@ -5506,6 +5534,59 @@ pub fn reference_derived_use_lines_note() -> String { CACHED.with(|c: &String| c.clone()) } +pub fn expand_variant_payload_struct_imports( + names: Rc>, + type_summaries: Rc>>, + variant_to_enum: Rc>, +) -> Rc> { + Rc::new({ + let mut __result = Vec::new(); + for n in names.clone().iter().cloned() { + __result.extend( + (*match v1_rt::map_get(&variant_to_enum, n.clone()) { + Some(enum_name) => { + if (enum_name.clone() == "".to_string()) { + Rc::new(vec![]) + } else { + match v1_rt::map_get( + &type_summaries, + variant_summary_key(enum_name.clone(), n.clone()), + ) { + Some(summary) => Rc::new({ + let mut __result = Vec::new(); + for ft in + Rc::new(v1_rt::map_values(&summary.field_type_map.clone())) + .iter() + .cloned() + { + if ((ft.clone() != "".to_string()) + && match v1_rt::map_get(&type_summaries, ft.clone()) { + Some(fts) => match (*fts.repr.clone()).clone() { + TypeRepr::StructRepr => true, + _ => false, + }, + None => false, + }) + { + __result.push(ft); + } + } + __result + }), + None => Rc::new(vec![]), + } + } + } + None => Rc::new(vec![]), + }) + .iter() + .cloned(), + ); + } + __result + }) +} + pub fn reference_derived_use_lines( items: Rc>>, unlisted_type_names: Rc>, @@ -5558,12 +5639,20 @@ pub fn reference_derived_use_lines( emit_info.variant_to_enum.clone(), source_indices.clone(), ); + let variant_payload_structs = expand_variant_payload_struct_imports( + type_surface_names.clone(), + emit_info.type_summaries.clone(), + emit_info.variant_to_enum.clone(), + ); let candidates = unique_strings(v1_rt::concat( v1_rt::concat( - v1_rt::concat(unlisted_type_names.clone(), value_names.clone()), - type_surface_names.clone(), + v1_rt::concat( + v1_rt::concat(unlisted_type_names.clone(), value_names.clone()), + type_surface_names.clone(), + ), + field_surface_names.clone(), ), - field_surface_names.clone(), + variant_payload_structs.clone(), )); let local_decl_names = Rc::new({ let mut __result = Vec::new();