@@ -55,7 +55,6 @@ use crate::graph::Symbol;
5555use crate :: paths:: Extend ;
5656use crate :: paths:: Path ;
5757use crate :: paths:: PathEdge ;
58- use crate :: paths:: PathEdgeList ;
5958use crate :: paths:: PathResolutionError ;
6059use crate :: paths:: Paths ;
6160use crate :: paths:: ScopeStack ;
@@ -2542,13 +2541,7 @@ impl Path {
25422541 partials : & mut PartialPaths ,
25432542 partial_path : & PartialPath ,
25442543 ) -> Option < Path > {
2545- let mut path = Path {
2546- start_node : partial_path. start_node ,
2547- end_node : partial_path. start_node ,
2548- symbol_stack : SymbolStack :: empty ( ) ,
2549- scope_stack : ScopeStack :: empty ( ) ,
2550- edges : PathEdgeList :: empty ( ) ,
2551- } ;
2544+ let mut path = Path :: from_node ( graph, paths, partial_path. start_node ) ?;
25522545 path. append_partial_path ( graph, paths, partials, partial_path)
25532546 . ok ( ) ?;
25542547 Some ( path)
@@ -2567,16 +2560,57 @@ impl Path {
25672560 return Err ( PathResolutionError :: IncorrectSourceNode ) ;
25682561 }
25692562
2563+ // If the join node operates on the stack, the effect is present in both sides.
2564+ // For correct joining, we must undo the effect on one of the sides. We match
2565+ // the end node of the lhs, and the start node of the rhs separately, depending
2566+ // on whether we must manipulate the lhs postcondition or rhs precondition,
2567+ // respectively. The reason we cannot use only one of the lhs end or rhs start
2568+ // node is that the variables used in them may differ.
2569+ let mut lhs_symbol_stack = self . symbol_stack ;
2570+ let lhs_scope_stack = self . scope_stack ;
2571+ let mut rhs_symbol_stack_precondition = partial_path. symbol_stack_precondition ;
2572+ let mut rhs_scope_stack_precondition = partial_path. scope_stack_precondition ;
2573+ match & graph[ self . end_node ] {
2574+ Node :: DropScopes ( _) => { }
2575+ Node :: JumpTo ( _) => { }
2576+ Node :: PopScopedSymbol ( _) => { }
2577+ Node :: PopSymbol ( _) => { }
2578+ Node :: PushScopedSymbol ( _) => {
2579+ lhs_symbol_stack. pop_front ( paths) . unwrap ( ) ;
2580+ }
2581+ Node :: PushSymbol ( _) => {
2582+ lhs_symbol_stack. pop_front ( paths) . unwrap ( ) ;
2583+ }
2584+ Node :: Root ( _) => { }
2585+ Node :: Scope ( _) => { }
2586+ }
2587+ match & graph[ partial_path. start_node ] {
2588+ Node :: DropScopes ( _) => {
2589+ rhs_scope_stack_precondition = PartialScopeStack :: empty ( ) ;
2590+ }
2591+ Node :: JumpTo ( _) => { }
2592+ Node :: PopScopedSymbol ( _) => {
2593+ let symbol = rhs_symbol_stack_precondition. pop_front ( partials) . unwrap ( ) ;
2594+ rhs_scope_stack_precondition = symbol. scopes . into_option ( ) . unwrap ( ) ;
2595+ }
2596+ Node :: PopSymbol ( _) => {
2597+ rhs_symbol_stack_precondition. pop_front ( partials) . unwrap ( ) ;
2598+ }
2599+ Node :: PushScopedSymbol ( _) => { }
2600+ Node :: PushSymbol ( _) => { }
2601+ Node :: Root ( _) => { }
2602+ Node :: Scope ( _) => { }
2603+ }
2604+
25702605 let mut symbol_bindings = SymbolStackBindings :: new ( ) ;
25712606 let mut scope_bindings = ScopeStackBindings :: new ( ) ;
2572- partial_path
2573- . scope_stack_precondition
2574- . match_stack ( self . scope_stack , & mut scope_bindings) ?;
2575- partial_path. symbol_stack_precondition . match_stack (
2607+
2608+ rhs_scope_stack_precondition. match_stack ( lhs_scope_stack, & mut scope_bindings) ?;
2609+ rhs_symbol_stack_precondition. match_stack (
25762610 graph,
25772611 paths,
25782612 partials,
2579- self . symbol_stack ,
2613+ lhs_symbol_stack ,
25802614 & mut symbol_bindings,
25812615 & mut scope_bindings,
25822616 ) ?;
0 commit comments