diff --git a/src/v1/05_emit_rust.dag b/src/v1/05_emit_rust.dag index a835c1912eb..5e742e0e9e6 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 { + 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) { + 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 => [] + } + ) + )) +} + 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] } diff --git a/src/v1/stage0/src/v1_compiler_emit_rust.rs b/src/v1/stage0/src/v1_compiler_emit_rust.rs index 731aac25a3f..e7eadca47d9 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,73 @@ 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> { + unique_strings(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 + })) +} + pub fn collect_value_ref_names( n: Rc, source_indices: Rc>>, @@ -4696,20 +4784,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 +4850,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 +4866,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 +5129,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();