@@ -167,7 +167,7 @@ pub async fn compute_merged_modules(module_graph: Vc<ModuleGraph>) -> Result<Vc<
167167 . collect :: < Result < Vec < _ > > > ( ) ?,
168168 & mut ( ) ,
169169 |parent_info : Option < ( ResolvedVc < Box < dyn Module > > , & ' _ RefData , _ ) > ,
170- node : ResolvedVc < Box < dyn Module > > ,
170+ module : ResolvedVc < Box < dyn Module > > ,
171171 _,
172172 _|
173173 -> Result < GraphTraversalAction > {
@@ -183,63 +183,70 @@ pub async fn compute_merged_modules(module_graph: Vc<ModuleGraph>) -> Result<Vc<
183183 } ,
184184 )
185185 } ) ;
186- let module = node;
187186
188- Ok ( if parent_module. is_some_and ( |p| p == module) {
189- // A self-reference
190- GraphTraversalAction :: Skip
191- } else if hoisted
192- && let Some ( parent_module) = parent_module
193- && mergeable. contains ( & parent_module)
194- && mergeable. contains ( & module)
195- && !async_module_info. contains ( & parent_module)
196- && !async_module_info. contains ( & module)
197- {
198- // ^ TODO technically we could merge a sync child into an async parent
199-
200- // A hoisted reference from a mergeable module to a non-async mergeable
201- // module, inherit bitmaps from parent.
202- module_merged_groups. entry ( node) . or_default ( ) ;
203- let [ Some ( parent_merged_groups) , Some ( current_merged_groups) ] =
204- module_merged_groups. get_disjoint_mut ( [ & parent_module, & node] )
205- else {
206- // All modules are inserted in the previous iteration
207- bail ! ( "unreachable except for eventual consistency" ) ;
208- } ;
209-
210- if current_merged_groups. is_empty ( ) {
211- // Initial visit, clone instead of merging
212- * current_merged_groups = parent_merged_groups. clone ( ) ;
213- GraphTraversalAction :: Continue
214- } else if parent_merged_groups. is_proper_superset ( current_merged_groups) {
215- // Add bits from parent, and continue traversal because changed
216- * * current_merged_groups |= & * * parent_merged_groups;
217- GraphTraversalAction :: Continue
187+ Ok (
188+ if hoisted
189+ && let Some ( parent_module) = parent_module
190+ && mergeable. contains ( & parent_module)
191+ && mergeable. contains ( & module)
192+ && !async_module_info. contains ( & parent_module)
193+ && !async_module_info. contains ( & module)
194+ {
195+ // ^ TODO technically we could merge a sync child into an async parent
196+ if parent_module == module {
197+ // A hoisted self-reference, no need to update bitmaps and don't recurse
198+ GraphTraversalAction :: Skip
199+ } else {
200+ // A hoisted reference from a mergeable module to a non-async mergeable
201+ // module, inherit bitmaps from parent.
202+ module_merged_groups. entry ( module) . or_default ( ) ;
203+ let [ Some ( parent_merged_groups) , Some ( current_merged_groups) ] =
204+ module_merged_groups. get_disjoint_mut ( [ & parent_module, & module] )
205+ else {
206+ // All modules are inserted in the previous iteration
207+ bail ! ( "unreachable except for eventual consistency" ) ;
208+ } ;
209+
210+ if current_merged_groups. is_empty ( ) {
211+ // Initial visit, clone instead of merging
212+ * current_merged_groups = parent_merged_groups. clone ( ) ;
213+ GraphTraversalAction :: Continue
214+ } else if parent_merged_groups. is_proper_superset ( current_merged_groups)
215+ {
216+ // Add bits from parent, and continue traversal because changed
217+ * * current_merged_groups |= & * * parent_merged_groups;
218+ GraphTraversalAction :: Continue
219+ } else {
220+ // Unchanged, no need to forward to children
221+ GraphTraversalAction :: Skip
222+ }
223+ }
218224 } else {
219- // Unchanged, no need to forward to children
220- GraphTraversalAction :: Skip
221- }
222- } else {
223- // Either a non-hoisted reference or an incompatible parent or child module
224-
225- if entry_modules. insert ( module) {
226- // Not assigned a new group before, create a new one.
227- let idx = next_index;
228- next_index += 1 ;
229-
230- if module_merged_groups. entry ( module) . or_default ( ) . insert ( idx) {
231- // Mark and continue traversal because modified (or first visit)
232- GraphTraversalAction :: Continue
225+ // Either a non-hoisted reference or an incompatible parent or child module
226+ if entry_modules. insert ( module) {
227+ // Not assigned a new group before, create a new one.
228+ let idx = next_index;
229+ next_index += 1 ;
230+
231+ if module_merged_groups. entry ( module) . or_default ( ) . insert ( idx) {
232+ if parent_module. is_some_and ( |p| p == module) {
233+ // A hoisted self-reference, don't recurse
234+ GraphTraversalAction :: Skip
235+ } else {
236+ // Mark and continue traversal because modified (or first visit)
237+ GraphTraversalAction :: Continue
238+ }
239+ } else {
240+ // Unchanged, no need to forward to children
241+ GraphTraversalAction :: Skip
242+ }
233243 } else {
234- // Unchanged, no need to forward to children
244+ // Already visited and assigned a new group, no need to forward to
245+ // children.
235246 GraphTraversalAction :: Skip
236247 }
237- } else {
238- // Already visited and assigned a new group, no need to forward to
239- // children.
240- GraphTraversalAction :: Skip
241- }
242- } )
248+ } ,
249+ )
243250 } ,
244251 |successor, _| {
245252 // Invert the ordering here. High priority values get visited first, and we want to
0 commit comments