@@ -179,7 +179,7 @@ pub async fn compute_merged_modules(module_graph: Vc<ModuleGraph>) -> Result<Vc<
179179 . collect :: < Result < Vec < _ > > > ( ) ?,
180180 & mut ( ) ,
181181 |parent_info : Option < ( ResolvedVc < Box < dyn Module > > , & ' _ RefData , _ ) > ,
182- node : ResolvedVc < Box < dyn Module > > ,
182+ module : ResolvedVc < Box < dyn Module > > ,
183183 _,
184184 _|
185185 -> Result < GraphTraversalAction > {
@@ -195,63 +195,70 @@ pub async fn compute_merged_modules(module_graph: Vc<ModuleGraph>) -> Result<Vc<
195195 } ,
196196 )
197197 } ) ;
198- let module = node;
199198
200- Ok ( if parent_module. is_some_and ( |p| p == module) {
201- // A self-reference
202- GraphTraversalAction :: Skip
203- } else if hoisted
204- && let Some ( parent_module) = parent_module
205- && mergeable. contains ( & parent_module)
206- && mergeable. contains ( & module)
207- && !async_modules. contains ( & parent_module)
208- && !async_modules. contains ( & module)
209- {
210- // ^ TODO technically we could merge a sync child into an async parent
211-
212- // A hoisted reference from a mergeable module to a non-async mergeable
213- // module, inherit bitmaps from parent.
214- module_merged_groups. entry ( node) . or_default ( ) ;
215- let [ Some ( parent_merged_groups) , Some ( current_merged_groups) ] =
216- module_merged_groups. get_disjoint_mut ( [ & parent_module, & node] )
217- else {
218- // All modules are inserted in the previous iteration
219- bail ! ( "unreachable except for eventual consistency" ) ;
220- } ;
221-
222- if current_merged_groups. is_empty ( ) {
223- // Initial visit, clone instead of merging
224- * current_merged_groups = parent_merged_groups. clone ( ) ;
225- GraphTraversalAction :: Continue
226- } else if parent_merged_groups. is_proper_superset ( current_merged_groups) {
227- // Add bits from parent, and continue traversal because changed
228- * * current_merged_groups |= & * * parent_merged_groups;
229- GraphTraversalAction :: Continue
199+ Ok (
200+ if hoisted
201+ && let Some ( parent_module) = parent_module
202+ && mergeable. contains ( & parent_module)
203+ && mergeable. contains ( & module)
204+ && !async_modules. contains ( & parent_module)
205+ && !async_modules. contains ( & module)
206+ {
207+ // ^ TODO technically we could merge a sync child into an async parent
208+ if parent_module == module {
209+ // A hoisted self-reference, no need to update bitmaps and don't recurse
210+ GraphTraversalAction :: Skip
211+ } else {
212+ // A hoisted reference from a mergeable module to a non-async mergeable
213+ // module, inherit bitmaps from parent.
214+ module_merged_groups. entry ( module) . or_default ( ) ;
215+ let [ Some ( parent_merged_groups) , Some ( current_merged_groups) ] =
216+ module_merged_groups. get_disjoint_mut ( [ & parent_module, & module] )
217+ else {
218+ // All modules are inserted in the previous iteration
219+ bail ! ( "unreachable except for eventual consistency" ) ;
220+ } ;
221+
222+ if current_merged_groups. is_empty ( ) {
223+ // Initial visit, clone instead of merging
224+ * current_merged_groups = parent_merged_groups. clone ( ) ;
225+ GraphTraversalAction :: Continue
226+ } else if parent_merged_groups. is_proper_superset ( current_merged_groups)
227+ {
228+ // Add bits from parent, and continue traversal because changed
229+ * * current_merged_groups |= & * * parent_merged_groups;
230+ GraphTraversalAction :: Continue
231+ } else {
232+ // Unchanged, no need to forward to children
233+ GraphTraversalAction :: Skip
234+ }
235+ }
230236 } else {
231- // Unchanged, no need to forward to children
232- GraphTraversalAction :: Skip
233- }
234- } else {
235- // Either a non-hoisted reference or an incompatible parent or child module
236-
237- if entry_modules. insert ( module) {
238- // Not assigned a new group before, create a new one.
239- let idx = next_index;
240- next_index += 1 ;
241-
242- if module_merged_groups. entry ( module) . or_default ( ) . insert ( idx) {
243- // Mark and continue traversal because modified (or first visit)
244- GraphTraversalAction :: Continue
237+ // Either a non-hoisted reference or an incompatible parent or child module
238+ if entry_modules. insert ( module) {
239+ // Not assigned a new group before, create a new one.
240+ let idx = next_index;
241+ next_index += 1 ;
242+
243+ if module_merged_groups. entry ( module) . or_default ( ) . insert ( idx) {
244+ if parent_module. is_some_and ( |p| p == module) {
245+ // A hoisted self-reference, don't recurse
246+ GraphTraversalAction :: Skip
247+ } else {
248+ // Mark and continue traversal because modified (or first visit)
249+ GraphTraversalAction :: Continue
250+ }
251+ } else {
252+ // Unchanged, no need to forward to children
253+ GraphTraversalAction :: Skip
254+ }
245255 } else {
246- // Unchanged, no need to forward to children
256+ // Already visited and assigned a new group, no need to forward to
257+ // children.
247258 GraphTraversalAction :: Skip
248259 }
249- } else {
250- // Already visited and assigned a new group, no need to forward to
251- // children.
252- GraphTraversalAction :: Skip
253- }
254- } )
260+ } ,
261+ )
255262 } ,
256263 |successor, _| {
257264 // Invert the ordering here. High priority values get visited first, and we want to
0 commit comments