| 3444 | } |
| 3445 | |
| 3446 | void rust_process_statement(RustLSPContext *ctx, TSNode node) { |
| 3447 | if (ts_node_is_null(node)) |
| 3448 | return; |
| 3449 | const char *kind = ts_node_type(node); |
| 3450 | |
| 3451 | /* let_declaration: let pat: T = expr; |
| 3452 | * |
| 3453 | * Bidirectional inference: if the user wrote `let v: Vec<String> = …;` |
| 3454 | * we pass `Vec<String>` as the expected hint when synthesising the |
| 3455 | * RHS. That lets ambiguous calls like `Vec::new()` keep their full |
| 3456 | * template arguments through the chain. */ |
| 3457 | if (strcmp(kind, "let_declaration") == 0) { |
| 3458 | TSNode pat = ts_node_child_by_field_name(node, "pattern", 7); |
| 3459 | TSNode tn = ts_node_child_by_field_name(node, "type", 4); |
| 3460 | TSNode val = ts_node_child_by_field_name(node, "value", 5); |
| 3461 | |
| 3462 | const CBMType *annotated = NULL; |
| 3463 | if (!ts_node_is_null(tn)) { |
| 3464 | annotated = rust_parse_type_node(ctx, tn); |
| 3465 | } |
| 3466 | const CBMType *let_type = annotated; |
| 3467 | if ((!let_type || cbm_type_is_unknown(let_type)) && !ts_node_is_null(val)) { |
| 3468 | /* Synthesis: evaluate the RHS with the (possibly NULL) |
| 3469 | * annotated type as a hint. */ |
| 3470 | let_type = rust_eval_expr_typed(ctx, val, annotated); |
| 3471 | } |
| 3472 | if (!let_type) |
| 3473 | let_type = cbm_type_unknown(); |
| 3474 | if (!ts_node_is_null(pat)) |
| 3475 | rust_bind_pattern(ctx, pat, let_type); |
| 3476 | return; |
| 3477 | } |
| 3478 | |
| 3479 | /* const_item / static_item: const NAME: T = …; */ |
| 3480 | if (strcmp(kind, "const_item") == 0 || strcmp(kind, "static_item") == 0) { |
| 3481 | TSNode name_node = ts_node_child_by_field_name(node, "name", 4); |
| 3482 | TSNode tn = ts_node_child_by_field_name(node, "type", 4); |
| 3483 | const CBMType *type = |
| 3484 | ts_node_is_null(tn) ? cbm_type_unknown() : rust_parse_type_node(ctx, tn); |
| 3485 | if (!ts_node_is_null(name_node)) { |
| 3486 | char *name = rust_node_text(ctx, name_node); |
| 3487 | if (name) |
| 3488 | cbm_scope_bind(ctx->current_scope, name, type); |
| 3489 | } |
| 3490 | return; |
| 3491 | } |
| 3492 | } |
| 3493 | |
| 3494 | /* ════════════════════════════════════════════════════════════════════ |
| 3495 | * 10. Function & file walk |
no test coverage detected