Skip to content

Commit 74b7f40

Browse files
committed
fix: captured refs create scope boundaries in type inference
1 parent aaba3cf commit 74b7f40

3 files changed

Lines changed: 21 additions & 16 deletions

File tree

crates/plotnik-lib/src/analyze/type_check/infer.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,9 +348,16 @@ impl<'a, 'd> InferenceVisitor<'a, 'd> {
348348
}
349349

350350
/// Determines if an expression creates a scope boundary when captured.
351+
///
352+
/// When captured, these expressions produce structured values (not nodes):
353+
/// - Sequences/alternations: produce structs/enums from their internal captures
354+
/// - Refs: produce whatever the called definition returns (struct if it has captures)
355+
///
356+
/// This only affects captured expressions. Uncaptured refs remain transparent
357+
/// (their captures bubble up) because this check only runs in `infer_captured_expr`.
351358
fn inner_creates_scope(inner: &Expr) -> bool {
352359
match inner {
353-
Expr::SeqExpr(_) | Expr::AltExpr(_) => true,
360+
Expr::SeqExpr(_) | Expr::AltExpr(_) | Expr::Ref(_) => true,
354361
Expr::QuantifiedExpr(q) => {
355362
// Look through quantifier to the actual expression
356363
q.inner()

crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__codegen_tests__definitions_nested_capture.snap

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,14 @@ S8 "parent"
2121
[type_defs]
2222
T0 = <Node>
2323
T1 = Struct M0:1 ; { name }
24-
T2 = Struct M1:2 ; { name, item }
24+
T2 = Struct M1:1 ; { item }
2525
T3 = ArrayStar(T2) ; T2*
26-
T4 = Struct M3:1 ; { items }
26+
T4 = Struct M2:1 ; { items }
2727

2828
[type_members]
2929
M0: S1 → T0 ; name: <Node>
30-
M1: S1 → T0 ; name: <Node>
31-
M2: S2 → T0 ; item: <Node>
32-
M3: S3 → T3 ; items: T3
30+
M1: S2 → T1 ; item: Inner
31+
M2: S3 → T3 ; items: T3
3332

3433
[type_names]
3534
N0: S4 → T1 ; Inner
@@ -57,14 +56,14 @@ Outer:
5756
14 ! (parent) 15
5857
15 ε [Arr] 17
5958
17 ε 41, 29
60-
19 ε [EndArr Set(M3)] 21
59+
19 ε [EndArr Set(M2)] 21
6160
21 △ 27
6261
22 ε [EndObj Push] 24
6362
24 ε 47, 19
6463
26 ▶
6564
27 ε [EndObj] 26
66-
29 ε [EndArr Set(M3)] 27
67-
31 ε [Set(M2)] 22
65+
29 ε [EndArr Set(M2)] 27
66+
31 ε [Set(M1)] 22
6867
33 ! (Inner) 01 : 31
6968
34 ε [Obj] 33
7069
36 ▷ 39

crates/plotnik-lib/src/emit/snapshots/plotnik_lib__emit__codegen_tests__quantifiers_sequence_in_called_def.snap

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,14 @@ S8 "parent"
2222
[type_defs]
2323
T0 = <Node>
2424
T1 = Struct M0:1 ; { name }
25-
T2 = Struct M1:2 ; { name, item }
25+
T2 = Struct M1:1 ; { item }
2626
T3 = ArrayStar(T2) ; T2*
27-
T4 = Struct M3:1 ; { items }
27+
T4 = Struct M2:1 ; { items }
2828

2929
[type_members]
3030
M0: S1 → T0 ; name: <Node>
31-
M1: S1 → T0 ; name: <Node>
32-
M2: S2 → T0 ; item: <Node>
33-
M3: S3 → T3 ; items: T3
31+
M1: S2 → T1 ; item: Item
32+
M2: S3 → T3 ; items: T3
3433

3534
[type_names]
3635
N0: S4 → T1 ; Item
@@ -68,8 +67,8 @@ Test:
6867
23 ε 46, 28
6968
25 ▶
7069
26 ε [EndObj] 25
71-
28 ε [EndArr Set(M3)] 26
72-
30 ε [Set(M2)] 21
70+
28 ε [EndArr Set(M2)] 26
71+
30 ε [Set(M1)] 21
7372
32 ! (Item) 01 : 30
7473
33 ε [Obj] 32
7574
35 ▷ 38

0 commit comments

Comments
 (0)