@@ -219,6 +219,7 @@ fn span_in_region(
219219 span_offset : u32 ,
220220 symbol_map : & SymbolMap ,
221221 var_name : & str ,
222+ all_regions : & [ Region ] ,
222223) -> bool {
223224 // Case 1: the span is the definition token of this region.
224225 if span_offset == region. def_offset {
@@ -236,8 +237,16 @@ fn span_in_region(
236237 // Compound assignments (+=, -=, .=, etc.) modify in place
237238 // and belong to the current region.
238239 Some ( VarDefKind :: CompoundAssignment ) => return true ,
239- // Any other definition kind starts its own region.
240- Some ( _) => { }
240+ // If this definition starts its own region, it doesn't
241+ // belong here. But if it was skipped by build_regions
242+ // (e.g. a deeper-nested conditional assignment), it
243+ // belongs to the enclosing region.
244+ Some ( _) => {
245+ let starts_own_region = all_regions. iter ( ) . any ( |r| r. def_offset == span_offset) ;
246+ if !starts_own_region {
247+ return true ;
248+ }
249+ }
241250 }
242251 }
243252
@@ -295,7 +304,7 @@ fn collect_variable_ranges_in_region(
295304 if span_scope != scope_start {
296305 continue ;
297306 }
298- if !span_in_region ( region, span. start , symbol_map, var_name) {
307+ if !span_in_region ( region, span. start , symbol_map, var_name, & regions ) {
299308 continue ;
300309 }
301310 if !seen_offsets. insert ( span. start ) {
@@ -327,6 +336,109 @@ fn collect_variable_ranges_in_region(
327336 }
328337 }
329338
339+ // ── Closure use() capture bridging ──────────────────────────────────
340+ //
341+ // When a variable is captured via `use ($var)`, renaming it must
342+ // propagate across both the outer scope (where the variable is
343+ // defined) and the inner closure scope (where it is used). The
344+ // `use ($var)` token sits physically in the outer scope but has a
345+ // `ClosureCapture` VarDefSite scoped to the closure body.
346+ //
347+ // Case A (cursor in outer scope): find ClosureCapture defs whose
348+ // offset falls within this region, then include all occurrences of
349+ // the variable inside each captured closure.
350+ //
351+ // Case B (cursor in closure scope): if the region's definition is
352+ // a ClosureCapture, bridge outward to the outer scope's region and
353+ // include those occurrences too.
354+
355+ // Case A: outer scope → closure bodies
356+ for def in & symbol_map. var_defs {
357+ if def. name == var_name
358+ && def. kind == VarDefKind :: ClosureCapture
359+ && span_in_region ( region, def. offset , symbol_map, var_name, & regions)
360+ {
361+ // The use() token itself (in outer scope) is already collected
362+ // above. Now collect all occurrences inside the closure body.
363+ let closure_scope = def. scope_start ;
364+ for span in & symbol_map. spans {
365+ if let SymbolKind :: Variable { name } = & span. kind {
366+ if name != var_name {
367+ continue ;
368+ }
369+ let ss = symbol_map. find_variable_scope ( name, span. start ) ;
370+ if ss != closure_scope {
371+ continue ;
372+ }
373+ if !seen_offsets. insert ( span. start ) {
374+ continue ;
375+ }
376+ ranges. push ( variable_range_without_sigil (
377+ content,
378+ span. start as usize ,
379+ span. end as usize ,
380+ ) ) ;
381+ }
382+ }
383+ }
384+ }
385+
386+ // Case B: closure scope → outer scope
387+ // Check if the current region's definition is a ClosureCapture.
388+ if let Some ( capture_def) = symbol_map. var_defs . iter ( ) . find ( |d| {
389+ d. name == var_name
390+ && d. kind == VarDefKind :: ClosureCapture
391+ && d. offset == region. def_offset
392+ && d. scope_start == scope_start
393+ } ) {
394+ // The use() token sits in the outer scope. Find which outer
395+ // region it belongs to and include all outer occurrences.
396+ let outer_scope = symbol_map. find_enclosing_scope ( capture_def. offset ) ;
397+ let outer_regions = build_regions ( symbol_map, var_name, outer_scope) ;
398+ if let Some ( outer_region) = outer_regions. iter ( ) . find ( |r| {
399+ capture_def. offset >= r. effective_from && capture_def. offset < r. reads_until
400+ || capture_def. offset == r. def_offset
401+ } ) {
402+ for span in & symbol_map. spans {
403+ if let SymbolKind :: Variable { name } = & span. kind {
404+ if name != var_name {
405+ continue ;
406+ }
407+ let ss = symbol_map. find_variable_scope ( name, span. start ) ;
408+ if ss != outer_scope {
409+ continue ;
410+ }
411+ if !span_in_region (
412+ outer_region,
413+ span. start ,
414+ symbol_map,
415+ var_name,
416+ & outer_regions,
417+ ) {
418+ continue ;
419+ }
420+ if !seen_offsets. insert ( span. start ) {
421+ continue ;
422+ }
423+ ranges. push ( variable_range_without_sigil (
424+ content,
425+ span. start as usize ,
426+ span. end as usize ,
427+ ) ) ;
428+ }
429+ }
430+ // Also include the outer region's def site if not yet seen.
431+ if seen_offsets. insert ( outer_region. def_offset ) {
432+ let end_offset = outer_region. def_offset + 1 + var_name. len ( ) as u32 ;
433+ ranges. push ( variable_range_without_sigil (
434+ content,
435+ outer_region. def_offset as usize ,
436+ end_offset as usize ,
437+ ) ) ;
438+ }
439+ }
440+ }
441+
330442 // Sort by position for a deterministic response.
331443 ranges. sort_by ( |a, b| {
332444 a. start
0 commit comments