Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 95 additions & 2 deletions src/v1/05_emit_rust.dag
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import v1.compiler.trait_derive_emit {
v1_emit_struct_from_capability_table, v1_emit_enum_supplemental_impls,
v1_generic_params_needing_clone_bound,
v1_emit_type_params_with_clone_bounds,
v1_emit_type_params_with_clone_and_ord_bounds,
v1_clone_bounded_type_params, v1_item_clone_bounded_param_names, v1_item_clone_undecided_head,
v1_map_key_required_type_names, v1_item_field_type_exprs, v1_with_map_key_requirement,
v1_clone_impl_required_type_params,
Expand All @@ -73,7 +74,8 @@ import v1.compiler.trait_derive_emit {
}
import v1.compiler.trait_bound_witness {
v1_rc_match_scrutinee_clone_bound_param_names, v1_union_clone_param_names,
v1_call_forwarding_clone_bound_wrapper_param_names
v1_call_forwarding_clone_bound_wrapper_param_names,
v1_set_union_ord_bound_param_names
}

import std.types { is_container_type, is_kernel_type, container_template_algebra }
Expand Down Expand Up @@ -5969,6 +5971,89 @@ fn v1_fn_body_derived_clone_param_names(params: List<Node>, inferred: Node, body
)
}

data v1_collect_set_union_call_elem_type_names_note: String = "Node-consuming extraction walker for v1_set_union_ord_bound_param_names (src/v1/trait_bound_witness.dag), gunbc dashboard node://adhoc-a9f61ade-340. Walks a function body collecting the resolved element-type-argument name of every argument passed to a set_union(..) call anywhere in the body -- not scoped to a direct top-level shape (unlike BoundedToDirectTopLevelMatchBody/BoundedToDirectSingleCallLambdaBody above) because the two real specimens this was traced from (audience_subset/audience_join, dag/std/authorization_profile.dag) both reach their set_union call through a nested match, one of them two matches deep. The variant coverage below starts from ownership.dag's collect_callable_refs (same file's own precedent for a full-body Node walker over this same expr_data vocabulary) rather than a blind recursion over .children -- ExprCall/ExprMatch/ExprIf/ExprLet/ExprBlock/ExprRecordLit/ExprMethodCall/ExprReturn/ExprLambda/ExprForEach/ExprFieldAccess are each named explicitly, matching that precedent -- plus one addition that precedent lacks: ExprBinOp, walking both binop_left/binop_right, needed because audience_subset's set_union call sits inside a `==` comparison (set_union(members, right_members) == right_members) and would otherwise be silently unreached; any other variant (ExprLiteral, ExprVar, etc.) is a base case with no nested expr to walk and contributes nothing."

fn v1_collect_set_union_call_elem_type_names(texpr: Node, si: Map<String, NewlineIndex>) -> List<String> {
match texpr.expr_data {
ExprCall =>
let callee_name = expr_call_func_at(texpr: texpr, source_indices: si)
let arg_hits = texpr.children |> fold(init: [], f: (acc, a) =>
concat(acc, v1_collect_set_union_call_elem_type_names(texpr: arg_value(n: a), si: si))
)
if callee_name == "set_union" {
let elem_hits = texpr.children |> fold(init: [], f: (acc, a) =>
let arg = arg_value(n: a)
match arg.inferred {
Present { value: Resolved { node: rt } } =>
concat(acc, rt.children |> map(c => authored_name_at(source_indices: si, node: c)))
_ => acc
}
)
concat(elem_hits, arg_hits)
} else {
arg_hits
}
ExprMatch =>
let scrut = v1_collect_set_union_call_elem_type_names(texpr: match_scrutinee(texpr: texpr), si: si)
match_arm_nodes(texpr: texpr) |> fold(init: scrut, f: (acc, arm) =>
concat(acc, v1_collect_set_union_call_elem_type_names(texpr: arm_body(n: arm), si: si))
)
ExprIf =>
let cond = v1_collect_set_union_call_elem_type_names(texpr: if_condition(texpr: texpr), si: si)
let then_br = v1_collect_set_union_call_elem_type_names(texpr: if_then_branch(texpr: texpr), si: si)
let else_br = match if_else_branch(texpr: texpr) {
Present { value: eb } => v1_collect_set_union_call_elem_type_names(texpr: eb, si: si)
Absent => []
}
concat(concat(cond, then_br), else_br)
ExprLet =>
let v = v1_collect_set_union_call_elem_type_names(texpr: let_value(texpr: texpr), si: si)
match let_body(texpr: texpr) {
Present { value: lb } => concat(v, v1_collect_set_union_call_elem_type_names(texpr: lb, si: si))
Absent => v
}
ExprBlock =>
texpr.children |> fold(init: [], f: (acc, child) =>
concat(acc, v1_collect_set_union_call_elem_type_names(texpr: child, si: si))
)
ExprRecordLit =>
texpr.children |> fold(init: [], f: (acc, field) =>
concat(acc, v1_collect_set_union_call_elem_type_names(texpr: arg_value(n: field), si: si))
)
ExprMethodCall { method_semantics: _ } =>
let recv = v1_collect_set_union_call_elem_type_names(texpr: method_receiver(texpr: texpr), si: si)
method_arg_nodes(texpr: texpr) |> fold(init: recv, f: (acc, a) =>
concat(acc, v1_collect_set_union_call_elem_type_names(texpr: arg_value(n: a), si: si))
)
ExprReturn =>
match texpr.children |> first {
Present { value: child } => v1_collect_set_union_call_elem_type_names(texpr: child, si: si)
Absent => []
}
ExprLambda =>
v1_collect_set_union_call_elem_type_names(texpr: lambda_body(texpr: texpr), si: si)
ExprForEach =>
let col = v1_collect_set_union_call_elem_type_names(texpr: foreach_collection(texpr: texpr), si: si)
concat(col, v1_collect_set_union_call_elem_type_names(texpr: foreach_body(texpr: texpr), si: si))
ExprFieldAccess =>
v1_collect_set_union_call_elem_type_names(texpr: field_access_base(texpr: texpr), si: si)
ExprBinOp { op: _, algebra_field: _ } =>
let l = v1_collect_set_union_call_elem_type_names(texpr: binop_left(texpr: texpr), si: si)
let r = v1_collect_set_union_call_elem_type_names(texpr: binop_right(texpr: texpr), si: si)
concat(l, r)
_ => []
}
}

fn v1_fn_body_set_union_ord_bound_param_names(
generic_param_names: List<String>,
body: Node,
source_indices: Map<String, NewlineIndex>
) -> List<String> {
let elem_type_names = v1_collect_set_union_call_elem_type_names(texpr: body, si: source_indices)
v1_set_union_ord_bound_param_names(generic_param_names: generic_param_names, set_union_call_elem_type_names: elem_type_names)
}

fn v1_call_forwarding_clone_bound_param_names(
generic_param_names: List<String>,
body: Node,
Expand Down Expand Up @@ -6100,7 +6185,15 @@ fn emit_fn_def(name: String, params: List<Node>, inferred: Node, body: Node, reg
derived_clone_param_names_with_rc_match
}
let needs_clone_bound = (clone_param_names |> count) > 0
let type_params_str = if needs_clone_bound {
let ord_param_names = v1_fn_body_set_union_ord_bound_param_names(
generic_param_names: generic_param_names,
body: body,
source_indices: si
)
let needs_ord_bound = (ord_param_names |> count) > 0
let type_params_str = if needs_ord_bound {
v1_emit_type_params_with_clone_and_ord_bounds(params: type_params, clone_param_names: clone_param_names, ord_param_names: ord_param_names, source_indices: si)
} else if needs_clone_bound {
v1_emit_type_params_with_clone_bounds(params: type_params, clone_param_names: clone_param_names, source_indices: si)
} else {
emit_type_params(params: type_params, source_indices: si)
Expand Down
Loading