@@ -13,6 +13,8 @@ import type {
1313  ReactDebugInfo , 
1414  ReactAsyncInfo , 
1515  ReactIOInfo , 
16+   ReactStackTrace , 
17+   ReactCallSite , 
1618}  from  'shared/ReactTypes' ; 
1719
1820import  type  { HooksTree }  from  'react-debug-tools/src/ReactDebugHooks' ; 
@@ -5274,6 +5276,72 @@ export function attach(
52745276    return result; 
52755277  } 
52765278
5279+   function getAwaitStackFromHooks( 
5280+     hooks: HooksTree, 
5281+     asyncInfo: ReactAsyncInfo, 
5282+   ): null | ReactStackTrace { 
5283+     // TODO: We search through the hooks tree generated by inspectHooksOfFiber so that we can 
5284+     // use the information already extracted but ideally this search would be faster since we 
5285+     // could know which index to extract from the debug state. 
5286+     for (let i = 0; i < hooks.length; i++) { 
5287+       const node = hooks[i]; 
5288+       const debugInfo = node.debugInfo; 
5289+       if (debugInfo != null && debugInfo.indexOf(asyncInfo) !== -1) { 
5290+         // Found a matching Hook. We'll now use its source location to construct a stack. 
5291+         const source = node.hookSource; 
5292+         if ( 
5293+           source != null && 
5294+           source.functionName !== null && 
5295+           source.fileName !== null && 
5296+           source.lineNumber !== null && 
5297+           source.columnNumber !== null 
5298+         ) { 
5299+           // Unfortunately this is in a slightly different format. TODO: Unify HookNode with ReactCallSite. 
5300+           const callSite: ReactCallSite = [ 
5301+             source.functionName, 
5302+             source.fileName, 
5303+             source.lineNumber, 
5304+             source.columnNumber, 
5305+             0, 
5306+             0, 
5307+             false, 
5308+           ]; 
5309+           // As we return we'll add any custom hooks parent stacks to the array. 
5310+           return [callSite]; 
5311+         } else { 
5312+           return []; 
5313+         } 
5314+       } 
5315+       // Otherwise, search the sub hooks of any custom hook. 
5316+       const matchedStack = getAwaitStackFromHooks(node.subHooks, asyncInfo); 
5317+       if (matchedStack !== null) { 
5318+         // Append this custom hook to the stack trace since it must have been called inside of it. 
5319+         const source = node.hookSource; 
5320+         if ( 
5321+           source != null && 
5322+           source.functionName !== null && 
5323+           source.fileName !== null && 
5324+           source.lineNumber !== null && 
5325+           source.columnNumber !== null 
5326+         ) { 
5327+           // Unfortunately this is in a slightly different format. TODO: Unify HookNode with ReactCallSite. 
5328+           const callSite: ReactCallSite = [ 
5329+             source.functionName, 
5330+             source.fileName, 
5331+             source.lineNumber, 
5332+             source.columnNumber, 
5333+             0, 
5334+             0, 
5335+             false, 
5336+           ]; 
5337+           matchedStack.push(callSite); 
5338+         } 
5339+         return matchedStack; 
5340+       } 
5341+     } 
5342+     return null; 
5343+   } 
5344+ 
52775345  function serializeAsyncInfo( 
52785346    asyncInfo: ReactAsyncInfo, 
52795347    parentInstance: DevToolsInstance, 
@@ -5317,6 +5385,11 @@ export function attach(
53175385            // If we awaited in the child position of a component, then the best stack would be the 
53185386            // return callsite but we don't have that available so instead we skip. The callsite of 
53195387            // the JSX would be misleading in this case. The same thing happens with throw-a-Promise. 
5388+             if (hooks !== null) { 
5389+               // If this component used Hooks we might be able to instead infer the stack from the 
5390+               // use() callsite if this async info came from a hook. Let's search the tree to find it. 
5391+               awaitStack = getAwaitStackFromHooks(hooks, asyncInfo); 
5392+             } 
53205393            break; 
53215394          default: 
53225395            // If we awaited by passing a Promise to a built-in element, then the JSX callsite is a 
0 commit comments