From f46450fab91ee25b0eb7e7521e9162d35048a205 Mon Sep 17 00:00:00 2001
From: Jack Pope <jackpope1@gmail.com>
Date: Fri, 13 Dec 2024 15:55:23 -0500
Subject: [PATCH 1/3] Revert "Fix unstable_useContextWithBailout dispatcher
 assignment (#30692)"

This reverts commit 0ad0fac1dc11db8d5a6831987fb0324cd6d59498.
---
 packages/react-reconciler/src/ReactFiberHooks.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/react-reconciler/src/ReactFiberHooks.js b/packages/react-reconciler/src/ReactFiberHooks.js
index 8affe4804b8ab..518bc6ae24382 100644
--- a/packages/react-reconciler/src/ReactFiberHooks.js
+++ b/packages/react-reconciler/src/ReactFiberHooks.js
@@ -4891,7 +4891,7 @@ if (__DEV__) {
       };
   }
   if (enableContextProfiling) {
-    (HooksDispatcherOnRerenderInDEV: Dispatcher).unstable_useContextWithBailout =
+    (HooksDispatcherOnUpdateInDEV: Dispatcher).unstable_useContextWithBailout =
       function <T>(
         context: ReactContext<T>,
         select: (T => Array<mixed>) | null,

From 693d4717a0089aec36ea6c592208f24a9ac0c64e Mon Sep 17 00:00:00 2001
From: Jack Pope <jackpope1@gmail.com>
Date: Fri, 13 Dec 2024 15:55:40 -0500
Subject: [PATCH 2/3] Revert "Fix unstable_useContextWithBailout incorrect
 dispatcher assignment (#30673)"

This reverts commit d48603a52564675ce02152fff245e38b6816da47.
---
 packages/react-reconciler/src/ReactFiberHooks.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/react-reconciler/src/ReactFiberHooks.js b/packages/react-reconciler/src/ReactFiberHooks.js
index 518bc6ae24382..64ddc88fd6ab2 100644
--- a/packages/react-reconciler/src/ReactFiberHooks.js
+++ b/packages/react-reconciler/src/ReactFiberHooks.js
@@ -5115,7 +5115,7 @@ if (__DEV__) {
       };
   }
   if (enableContextProfiling) {
-    (InvalidNestedHooksDispatcherOnMountInDEV: Dispatcher).unstable_useContextWithBailout =
+    (HooksDispatcherOnUpdateInDEV: Dispatcher).unstable_useContextWithBailout =
       function <T>(
         context: ReactContext<T>,
         select: (T => Array<mixed>) | null,

From 1471fa09b7f4370b1c6c4540dc549d5a1aae1489 Mon Sep 17 00:00:00 2001
From: Jack Pope <jackpope1@gmail.com>
Date: Fri, 13 Dec 2024 16:03:33 -0500
Subject: [PATCH 3/3] Revert "Add unstable context bailout for profiling
 (#30407)"

This reverts commit 1350a85980d1bf5e63c16a4a889861246f4cc107.
---
 .../react-debug-tools/src/ReactDebugHooks.js  |  30 +--
 .../react-reconciler/src/ReactFiberHooks.js   | 115 +---------
 .../src/ReactFiberNewContext.js               | 137 +----------
 .../src/ReactInternalTypes.js                 |  27 +--
 .../__tests__/ReactContextWithBailout-test.js | 217 ------------------
 packages/react/index.fb.js                    |   1 -
 packages/react/src/ReactClient.js             |   2 -
 packages/react/src/ReactHooks.js              |  25 --
 packages/shared/ReactFeatureFlags.js          |   3 -
 .../forks/ReactFeatureFlags.native-fb.js      |   1 -
 .../forks/ReactFeatureFlags.native-oss.js     |   1 -
 .../forks/ReactFeatureFlags.test-renderer.js  |   1 -
 .../ReactFeatureFlags.test-renderer.www.js    |   1 -
 .../shared/forks/ReactFeatureFlags.www.js     |   2 -
 scripts/error-codes/codes.json                |   1 -
 15 files changed, 16 insertions(+), 548 deletions(-)
 delete mode 100644 packages/react-reconciler/src/__tests__/ReactContextWithBailout-test.js

diff --git a/packages/react-debug-tools/src/ReactDebugHooks.js b/packages/react-debug-tools/src/ReactDebugHooks.js
index eccaa6a67b166..d2cea81f576c4 100644
--- a/packages/react-debug-tools/src/ReactDebugHooks.js
+++ b/packages/react-debug-tools/src/ReactDebugHooks.js
@@ -20,7 +20,6 @@ import type {
   Dependencies,
   Fiber,
   Dispatcher as DispatcherType,
-  ContextDependencyWithSelect,
 } from 'react-reconciler/src/ReactInternalTypes';
 import type {TransitionStatus} from 'react-reconciler/src/ReactFiberConfig';
 
@@ -76,13 +75,6 @@ function getPrimitiveStackCache(): Map<string, Array<any>> {
     try {
       // Use all hooks here to add them to the hook log.
       Dispatcher.useContext(({_currentValue: null}: any));
-      if (typeof Dispatcher.unstable_useContextWithBailout === 'function') {
-        // This type check is for Flow only.
-        Dispatcher.unstable_useContextWithBailout(
-          ({_currentValue: null}: any),
-          null,
-        );
-      }
       Dispatcher.useState(null);
       Dispatcher.useReducer((s: mixed, a: mixed) => s, null);
       Dispatcher.useRef(null);
@@ -150,10 +142,7 @@ function getPrimitiveStackCache(): Map<string, Array<any>> {
 
 let currentFiber: null | Fiber = null;
 let currentHook: null | Hook = null;
-let currentContextDependency:
-  | null
-  | ContextDependency<mixed>
-  | ContextDependencyWithSelect<mixed> = null;
+let currentContextDependency: null | ContextDependency<mixed> = null;
 
 function nextHook(): null | Hook {
   const hook = currentHook;
@@ -274,22 +263,6 @@ function useContext<T>(context: ReactContext<T>): T {
   return value;
 }
 
-function unstable_useContextWithBailout<T>(
-  context: ReactContext<T>,
-  select: (T => Array<mixed>) | null,
-): T {
-  const value = readContext(context);
-  hookLog.push({
-    displayName: context.displayName || null,
-    primitive: 'ContextWithBailout',
-    stackError: new Error(),
-    value: value,
-    debugInfo: null,
-    dispatcherHookName: 'ContextWithBailout',
-  });
-  return value;
-}
-
 function useState<S>(
   initialState: (() => S) | S,
 ): [S, Dispatch<BasicStateAction<S>>] {
@@ -764,7 +737,6 @@ const Dispatcher: DispatcherType = {
   useCacheRefresh,
   useCallback,
   useContext,
-  unstable_useContextWithBailout,
   useEffect,
   useImperativeHandle,
   useDebugValue,
diff --git a/packages/react-reconciler/src/ReactFiberHooks.js b/packages/react-reconciler/src/ReactFiberHooks.js
index 64ddc88fd6ab2..771b60cbb0894 100644
--- a/packages/react-reconciler/src/ReactFiberHooks.js
+++ b/packages/react-reconciler/src/ReactFiberHooks.js
@@ -39,12 +39,11 @@ import {
   enableLazyContextPropagation,
   enableTransitionTracing,
   enableUseEffectEventHook,
+  enableUseResourceEffectHook,
   enableLegacyCache,
   debugRenderPhaseSideEffectsForStrictMode,
   disableLegacyMode,
   enableNoCloningMemoCache,
-  enableContextProfiling,
-  enableUseResourceEffectHook,
 } from 'shared/ReactFeatureFlags';
 import {
   REACT_CONTEXT_TYPE,
@@ -78,11 +77,7 @@ import {
   ContinuousEventPriority,
   higherEventPriority,
 } from './ReactEventPriorities';
-import {
-  readContext,
-  readContextAndCompare,
-  checkIfContextChanged,
-} from './ReactFiberNewContext';
+import {readContext, checkIfContextChanged} from './ReactFiberNewContext';
 import {HostRoot, CacheComponent, HostComponent} from './ReactWorkTags';
 import {
   LayoutStatic as LayoutStaticEffect,
@@ -1111,16 +1106,6 @@ function updateWorkInProgressHook(): Hook {
   return workInProgressHook;
 }
 
-function unstable_useContextWithBailout<T>(
-  context: ReactContext<T>,
-  select: (T => Array<mixed>) | null,
-): T {
-  if (select === null) {
-    return readContext(context);
-  }
-  return readContextAndCompare(context, select);
-}
-
 function createFunctionComponentUpdateQueue(): FunctionComponentUpdateQueue {
   return {
     lastEffect: null,
@@ -3958,10 +3943,6 @@ if (enableUseEffectEventHook) {
 if (enableUseResourceEffectHook) {
   (ContextOnlyDispatcher: Dispatcher).useResourceEffect = throwInvalidHookError;
 }
-if (enableContextProfiling) {
-  (ContextOnlyDispatcher: Dispatcher).unstable_useContextWithBailout =
-    throwInvalidHookError;
-}
 
 const HooksDispatcherOnMount: Dispatcher = {
   readContext,
@@ -3995,10 +3976,6 @@ if (enableUseEffectEventHook) {
 if (enableUseResourceEffectHook) {
   (HooksDispatcherOnMount: Dispatcher).useResourceEffect = mountResourceEffect;
 }
-if (enableContextProfiling) {
-  (HooksDispatcherOnMount: Dispatcher).unstable_useContextWithBailout =
-    unstable_useContextWithBailout;
-}
 
 const HooksDispatcherOnUpdate: Dispatcher = {
   readContext,
@@ -4033,10 +4010,6 @@ if (enableUseResourceEffectHook) {
   (HooksDispatcherOnUpdate: Dispatcher).useResourceEffect =
     updateResourceEffect;
 }
-if (enableContextProfiling) {
-  (HooksDispatcherOnUpdate: Dispatcher).unstable_useContextWithBailout =
-    unstable_useContextWithBailout;
-}
 
 const HooksDispatcherOnRerender: Dispatcher = {
   readContext,
@@ -4071,10 +4044,6 @@ if (enableUseResourceEffectHook) {
   (HooksDispatcherOnRerender: Dispatcher).useResourceEffect =
     updateResourceEffect;
 }
-if (enableContextProfiling) {
-  (HooksDispatcherOnRerender: Dispatcher).unstable_useContextWithBailout =
-    unstable_useContextWithBailout;
-}
 
 let HooksDispatcherOnMountInDEV: Dispatcher | null = null;
 let HooksDispatcherOnMountWithHookTypesInDEV: Dispatcher | null = null;
@@ -4296,17 +4265,6 @@ if (__DEV__) {
         );
       };
   }
-  if (enableContextProfiling) {
-    (HooksDispatcherOnMountInDEV: Dispatcher).unstable_useContextWithBailout =
-      function <T>(
-        context: ReactContext<T>,
-        select: (T => Array<mixed>) | null,
-      ): T {
-        currentHookNameInDev = 'useContext';
-        mountHookTypesDev();
-        return unstable_useContextWithBailout(context, select);
-      };
-  }
 
   HooksDispatcherOnMountWithHookTypesInDEV = {
     readContext<T>(context: ReactContext<T>): T {
@@ -4494,17 +4452,6 @@ if (__DEV__) {
         );
       };
   }
-  if (enableContextProfiling) {
-    (HooksDispatcherOnMountWithHookTypesInDEV: Dispatcher).unstable_useContextWithBailout =
-      function <T>(
-        context: ReactContext<T>,
-        select: (T => Array<mixed>) | null,
-      ): T {
-        currentHookNameInDev = 'useContext';
-        updateHookTypesDev();
-        return unstable_useContextWithBailout(context, select);
-      };
-  }
 
   HooksDispatcherOnUpdateInDEV = {
     readContext<T>(context: ReactContext<T>): T {
@@ -4692,17 +4639,6 @@ if (__DEV__) {
         );
       };
   }
-  if (enableContextProfiling) {
-    (HooksDispatcherOnUpdateInDEV: Dispatcher).unstable_useContextWithBailout =
-      function <T>(
-        context: ReactContext<T>,
-        select: (T => Array<mixed>) | null,
-      ): T {
-        currentHookNameInDev = 'useContext';
-        updateHookTypesDev();
-        return unstable_useContextWithBailout(context, select);
-      };
-  }
 
   HooksDispatcherOnRerenderInDEV = {
     readContext<T>(context: ReactContext<T>): T {
@@ -4890,17 +4826,6 @@ if (__DEV__) {
         );
       };
   }
-  if (enableContextProfiling) {
-    (HooksDispatcherOnUpdateInDEV: Dispatcher).unstable_useContextWithBailout =
-      function <T>(
-        context: ReactContext<T>,
-        select: (T => Array<mixed>) | null,
-      ): T {
-        currentHookNameInDev = 'useContext';
-        updateHookTypesDev();
-        return unstable_useContextWithBailout(context, select);
-      };
-  }
 
   InvalidNestedHooksDispatcherOnMountInDEV = {
     readContext<T>(context: ReactContext<T>): T {
@@ -5114,18 +5039,6 @@ if (__DEV__) {
         );
       };
   }
-  if (enableContextProfiling) {
-    (HooksDispatcherOnUpdateInDEV: Dispatcher).unstable_useContextWithBailout =
-      function <T>(
-        context: ReactContext<T>,
-        select: (T => Array<mixed>) | null,
-      ): T {
-        currentHookNameInDev = 'useContext';
-        warnInvalidHookAccess();
-        mountHookTypesDev();
-        return unstable_useContextWithBailout(context, select);
-      };
-  }
 
   InvalidNestedHooksDispatcherOnUpdateInDEV = {
     readContext<T>(context: ReactContext<T>): T {
@@ -5339,18 +5252,6 @@ if (__DEV__) {
         );
       };
   }
-  if (enableContextProfiling) {
-    (InvalidNestedHooksDispatcherOnUpdateInDEV: Dispatcher).unstable_useContextWithBailout =
-      function <T>(
-        context: ReactContext<T>,
-        select: (T => Array<mixed>) | null,
-      ): T {
-        currentHookNameInDev = 'useContext';
-        warnInvalidHookAccess();
-        updateHookTypesDev();
-        return unstable_useContextWithBailout(context, select);
-      };
-  }
 
   InvalidNestedHooksDispatcherOnRerenderInDEV = {
     readContext<T>(context: ReactContext<T>): T {
@@ -5564,16 +5465,4 @@ if (__DEV__) {
         );
       };
   }
-  if (enableContextProfiling) {
-    (InvalidNestedHooksDispatcherOnRerenderInDEV: Dispatcher).unstable_useContextWithBailout =
-      function <T>(
-        context: ReactContext<T>,
-        select: (T => Array<mixed>) | null,
-      ): T {
-        currentHookNameInDev = 'useContext';
-        warnInvalidHookAccess();
-        updateHookTypesDev();
-        return unstable_useContextWithBailout(context, select);
-      };
-  }
 }
diff --git a/packages/react-reconciler/src/ReactFiberNewContext.js b/packages/react-reconciler/src/ReactFiberNewContext.js
index 190475519e1ca..6a779cfd4ab4c 100644
--- a/packages/react-reconciler/src/ReactFiberNewContext.js
+++ b/packages/react-reconciler/src/ReactFiberNewContext.js
@@ -12,7 +12,6 @@ import type {
   Fiber,
   ContextDependency,
   Dependencies,
-  ContextDependencyWithSelect,
 } from './ReactInternalTypes';
 import type {StackCursor} from './ReactFiberStack';
 import type {Lanes} from './ReactFiberLane';
@@ -48,8 +47,6 @@ import {
   enableRenderableContext,
 } from 'shared/ReactFeatureFlags';
 import {getHostTransitionProvider} from './ReactFiberHostContext';
-import isArray from '../../shared/isArray';
-import {enableContextProfiling} from '../../shared/ReactFeatureFlags';
 
 const valueCursor: StackCursor<mixed> = createCursor(null);
 
@@ -69,10 +66,7 @@ if (__DEV__) {
 }
 
 let currentlyRenderingFiber: Fiber | null = null;
-let lastContextDependency:
-  | ContextDependency<mixed>
-  | ContextDependencyWithSelect<mixed>
-  | null = null;
+let lastContextDependency: ContextDependency<mixed> | null = null;
 
 let isDisallowedContextReadInDEV: boolean = false;
 
@@ -401,23 +395,6 @@ function propagateContextChanges<T>(
           const context: ReactContext<T> = contexts[i];
           // Check if the context matches.
           if (dependency.context === context) {
-            if (enableContextProfiling) {
-              const select = dependency.select;
-              if (select != null && dependency.lastSelectedValue != null) {
-                const newValue = isPrimaryRenderer
-                  ? dependency.context._currentValue
-                  : dependency.context._currentValue2;
-                if (
-                  !checkIfSelectedContextValuesChanged(
-                    dependency.lastSelectedValue,
-                    select(newValue),
-                  )
-                ) {
-                  // Compared value hasn't changed. Bail out early.
-                  continue findContext;
-                }
-              }
-            }
             // Match! Schedule an update on this fiber.
 
             // In the lazy implementation, don't mark a dirty flag on the
@@ -657,29 +634,6 @@ function propagateParentContextChanges(
   workInProgress.flags |= DidPropagateContext;
 }
 
-function checkIfSelectedContextValuesChanged(
-  oldComparedValue: Array<mixed>,
-  newComparedValue: Array<mixed>,
-): boolean {
-  // We have an implicit contract that compare functions must return arrays.
-  // This allows us to compare multiple values in the same context access
-  // since compiling to additional hook calls regresses perf.
-  if (isArray(oldComparedValue) && isArray(newComparedValue)) {
-    if (oldComparedValue.length !== newComparedValue.length) {
-      return true;
-    }
-
-    for (let i = 0; i < oldComparedValue.length; i++) {
-      if (!is(newComparedValue[i], oldComparedValue[i])) {
-        return true;
-      }
-    }
-  } else {
-    throw new Error('Compared context values must be arrays');
-  }
-  return false;
-}
-
 export function checkIfContextChanged(
   currentDependencies: Dependencies,
 ): boolean {
@@ -698,23 +652,8 @@ export function checkIfContextChanged(
       ? context._currentValue
       : context._currentValue2;
     const oldValue = dependency.memoizedValue;
-    if (
-      enableContextProfiling &&
-      dependency.select != null &&
-      dependency.lastSelectedValue != null
-    ) {
-      if (
-        checkIfSelectedContextValuesChanged(
-          dependency.lastSelectedValue,
-          dependency.select(newValue),
-        )
-      ) {
-        return true;
-      }
-    } else {
-      if (!is(newValue, oldValue)) {
-        return true;
-      }
+    if (!is(newValue, oldValue)) {
+      return true;
     }
     dependency = dependency.next;
   }
@@ -747,21 +686,6 @@ export function prepareToReadContext(
   }
 }
 
-export function readContextAndCompare<C>(
-  context: ReactContext<C>,
-  select: C => Array<mixed>,
-): C {
-  if (!(enableLazyContextPropagation && enableContextProfiling)) {
-    throw new Error('Not implemented.');
-  }
-
-  return readContextForConsumer_withSelect(
-    currentlyRenderingFiber,
-    context,
-    select,
-  );
-}
-
 export function readContext<T>(context: ReactContext<T>): T {
   if (__DEV__) {
     // This warning would fire if you read context inside a Hook like useMemo.
@@ -789,59 +713,10 @@ export function readContextDuringReconciliation<T>(
   return readContextForConsumer(consumer, context);
 }
 
-function readContextForConsumer_withSelect<C>(
-  consumer: Fiber | null,
-  context: ReactContext<C>,
-  select: C => Array<mixed>,
-): C {
-  const value = isPrimaryRenderer
-    ? context._currentValue
-    : context._currentValue2;
-
-  const contextItem = {
-    context: ((context: any): ReactContext<mixed>),
-    memoizedValue: value,
-    next: null,
-    select: ((select: any): (context: mixed) => Array<mixed>),
-    lastSelectedValue: select(value),
-  };
-
-  if (lastContextDependency === null) {
-    if (consumer === null) {
-      throw new Error(
-        'Context can only be read while React is rendering. ' +
-          'In classes, you can read it in the render method or getDerivedStateFromProps. ' +
-          'In function components, you can read it directly in the function body, but not ' +
-          'inside Hooks like useReducer() or useMemo().',
-      );
-    }
-
-    // This is the first dependency for this component. Create a new list.
-    lastContextDependency = contextItem;
-    consumer.dependencies = __DEV__
-      ? {
-          lanes: NoLanes,
-          firstContext: contextItem,
-          _debugThenableState: null,
-        }
-      : {
-          lanes: NoLanes,
-          firstContext: contextItem,
-        };
-    if (enableLazyContextPropagation) {
-      consumer.flags |= NeedsPropagation;
-    }
-  } else {
-    // Append a new context item.
-    lastContextDependency = lastContextDependency.next = contextItem;
-  }
-  return value;
-}
-
-function readContextForConsumer<C>(
+function readContextForConsumer<T>(
   consumer: Fiber | null,
-  context: ReactContext<C>,
-): C {
+  context: ReactContext<T>,
+): T {
   const value = isPrimaryRenderer
     ? context._currentValue
     : context._currentValue2;
diff --git a/packages/react-reconciler/src/ReactInternalTypes.js b/packages/react-reconciler/src/ReactInternalTypes.js
index 2ef3a2da4f535..afe853202f141 100644
--- a/packages/react-reconciler/src/ReactInternalTypes.js
+++ b/packages/react-reconciler/src/ReactInternalTypes.js
@@ -63,27 +63,18 @@ export type HookType =
   | 'useFormState'
   | 'useActionState';
 
-export type ContextDependency<C> = {
-  context: ReactContext<C>,
-  next: ContextDependency<mixed> | ContextDependencyWithSelect<mixed> | null,
-  memoizedValue: C,
-};
-
-export type ContextDependencyWithSelect<C> = {
-  context: ReactContext<C>,
-  next: ContextDependency<mixed> | ContextDependencyWithSelect<mixed> | null,
-  memoizedValue: C,
-  select: C => Array<mixed>,
-  lastSelectedValue: ?Array<mixed>,
+export type ContextDependency<T> = {
+  context: ReactContext<T>,
+  next: ContextDependency<mixed> | null,
+  memoizedValue: T,
+  ...
 };
 
 export type Dependencies = {
   lanes: Lanes,
-  firstContext:
-    | ContextDependency<mixed>
-    | ContextDependencyWithSelect<mixed>
-    | null,
+  firstContext: ContextDependency<mixed> | null,
   _debugThenableState?: null | ThenableState, // DEV-only
+  ...
 };
 
 export type MemoCache = {
@@ -401,10 +392,6 @@ export type Dispatcher = {
     initialArg: I,
     init?: (I) => S,
   ): [S, Dispatch<A>],
-  unstable_useContextWithBailout?: <T>(
-    context: ReactContext<T>,
-    select: (T => Array<mixed>) | null,
-  ) => T,
   useContext<T>(context: ReactContext<T>): T,
   useRef<T>(initialValue: T): {current: T},
   useEffect(
diff --git a/packages/react-reconciler/src/__tests__/ReactContextWithBailout-test.js b/packages/react-reconciler/src/__tests__/ReactContextWithBailout-test.js
deleted file mode 100644
index c510206148b16..0000000000000
--- a/packages/react-reconciler/src/__tests__/ReactContextWithBailout-test.js
+++ /dev/null
@@ -1,217 +0,0 @@
-let React;
-let ReactNoop;
-let Scheduler;
-let act;
-let assertLog;
-let useState;
-let useContext;
-let unstable_useContextWithBailout;
-
-describe('ReactContextWithBailout', () => {
-  beforeEach(() => {
-    jest.resetModules();
-
-    React = require('react');
-    ReactNoop = require('react-noop-renderer');
-    Scheduler = require('scheduler');
-    const testUtils = require('internal-test-utils');
-    act = testUtils.act;
-    assertLog = testUtils.assertLog;
-    useState = React.useState;
-    useContext = React.useContext;
-    unstable_useContextWithBailout = React.unstable_useContextWithBailout;
-  });
-
-  function Text({text}) {
-    Scheduler.log(text);
-    return text;
-  }
-
-  // @gate enableLazyContextPropagation && enableContextProfiling
-  test('unstable_useContextWithBailout basic usage', async () => {
-    const Context = React.createContext();
-
-    let setContext;
-    function App() {
-      const [context, _setContext] = useState({a: 'A0', b: 'B0', c: 'C0'});
-      setContext = _setContext;
-      return (
-        <Context.Provider value={context}>
-          <Indirection />
-        </Context.Provider>
-      );
-    }
-
-    // Intermediate parent that bails out. Children will only re-render when the
-    // context changes.
-    const Indirection = React.memo(() => {
-      return (
-        <>
-          A: <A />, B: <B />, C: <C />, AB: <AB />
-        </>
-      );
-    });
-
-    function A() {
-      const {a} = unstable_useContextWithBailout(Context, context => [
-        context.a,
-      ]);
-      return <Text text={a} />;
-    }
-
-    function B() {
-      const {b} = unstable_useContextWithBailout(Context, context => [
-        context.b,
-      ]);
-      return <Text text={b} />;
-    }
-
-    function C() {
-      const {c} = unstable_useContextWithBailout(Context, context => [
-        context.c,
-      ]);
-      return <Text text={c} />;
-    }
-
-    function AB() {
-      const {a, b} = unstable_useContextWithBailout(Context, context => [
-        context.a,
-        context.b,
-      ]);
-      return <Text text={a + b} />;
-    }
-
-    const root = ReactNoop.createRoot();
-    await act(async () => {
-      root.render(<App />);
-    });
-    assertLog(['A0', 'B0', 'C0', 'A0B0']);
-    expect(root).toMatchRenderedOutput('A: A0, B: B0, C: C0, AB: A0B0');
-
-    // Update a. Only the A and AB consumer should re-render.
-    await act(async () => {
-      setContext({a: 'A1', c: 'C0', b: 'B0'});
-    });
-    assertLog(['A1', 'A1B0']);
-    expect(root).toMatchRenderedOutput('A: A1, B: B0, C: C0, AB: A1B0');
-
-    // Update b. Only the B and AB consumer should re-render.
-    await act(async () => {
-      setContext({a: 'A1', b: 'B1', c: 'C0'});
-    });
-    assertLog(['B1', 'A1B1']);
-    expect(root).toMatchRenderedOutput('A: A1, B: B1, C: C0, AB: A1B1');
-
-    // Update c. Only the C consumer should re-render.
-    await act(async () => {
-      setContext({a: 'A1', b: 'B1', c: 'C1'});
-    });
-    assertLog(['C1']);
-    expect(root).toMatchRenderedOutput('A: A1, B: B1, C: C1, AB: A1B1');
-  });
-
-  // @gate enableLazyContextPropagation && enableContextProfiling
-  test('unstable_useContextWithBailout and useContext subscribing to same context in same component', async () => {
-    const Context = React.createContext();
-
-    let setContext;
-    function App() {
-      const [context, _setContext] = useState({a: 0, b: 0, unrelated: 0});
-      setContext = _setContext;
-      return (
-        <Context.Provider value={context}>
-          <Indirection />
-        </Context.Provider>
-      );
-    }
-
-    // Intermediate parent that bails out. Children will only re-render when the
-    // context changes.
-    const Indirection = React.memo(() => {
-      return <Child />;
-    });
-
-    function Child() {
-      const {a} = unstable_useContextWithBailout(Context, context => [
-        context.a,
-      ]);
-      const context = useContext(Context);
-      return <Text text={`A: ${a}, B: ${context.b}`} />;
-    }
-
-    const root = ReactNoop.createRoot();
-    await act(async () => {
-      root.render(<App />);
-    });
-    assertLog(['A: 0, B: 0']);
-    expect(root).toMatchRenderedOutput('A: 0, B: 0');
-
-    // Update an unrelated field that isn't used by the component. The context
-    // attempts to bail out, but the normal context forces an update.
-    await act(async () => {
-      setContext({a: 0, b: 0, unrelated: 1});
-    });
-    assertLog(['A: 0, B: 0']);
-    expect(root).toMatchRenderedOutput('A: 0, B: 0');
-  });
-
-  // @gate enableLazyContextPropagation && enableContextProfiling
-  test('unstable_useContextWithBailout and useContext subscribing to different contexts in same component', async () => {
-    const ContextA = React.createContext();
-    const ContextB = React.createContext();
-
-    let setContextA;
-    let setContextB;
-    function App() {
-      const [a, _setContextA] = useState({a: 0, unrelated: 0});
-      const [b, _setContextB] = useState(0);
-      setContextA = _setContextA;
-      setContextB = _setContextB;
-      return (
-        <ContextA.Provider value={a}>
-          <ContextB.Provider value={b}>
-            <Indirection />
-          </ContextB.Provider>
-        </ContextA.Provider>
-      );
-    }
-
-    // Intermediate parent that bails out. Children will only re-render when the
-    // context changes.
-    const Indirection = React.memo(() => {
-      return <Child />;
-    });
-
-    function Child() {
-      const {a} = unstable_useContextWithBailout(ContextA, context => [
-        context.a,
-      ]);
-      const b = useContext(ContextB);
-      return <Text text={`A: ${a}, B: ${b}`} />;
-    }
-
-    const root = ReactNoop.createRoot();
-    await act(async () => {
-      root.render(<App />);
-    });
-    assertLog(['A: 0, B: 0']);
-    expect(root).toMatchRenderedOutput('A: 0, B: 0');
-
-    // Update a field in A that isn't part of the compared context. It should
-    // bail out.
-    await act(async () => {
-      setContextA({a: 0, unrelated: 1});
-    });
-    assertLog([]);
-    expect(root).toMatchRenderedOutput('A: 0, B: 0');
-
-    // Now update the same a field again, but this time, also update a different
-    // context in the same batch. The other context prevents a bail out.
-    await act(async () => {
-      setContextA({a: 0, unrelated: 1});
-      setContextB(1);
-    });
-    assertLog(['A: 0, B: 1']);
-    expect(root).toMatchRenderedOutput('A: 0, B: 1');
-  });
-});
diff --git a/packages/react/index.fb.js b/packages/react/index.fb.js
index 8cded91b9854d..84128cf0ea5d9 100644
--- a/packages/react/index.fb.js
+++ b/packages/react/index.fb.js
@@ -42,7 +42,6 @@ export {
   use,
   useActionState,
   useCallback,
-  unstable_useContextWithBailout,
   useContext,
   useDebugValue,
   useDeferredValue,
diff --git a/packages/react/src/ReactClient.js b/packages/react/src/ReactClient.js
index 90ce18b133a34..02625e3af91c5 100644
--- a/packages/react/src/ReactClient.js
+++ b/packages/react/src/ReactClient.js
@@ -37,7 +37,6 @@ import {postpone} from './ReactPostpone';
 import {
   getCacheForType,
   useCallback,
-  unstable_useContextWithBailout,
   useContext,
   useEffect,
   useEffectEvent,
@@ -86,7 +85,6 @@ export {
   cache,
   postpone as unstable_postpone,
   useCallback,
-  unstable_useContextWithBailout,
   useContext,
   useEffect,
   useEffectEvent as experimental_useEffectEvent,
diff --git a/packages/react/src/ReactHooks.js b/packages/react/src/ReactHooks.js
index 40c8a23d3798b..32f49268880f0 100644
--- a/packages/react/src/ReactHooks.js
+++ b/packages/react/src/ReactHooks.js
@@ -19,10 +19,6 @@ import {REACT_CONSUMER_TYPE} from 'shared/ReactSymbols';
 import ReactSharedInternals from 'shared/ReactSharedInternals';
 
 import {enableUseResourceEffectHook} from 'shared/ReactFeatureFlags';
-import {
-  enableContextProfiling,
-  enableLazyContextPropagation,
-} from '../../shared/ReactFeatureFlags';
 
 type BasicStateAction<S> = (S => S) | S;
 type Dispatch<A> = A => void;
@@ -69,27 +65,6 @@ export function useContext<T>(Context: ReactContext<T>): T {
   return dispatcher.useContext(Context);
 }
 
-export function unstable_useContextWithBailout<T>(
-  context: ReactContext<T>,
-  select: (T => Array<mixed>) | null,
-): T {
-  if (!(enableLazyContextPropagation && enableContextProfiling)) {
-    throw new Error('Not implemented.');
-  }
-
-  const dispatcher = resolveDispatcher();
-  if (__DEV__) {
-    if (context.$$typeof === REACT_CONSUMER_TYPE) {
-      console.error(
-        'Calling useContext(Context.Consumer) is not supported and will cause bugs. ' +
-          'Did you mean to call useContext(Context) instead?',
-      );
-    }
-  }
-  // $FlowFixMe[not-a-function] This is unstable, thus optional
-  return dispatcher.unstable_useContextWithBailout(context, select);
-}
-
 export function useState<S>(
   initialState: (() => S) | S,
 ): [S, Dispatch<BasicStateAction<S>>] {
diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js
index d1dc6cb7f7907..8caf79fbf285d 100644
--- a/packages/shared/ReactFeatureFlags.js
+++ b/packages/shared/ReactFeatureFlags.js
@@ -101,9 +101,6 @@ export const enableTransitionTracing = false;
 
 export const enableLazyContextPropagation = true;
 
-// Expose unstable useContext for performance testing
-export const enableContextProfiling = false;
-
 // FB-only usage. The new API has different semantics.
 export const enableLegacyHidden = false;
 
diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js
index 498af214b0188..6c14a9ece37a0 100644
--- a/packages/shared/forks/ReactFeatureFlags.native-fb.js
+++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js
@@ -53,7 +53,6 @@ export const enableFizzExternalRuntime = true;
 export const enableGetInspectorDataForInstanceInProduction = true;
 export const enableHalt = false;
 export const enableInfiniteRenderLoopDetection = false;
-export const enableContextProfiling = false;
 export const enableLazyContextPropagation = true;
 export const enableLegacyCache = false;
 export const enableLegacyFBSupport = false;
diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js
index fb996a43adb6c..6dce24e57fcd7 100644
--- a/packages/shared/forks/ReactFeatureFlags.native-oss.js
+++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js
@@ -43,7 +43,6 @@ export const enableHalt = false;
 export const enableHiddenSubtreeInsertionEffectCleanup = false;
 export const enableInfiniteRenderLoopDetection = false;
 export const enableLazyContextPropagation = true;
-export const enableContextProfiling = false;
 export const enableLegacyCache = false;
 export const enableLegacyFBSupport = false;
 export const enableLegacyHidden = false;
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js
index 6646a126a0ceb..b332c485a0862 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js
@@ -49,7 +49,6 @@ export const transitionLaneExpirationMs = 5000;
 
 export const disableSchedulerTimeoutInWorkLoop = false;
 export const enableLazyContextPropagation = true;
-export const enableContextProfiling = false;
 export const enableLegacyHidden = false;
 
 export const enableTransitionTracing = false;
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
index dae38936f8a01..20ecdb44b4717 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
@@ -51,7 +51,6 @@ export const transitionLaneExpirationMs = 5000;
 
 export const disableSchedulerTimeoutInWorkLoop = false;
 export const enableLazyContextPropagation = true;
-export const enableContextProfiling = false;
 export const enableLegacyHidden = false;
 
 export const enableTransitionTracing = false;
diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js
index 060600286e6de..8054a14bbc8a6 100644
--- a/packages/shared/forks/ReactFeatureFlags.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.www.js
@@ -79,8 +79,6 @@ export const enablePostpone = false;
 
 export const enableHalt = false;
 
-export const enableContextProfiling = true;
-
 // TODO: www currently relies on this feature. It's disabled in open source.
 // Need to remove it.
 export const disableCommentsAsDOMContainers = false;
diff --git a/scripts/error-codes/codes.json b/scripts/error-codes/codes.json
index 65961e313b074..3ad0aa6f6006a 100644
--- a/scripts/error-codes/codes.json
+++ b/scripts/error-codes/codes.json
@@ -530,4 +530,3 @@
   "542": "Suspense Exception: This is not a real error! It's an implementation detail of `useActionState` to interrupt the current render. You must either rethrow it immediately, or move the `useActionState` call outside of the `try/catch` block. Capturing without rethrowing will lead to unexpected behavior.\n\nTo handle async errors, wrap your component in an error boundary.",
   "543": "Expected a ResourceEffectUpdate to be pushed together with ResourceEffectIdentity. This is a bug in React."
 }
-