Allow base::DoNothing() to handle any argument list.

This changes the form of DoNothing() from a simple no-arg function to a class
that produces callbacks via templated operator().  This allows callers to
replace base::Bind(&base::DoNothing) with base::DoNothing() for a small
boilerplate reduction; more importantly, it allows using DoNothing() to replace
existing no-op functions/lambdas that took more than zero args, and thus had to
be manually declared.  This removes dozens of such functions and around 600 LOC
total.

In a few places, DoNothing() can't be used directly, and this change also adds
explicit callback-generating Once<>() and Repeatedly<>() members that will
produce a callback with a specific signature.

BUG=811554
TEST=none

Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_mojo;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_vr;master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Change-Id: I37f87b35c6c079a6a8c03ff18ec3a54e1237f126
Reviewed-on: https://chromium-review.googlesource.com/903416
Commit-Queue: Peter Kasting <pkasting@chromium.org>
Reviewed-by: Jochen Eisinger <jochen@chromium.org>
Reviewed-by: Gabriel Charette <gab@chromium.org>
Cr-Commit-Position: refs/heads/master@{#538953}

CrOS-Libchrome-Original-Commit: 341e1fbe2da09573345a48821a8273d5a06e375d
diff --git a/base/bind_helpers.cc b/base/bind_helpers.cc
deleted file mode 100644
index f1fe46d..0000000
--- a/base/bind_helpers.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/bind_helpers.h"
-
-#include "base/callback.h"
-
-namespace base {
-
-void DoNothing() {
-}
-
-}  // namespace base
diff --git a/base/bind_helpers.h b/base/bind_helpers.h
index 07d64ae..fca3939 100644
--- a/base/bind_helpers.h
+++ b/base/bind_helpers.h
@@ -10,6 +10,7 @@
 #include <type_traits>
 #include <utility>
 
+#include "base/bind.h"
 #include "base/callback.h"
 #include "base/memory/weak_ptr.h"
 #include "build/build_config.h"
@@ -19,8 +20,28 @@
 
 namespace base {
 
-// Useful for creating a Closure that does nothing when called.
-BASE_EXPORT void DoNothing();
+// Creates a callback that does nothing when called.
+class BASE_EXPORT DoNothing {
+ public:
+  template <typename... Args>
+  operator RepeatingCallback<void(Args...)>() const {
+    return Repeatedly<Args...>();
+  }
+  template <typename... Args>
+  operator OnceCallback<void(Args...)>() const {
+    return Once<Args...>();
+  }
+  // Explicit way of specifying a specific callback type when the compiler can't
+  // deduce it.
+  template <typename... Args>
+  static RepeatingCallback<void(Args...)> Repeatedly() {
+    return BindRepeating([](Args... args) {});
+  }
+  template <typename... Args>
+  static OnceCallback<void(Args...)> Once() {
+    return BindOnce([](Args... args) {});
+  }
+};
 
 // Useful for creating a Closure that will delete a pointer when invoked. Only
 // use this when necessary. In most cases MessageLoop::DeleteSoon() is a better
diff --git a/base/callback_list_unittest.cc b/base/callback_list_unittest.cc
index 62081e9..6eb5ff7 100644
--- a/base/callback_list_unittest.cc
+++ b/base/callback_list_unittest.cc
@@ -310,7 +310,7 @@
       Bind(&Counter::Increment, Unretained(&remove_count)));
 
   std::unique_ptr<CallbackList<void(void)>::Subscription> subscription =
-      cb_reg.Add(Bind(&DoNothing));
+      cb_reg.Add(DoNothing());
 
   // Removing a subscription outside of iteration signals the callback.
   EXPECT_EQ(0, remove_count.value());
diff --git a/base/debug/activity_tracker_unittest.cc b/base/debug/activity_tracker_unittest.cc
index 79d19db..e2b61a9 100644
--- a/base/debug/activity_tracker_unittest.cc
+++ b/base/debug/activity_tracker_unittest.cc
@@ -7,6 +7,7 @@
 #include <memory>
 
 #include "base/bind.h"
+#include "base/bind_helpers.h"
 #include "base/files/file.h"
 #include "base/files/file_util.h"
 #include "base/files/memory_mapped_file.h"
@@ -98,8 +99,6 @@
     exit_data_ = std::move(data);
   }
 
-  static void DoNothing() {}
-
   int64_t exit_id_ = 0;
   int64_t exit_stamp_;
   int exit_code_;
@@ -216,7 +215,7 @@
   ASSERT_EQ(0U, snapshot.activity_stack.size());
 
   {
-    PendingTask task1(FROM_HERE, BindOnce(&DoNothing));
+    PendingTask task1(FROM_HERE, DoNothing());
     ScopedTaskRunActivity activity1(task1);
     ActivityUserData& user_data1 = activity1.user_data();
     (void)user_data1;  // Tell compiler it's been used.
@@ -227,7 +226,7 @@
     EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[0].activity_type);
 
     {
-      PendingTask task2(FROM_HERE, BindOnce(&DoNothing));
+      PendingTask task2(FROM_HERE, DoNothing());
       ScopedTaskRunActivity activity2(task2);
       ActivityUserData& user_data2 = activity2.user_data();
       (void)user_data2;  // Tell compiler it's been used.
@@ -494,7 +493,7 @@
   global->RecordProcessLaunch(other_process_id, FILE_PATH_LITERAL("foo --bar"));
 
   // Do some activities.
-  PendingTask task(FROM_HERE, BindOnce(&DoNothing));
+  PendingTask task(FROM_HERE, DoNothing());
   ScopedTaskRunActivity activity(task);
   ActivityUserData& user_data = activity.user_data();
   ASSERT_NE(0U, user_data.id());
diff --git a/base/message_loop/message_pump_glib_unittest.cc b/base/message_loop/message_pump_glib_unittest.cc
index f7868c7..451c6f5 100644
--- a/base/message_loop/message_pump_glib_unittest.cc
+++ b/base/message_loop/message_pump_glib_unittest.cc
@@ -203,24 +203,24 @@
   // If changes cause this test to fail, it is reasonable to change it, but
   // TestWorkWhileWaitingForEvents and TestEventsWhileWaitingForWork have to be
   // changed accordingly, otherwise they can become flaky.
-  injector()->AddEventAsTask(0, BindOnce(&DoNothing));
+  injector()->AddEventAsTask(0, DoNothing());
   OnceClosure check_task =
       BindOnce(&ExpectProcessedEvents, Unretained(injector()), 2);
   OnceClosure posted_task =
       BindOnce(&PostMessageLoopTask, FROM_HERE, std::move(check_task));
   injector()->AddEventAsTask(0, std::move(posted_task));
-  injector()->AddEventAsTask(0, BindOnce(&DoNothing));
+  injector()->AddEventAsTask(0, DoNothing());
   injector()->AddEvent(0, MessageLoop::QuitWhenIdleClosure());
   RunLoop().Run();
   EXPECT_EQ(4, injector()->processed_events());
 
   injector()->Reset();
-  injector()->AddEventAsTask(0, BindOnce(&DoNothing));
+  injector()->AddEventAsTask(0, DoNothing());
   check_task = BindOnce(&ExpectProcessedEvents, Unretained(injector()), 2);
   posted_task =
       BindOnce(&PostMessageLoopTask, FROM_HERE, std::move(check_task));
   injector()->AddEventAsTask(0, std::move(posted_task));
-  injector()->AddEventAsTask(10, BindOnce(&DoNothing));
+  injector()->AddEventAsTask(10, DoNothing());
   injector()->AddEvent(0, MessageLoop::QuitWhenIdleClosure());
   RunLoop().Run();
   EXPECT_EQ(4, injector()->processed_events());
@@ -376,8 +376,8 @@
   injector->AddEvent(0, MessageLoop::QuitWhenIdleClosure());
 
   // Post a couple of dummy tasks
-  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, BindOnce(&DoNothing));
-  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, BindOnce(&DoNothing));
+  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, DoNothing());
+  ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, DoNothing());
 
   // Drain the events
   while (g_main_context_pending(nullptr)) {
diff --git a/base/message_loop/message_pump_perftest.cc b/base/message_loop/message_pump_perftest.cc
index e0992fd..cadd58e 100644
--- a/base/message_loop/message_pump_perftest.cc
+++ b/base/message_loop/message_pump_perftest.cc
@@ -263,8 +263,8 @@
     do {
       for (int i = 0; i < batch_size; ++i) {
         for (int j = 0; j < tasks_per_reload; ++j) {
-          queue->AddToIncomingQueue(FROM_HERE, base::BindOnce(&DoNothing),
-                                    base::TimeDelta(), Nestable::kNonNestable);
+          queue->AddToIncomingQueue(FROM_HERE, DoNothing(), base::TimeDelta(),
+                                    Nestable::kNonNestable);
           num_posted++;
         }
         TaskQueue loop_local_queue;
diff --git a/base/pending_task_unittest.cc b/base/pending_task_unittest.cc
index d69de06..2a3e0c0 100644
--- a/base/pending_task_unittest.cc
+++ b/base/pending_task_unittest.cc
@@ -69,7 +69,7 @@
       location5,
       ExpectedTrace({location3.program_counter(), location2.program_counter(),
                      location1.program_counter(), location0.program_counter()}),
-      Bind(&DoNothing));
+      DoNothing());
   Closure task4 = Bind(
       &PendingTaskTest::VerifyTraceAndPost, loop.task_runner(), location3,
       location4,
@@ -119,7 +119,7 @@
            ExpectedTrace(
                {location_c0.program_counter(), location_b0.program_counter(),
                 location_a1.program_counter(), location_a0.program_counter()}),
-           Bind(&DoNothing));
+           DoNothing());
   Closure task_c0 = Bind(&PendingTaskTest::VerifyTraceAndPost,
                          loop.task_runner(), location_c0, location_a2,
                          ExpectedTrace({location_b0.program_counter(),
@@ -143,7 +143,7 @@
            thread_b.message_loop()->task_runner(), location_b0, location_b1,
            ExpectedTrace({location_a1.program_counter(),
                           location_a0.program_counter(), nullptr}),
-           Bind(&DoNothing));
+           DoNothing());
 
   // Push one frame onto the stack in thread a then pass to thread b.
   Closure task_a1 =
diff --git a/base/task/cancelable_task_tracker.cc b/base/task/cancelable_task_tracker.cc
index ddc997e..076a684 100644
--- a/base/task/cancelable_task_tracker.cc
+++ b/base/task/cancelable_task_tracker.cc
@@ -70,8 +70,7 @@
     OnceClosure task) {
   DCHECK(sequence_checker_.CalledOnValidSequence());
 
-  return PostTaskAndReply(task_runner, from_here, std::move(task),
-                          BindOnce(&DoNothing));
+  return PostTaskAndReply(task_runner, from_here, std::move(task), DoNothing());
 }
 
 CancelableTaskTracker::TaskId CancelableTaskTracker::PostTaskAndReply(
diff --git a/base/task/cancelable_task_tracker_unittest.cc b/base/task/cancelable_task_tracker_unittest.cc
index 4559b87..b95b158 100644
--- a/base/task/cancelable_task_tracker_unittest.cc
+++ b/base/task/cancelable_task_tracker_unittest.cc
@@ -165,7 +165,7 @@
   ASSERT_TRUE(worker_thread.Start());
 
   CancelableTaskTracker::TaskId task_id = task_tracker_.PostTaskAndReply(
-      worker_thread.task_runner().get(), FROM_HERE, BindOnce(&DoNothing),
+      worker_thread.task_runner().get(), FROM_HERE, DoNothing(),
       MakeExpectedNotRunClosure(FROM_HERE));
   EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id);
 
@@ -354,7 +354,7 @@
 void PostDoNothingTask(CancelableTaskTracker* task_tracker) {
   ignore_result(task_tracker->PostTask(
       scoped_refptr<TestSimpleTaskRunner>(new TestSimpleTaskRunner()).get(),
-      FROM_HERE, BindOnce(&DoNothing)));
+      FROM_HERE, DoNothing()));
 }
 
 TEST_F(CancelableTaskTrackerDeathTest, PostFromDifferentThread) {
@@ -379,8 +379,8 @@
   Thread bad_thread("bad thread");
   ASSERT_TRUE(bad_thread.Start());
 
-  CancelableTaskTracker::TaskId task_id = task_tracker_.PostTask(
-      test_task_runner.get(), FROM_HERE, BindOnce(&DoNothing));
+  CancelableTaskTracker::TaskId task_id =
+      task_tracker_.PostTask(test_task_runner.get(), FROM_HERE, DoNothing());
   EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id);
 
   bad_thread.task_runner()->PostTask(
@@ -398,8 +398,8 @@
   Thread bad_thread("bad thread");
   ASSERT_TRUE(bad_thread.Start());
 
-  CancelableTaskTracker::TaskId task_id = task_tracker_.PostTask(
-      test_task_runner.get(), FROM_HERE, BindOnce(&DoNothing));
+  CancelableTaskTracker::TaskId task_id =
+      task_tracker_.PostTask(test_task_runner.get(), FROM_HERE, DoNothing());
   EXPECT_NE(CancelableTaskTracker::kBadTaskId, task_id);
 
   bad_thread.task_runner()->PostTask(
diff --git a/base/task_scheduler/lazy_task_runner_unittest.cc b/base/task_scheduler/lazy_task_runner_unittest.cc
index 0baafc8..3ca09c9 100644
--- a/base/task_scheduler/lazy_task_runner_unittest.cc
+++ b/base/task_scheduler/lazy_task_runner_unittest.cc
@@ -169,7 +169,7 @@
     // goes out of scope, the second invocation of the line below will access a
     // deleted TaskScheduler and crash.
     g_sequenced_task_runner_user_visible.Get()->PostTask(FROM_HERE,
-                                                         BindOnce(&DoNothing));
+                                                         DoNothing());
   }
 }
 
@@ -179,8 +179,8 @@
     // If the TaskRunner isn't released when the test::ScopedTaskEnvironment
     // goes out of scope, the second invocation of the line below will access a
     // deleted TaskScheduler and crash.
-    g_single_thread_task_runner_user_visible.Get()->PostTask(
-        FROM_HERE, BindOnce(&DoNothing));
+    g_single_thread_task_runner_user_visible.Get()->PostTask(FROM_HERE,
+                                                             DoNothing());
   }
 }
 
@@ -191,8 +191,7 @@
     // If the TaskRunner isn't released when the test::ScopedTaskEnvironment
     // goes out of scope, the second invocation of the line below will access a
     // deleted TaskScheduler and crash.
-    g_com_sta_task_runner_user_visible.Get()->PostTask(FROM_HERE,
-                                                       BindOnce(&DoNothing));
+    g_com_sta_task_runner_user_visible.Get()->PostTask(FROM_HERE, DoNothing());
   }
 }
 #endif  // defined(OS_WIN)
diff --git a/base/task_scheduler/priority_queue_unittest.cc b/base/task_scheduler/priority_queue_unittest.cc
index 13756c8..9dc4d13 100644
--- a/base/task_scheduler/priority_queue_unittest.cc
+++ b/base/task_scheduler/priority_queue_unittest.cc
@@ -60,25 +60,25 @@
 TEST(TaskSchedulerPriorityQueueTest, PushPopPeek) {
   // Create test sequences.
   scoped_refptr<Sequence> sequence_a(new Sequence);
-  sequence_a->PushTask(Task(FROM_HERE, Bind(&DoNothing),
+  sequence_a->PushTask(Task(FROM_HERE, DoNothing(),
                             TaskTraits(TaskPriority::USER_VISIBLE),
                             TimeDelta()));
   SequenceSortKey sort_key_a = sequence_a->GetSortKey();
 
   scoped_refptr<Sequence> sequence_b(new Sequence);
-  sequence_b->PushTask(Task(FROM_HERE, Bind(&DoNothing),
+  sequence_b->PushTask(Task(FROM_HERE, DoNothing(),
                             TaskTraits(TaskPriority::USER_BLOCKING),
                             TimeDelta()));
   SequenceSortKey sort_key_b = sequence_b->GetSortKey();
 
   scoped_refptr<Sequence> sequence_c(new Sequence);
-  sequence_c->PushTask(Task(FROM_HERE, Bind(&DoNothing),
+  sequence_c->PushTask(Task(FROM_HERE, DoNothing(),
                             TaskTraits(TaskPriority::USER_BLOCKING),
                             TimeDelta()));
   SequenceSortKey sort_key_c = sequence_c->GetSortKey();
 
   scoped_refptr<Sequence> sequence_d(new Sequence);
-  sequence_d->PushTask(Task(FROM_HERE, Bind(&DoNothing),
+  sequence_d->PushTask(Task(FROM_HERE, DoNothing(),
                             TaskTraits(TaskPriority::BACKGROUND), TimeDelta()));
   SequenceSortKey sort_key_d = sequence_d->GetSortKey();
 
diff --git a/base/task_scheduler/scheduler_single_thread_task_runner_manager_unittest.cc b/base/task_scheduler/scheduler_single_thread_task_runner_manager_unittest.cc
index e3e68b2..add274e 100644
--- a/base/task_scheduler/scheduler_single_thread_task_runner_manager_unittest.cc
+++ b/base/task_scheduler/scheduler_single_thread_task_runner_manager_unittest.cc
@@ -339,7 +339,7 @@
   auto task_runner =
       single_thread_task_runner_manager_
           ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits(), GetParam());
-  EXPECT_TRUE(task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing)));
+  EXPECT_TRUE(task_runner->PostTask(FROM_HERE, DoNothing()));
   task_tracker_.Shutdown();
   TearDownSingleThreadTaskRunnerManager();
   EXPECT_FALSE(task_runner->PostTask(FROM_HERE, BindOnce(&ShouldNotRun)));
@@ -444,7 +444,7 @@
         BindOnce(&WaitableEvent::Signal, Unretained(&task_running))));
     EXPECT_TRUE(task_runner->PostTask(
         FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking))));
-    EXPECT_TRUE(task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing)));
+    EXPECT_TRUE(task_runner->PostTask(FROM_HERE, DoNothing()));
   }
 
   task_running.Wait();
diff --git a/base/task_scheduler/scheduler_worker_pool_impl_unittest.cc b/base/task_scheduler/scheduler_worker_pool_impl_unittest.cc
index ece1f24..117d6e8 100644
--- a/base/task_scheduler/scheduler_worker_pool_impl_unittest.cc
+++ b/base/task_scheduler/scheduler_worker_pool_impl_unittest.cc
@@ -432,7 +432,7 @@
       worker_pool_->CreateTaskRunnerWithTraits({WithBaseSyncPrimitives()});
   constexpr size_t kNumTasksPosted = 2 * kNumWorkersInWorkerPool;
   for (size_t i = 0; i < kNumTasksPosted; ++i)
-    task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing));
+    task_runner->PostTask(FROM_HERE, DoNothing());
 
   EXPECT_EQ(0U, worker_pool_->NumberOfWorkersForTesting());
 
@@ -575,8 +575,8 @@
   // Post 2 more tasks while the first task hasn't completed its execution. It
   // is guaranteed that these tasks will run immediately after the first task,
   // without allowing the worker to sleep.
-  task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing));
-  task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing));
+  task_runner->PostTask(FROM_HERE, DoNothing());
+  task_runner->PostTask(FROM_HERE, DoNothing());
 
   // Allow tasks to run and wait until the SchedulerWorker is idle.
   event.Signal();
@@ -585,7 +585,7 @@
   // Wake up the SchedulerWorker that just became idle by posting a task and
   // wait until it becomes idle again. The SchedulerWorker should record the
   // TaskScheduler.NumTasksBetweenWaits.* histogram on wake up.
-  task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing));
+  task_runner->PostTask(FROM_HERE, DoNothing());
   worker_pool_->WaitForAllWorkersIdleForTesting();
 
   // Verify that counts were recorded to the histogram as expected.
@@ -1410,7 +1410,7 @@
     // Periodically post tasks to ensure that posting tasks does not prevent
     // workers that are idle due to the pool being over capacity from cleaning
     // up.
-    task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing));
+    task_runner->PostTask(FROM_HERE, DoNothing());
     PlatformThread::Sleep(kReclaimTimeForCleanupTests / 2);
   }
   // Note: one worker above capacity will not get cleaned up since it's on the
diff --git a/base/task_scheduler/scheduler_worker_pool_unittest.cc b/base/task_scheduler/scheduler_worker_pool_unittest.cc
index 129e0f9..242a921 100644
--- a/base/task_scheduler/scheduler_worker_pool_unittest.cc
+++ b/base/task_scheduler/scheduler_worker_pool_unittest.cc
@@ -222,7 +222,7 @@
   StartWorkerPool();
   auto task_runner = test::CreateTaskRunnerWithExecutionMode(
       worker_pool_.get(), GetParam().execution_mode);
-  EXPECT_TRUE(task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing)));
+  EXPECT_TRUE(task_runner->PostTask(FROM_HERE, DoNothing()));
   task_tracker_.Shutdown();
   worker_pool_->JoinForTesting();
   worker_pool_.reset();
diff --git a/base/task_scheduler/sequence_unittest.cc b/base/task_scheduler/sequence_unittest.cc
index aa634a0..86d1547 100644
--- a/base/task_scheduler/sequence_unittest.cc
+++ b/base/task_scheduler/sequence_unittest.cc
@@ -97,8 +97,8 @@
 // Verifies the sort key of a sequence that contains one BACKGROUND task.
 TEST(TaskSchedulerSequenceTest, GetSortKeyBackground) {
   // Create a sequence with a BACKGROUND task.
-  Task background_task(FROM_HERE, BindOnce(&DoNothing),
-                       {TaskPriority::BACKGROUND}, TimeDelta());
+  Task background_task(FROM_HERE, DoNothing(), {TaskPriority::BACKGROUND},
+                       TimeDelta());
   scoped_refptr<Sequence> background_sequence = MakeRefCounted<Sequence>();
   background_sequence->PushTask(std::move(background_task));
 
@@ -122,8 +122,8 @@
 // USER_VISIBLE task.
 TEST(TaskSchedulerSequenceTest, GetSortKeyForeground) {
   // Create a sequence with a USER_VISIBLE task.
-  Task foreground_task(FROM_HERE, BindOnce(&DoNothing),
-                       {TaskPriority::USER_VISIBLE}, TimeDelta());
+  Task foreground_task(FROM_HERE, DoNothing(), {TaskPriority::USER_VISIBLE},
+                       TimeDelta());
   scoped_refptr<Sequence> foreground_sequence = MakeRefCounted<Sequence>();
   foreground_sequence->PushTask(std::move(foreground_task));
 
@@ -147,8 +147,7 @@
 // isn't empty.
 TEST(TaskSchedulerSequenceTest, PopNonEmptyFrontSlot) {
   scoped_refptr<Sequence> sequence = MakeRefCounted<Sequence>();
-  sequence->PushTask(
-      Task(FROM_HERE, Bind(&DoNothing), TaskTraits(), TimeDelta()));
+  sequence->PushTask(Task(FROM_HERE, DoNothing(), TaskTraits(), TimeDelta()));
 
   EXPECT_DCHECK_DEATH({ sequence->Pop(); });
 }
@@ -157,8 +156,7 @@
 // slot is empty.
 TEST(TaskSchedulerSequenceTest, TakeEmptyFrontSlot) {
   scoped_refptr<Sequence> sequence = MakeRefCounted<Sequence>();
-  sequence->PushTask(
-      Task(FROM_HERE, Bind(&DoNothing), TaskTraits(), TimeDelta()));
+  sequence->PushTask(Task(FROM_HERE, DoNothing(), TaskTraits(), TimeDelta()));
 
   EXPECT_TRUE(sequence->TakeTask());
   EXPECT_DCHECK_DEATH({ sequence->TakeTask(); });
diff --git a/base/task_scheduler/task_tracker_posix_unittest.cc b/base/task_scheduler/task_tracker_posix_unittest.cc
index ba478c8..d8849de 100644
--- a/base/task_scheduler/task_tracker_posix_unittest.cc
+++ b/base/task_scheduler/task_tracker_posix_unittest.cc
@@ -76,7 +76,7 @@
   ASSERT_EQ(0, pipe(fds));
   Task task(FROM_HERE,
             Bind(IgnoreResult(&FileDescriptorWatcher::WatchReadable), fds[0],
-                 Bind(&DoNothing)),
+                 DoNothing()),
             TaskTraits(), TimeDelta());
   // FileDescriptorWatcher::WatchReadable needs a SequencedTaskRunnerHandle.
   task.sequenced_task_runner_ref = MakeRefCounted<NullTaskRunner>();
diff --git a/base/task_scheduler/task_tracker_unittest.cc b/base/task_scheduler/task_tracker_unittest.cc
index 502c3e9..1c75983 100644
--- a/base/task_scheduler/task_tracker_unittest.cc
+++ b/base/task_scheduler/task_tracker_unittest.cc
@@ -576,16 +576,16 @@
 }
 
 TEST_P(TaskSchedulerTaskTrackerTest, FlushPendingDelayedTask) {
-  const Task delayed_task(FROM_HERE, BindOnce(&DoNothing),
-                          TaskTraits(GetParam()), TimeDelta::FromDays(1));
+  const Task delayed_task(FROM_HERE, DoNothing(), TaskTraits(GetParam()),
+                          TimeDelta::FromDays(1));
   tracker_.WillPostTask(delayed_task);
   // FlushForTesting() should return even if the delayed task didn't run.
   tracker_.FlushForTesting();
 }
 
 TEST_P(TaskSchedulerTaskTrackerTest, FlushAsyncForTestingPendingDelayedTask) {
-  const Task delayed_task(FROM_HERE, BindOnce(&DoNothing),
-                          TaskTraits(GetParam()), TimeDelta::FromDays(1));
+  const Task delayed_task(FROM_HERE, DoNothing(), TaskTraits(GetParam()),
+                          TimeDelta::FromDays(1));
   tracker_.WillPostTask(delayed_task);
   // FlushAsyncForTesting() should callback even if the delayed task didn't run.
   bool called_back = false;
@@ -596,7 +596,7 @@
 }
 
 TEST_P(TaskSchedulerTaskTrackerTest, FlushPendingUndelayedTask) {
-  Task undelayed_task(FROM_HERE, Bind(&DoNothing), TaskTraits(GetParam()),
+  Task undelayed_task(FROM_HERE, DoNothing(), TaskTraits(GetParam()),
                       TimeDelta());
   tracker_.WillPostTask(undelayed_task);
 
@@ -611,7 +611,7 @@
 }
 
 TEST_P(TaskSchedulerTaskTrackerTest, FlushAsyncForTestingPendingUndelayedTask) {
-  Task undelayed_task(FROM_HERE, Bind(&DoNothing), TaskTraits(GetParam()),
+  Task undelayed_task(FROM_HERE, DoNothing(), TaskTraits(GetParam()),
                       TimeDelta());
   tracker_.WillPostTask(undelayed_task);
 
@@ -629,7 +629,7 @@
 }
 
 TEST_P(TaskSchedulerTaskTrackerTest, PostTaskDuringFlush) {
-  Task undelayed_task(FROM_HERE, Bind(&DoNothing), TaskTraits(GetParam()),
+  Task undelayed_task(FROM_HERE, DoNothing(), TaskTraits(GetParam()),
                       TimeDelta());
   tracker_.WillPostTask(undelayed_task);
 
@@ -639,7 +639,7 @@
   VERIFY_ASYNC_FLUSH_IN_PROGRESS();
 
   // Simulate posting another undelayed task.
-  Task other_undelayed_task(FROM_HERE, Bind(&DoNothing), TaskTraits(GetParam()),
+  Task other_undelayed_task(FROM_HERE, DoNothing(), TaskTraits(GetParam()),
                             TimeDelta());
   tracker_.WillPostTask(other_undelayed_task);
 
@@ -656,7 +656,7 @@
 }
 
 TEST_P(TaskSchedulerTaskTrackerTest, PostTaskDuringFlushAsyncForTesting) {
-  Task undelayed_task(FROM_HERE, Bind(&DoNothing), TaskTraits(GetParam()),
+  Task undelayed_task(FROM_HERE, DoNothing(), TaskTraits(GetParam()),
                       TimeDelta());
   tracker_.WillPostTask(undelayed_task);
 
@@ -669,7 +669,7 @@
   EXPECT_FALSE(event.IsSignaled());
 
   // Simulate posting another undelayed task.
-  Task other_undelayed_task(FROM_HERE, Bind(&DoNothing), TaskTraits(GetParam()),
+  Task other_undelayed_task(FROM_HERE, DoNothing(), TaskTraits(GetParam()),
                             TimeDelta());
   tracker_.WillPostTask(other_undelayed_task);
 
@@ -689,10 +689,10 @@
 
 TEST_P(TaskSchedulerTaskTrackerTest, RunDelayedTaskDuringFlush) {
   // Simulate posting a delayed and an undelayed task.
-  Task delayed_task(FROM_HERE, Bind(&DoNothing), TaskTraits(GetParam()),
+  Task delayed_task(FROM_HERE, DoNothing(), TaskTraits(GetParam()),
                     TimeDelta::FromDays(1));
   tracker_.WillPostTask(delayed_task);
-  Task undelayed_task(FROM_HERE, Bind(&DoNothing), TaskTraits(GetParam()),
+  Task undelayed_task(FROM_HERE, DoNothing(), TaskTraits(GetParam()),
                       TimeDelta());
   tracker_.WillPostTask(undelayed_task);
 
@@ -718,10 +718,10 @@
 
 TEST_P(TaskSchedulerTaskTrackerTest, RunDelayedTaskDuringFlushAsyncForTesting) {
   // Simulate posting a delayed and an undelayed task.
-  Task delayed_task(FROM_HERE, Bind(&DoNothing), TaskTraits(GetParam()),
+  Task delayed_task(FROM_HERE, DoNothing(), TaskTraits(GetParam()),
                     TimeDelta::FromDays(1));
   tracker_.WillPostTask(delayed_task);
-  Task undelayed_task(FROM_HERE, Bind(&DoNothing), TaskTraits(GetParam()),
+  Task undelayed_task(FROM_HERE, DoNothing(), TaskTraits(GetParam()),
                       TimeDelta());
   tracker_.WillPostTask(undelayed_task);
 
@@ -753,7 +753,7 @@
     return;
 
   // Simulate posting a task.
-  Task undelayed_task(FROM_HERE, Bind(&DoNothing), TaskTraits(GetParam()),
+  Task undelayed_task(FROM_HERE, DoNothing(), TaskTraits(GetParam()),
                       TimeDelta());
   tracker_.WillPostTask(undelayed_task);
 
@@ -771,7 +771,7 @@
     return;
 
   // Simulate posting a task.
-  Task undelayed_task(FROM_HERE, Bind(&DoNothing), TaskTraits(GetParam()),
+  Task undelayed_task(FROM_HERE, DoNothing(), TaskTraits(GetParam()),
                       TimeDelta());
   tracker_.WillPostTask(undelayed_task);
 
@@ -793,7 +793,7 @@
     return;
 
   // Simulate posting a task.
-  Task undelayed_task(FROM_HERE, Bind(&DoNothing), TaskTraits(GetParam()),
+  Task undelayed_task(FROM_HERE, DoNothing(), TaskTraits(GetParam()),
                       TimeDelta());
   tracker_.WillPostTask(undelayed_task);
 
@@ -816,7 +816,7 @@
     return;
 
   // Simulate posting a task.
-  Task undelayed_task(FROM_HERE, Bind(&DoNothing), TaskTraits(GetParam()),
+  Task undelayed_task(FROM_HERE, DoNothing(), TaskTraits(GetParam()),
                       TimeDelta());
   tracker_.WillPostTask(undelayed_task);
 
@@ -839,7 +839,7 @@
 }
 
 TEST_P(TaskSchedulerTaskTrackerTest, DoublePendingFlushAsyncForTestingFails) {
-  Task undelayed_task(FROM_HERE, Bind(&DoNothing), TaskTraits(GetParam()),
+  Task undelayed_task(FROM_HERE, DoNothing(), TaskTraits(GetParam()),
                       TimeDelta());
   tracker_.WillPostTask(undelayed_task);
 
@@ -1039,9 +1039,9 @@
 // when it can be rescheduled.
 TEST_F(TaskSchedulerTaskTrackerTest,
        RunAndPopNextTaskReturnsSequenceToReschedule) {
-  Task task_1(FROM_HERE, BindOnce(&DoNothing), TaskTraits(), TimeDelta());
+  Task task_1(FROM_HERE, DoNothing(), TaskTraits(), TimeDelta());
   EXPECT_TRUE(tracker_.WillPostTask(task_1));
-  Task task_2(FROM_HERE, BindOnce(&DoNothing), TaskTraits(), TimeDelta());
+  Task task_2(FROM_HERE, DoNothing(), TaskTraits(), TimeDelta());
   EXPECT_TRUE(tracker_.WillPostTask(task_2));
 
   scoped_refptr<Sequence> sequence =
@@ -1067,8 +1067,8 @@
   std::vector<scoped_refptr<Sequence>> scheduled_sequences;
   testing::StrictMock<MockCanScheduleSequenceObserver> never_notified_observer;
   for (int i = 0; i < kMaxNumScheduledBackgroundSequences; ++i) {
-    Task task(FROM_HERE, BindOnce(&DoNothing),
-              TaskTraits(TaskPriority::BACKGROUND), TimeDelta());
+    Task task(FROM_HERE, DoNothing(), TaskTraits(TaskPriority::BACKGROUND),
+              TimeDelta());
     EXPECT_TRUE(tracker.WillPostTask(task));
     scoped_refptr<Sequence> sequence =
         test::CreateSequenceWithTask(std::move(task));
@@ -1213,7 +1213,7 @@
   // Simulate scheduling sequences. TaskTracker should prevent this.
   std::vector<scoped_refptr<Sequence>> preempted_sequences;
   for (int i = 0; i < 3; ++i) {
-    Task task(FROM_HERE, BindOnce(&DoNothing),
+    Task task(FROM_HERE, DoNothing(),
               TaskTraits(TaskPriority::BACKGROUND,
                          TaskShutdownBehavior::BLOCK_SHUTDOWN),
               TimeDelta());
@@ -1344,7 +1344,7 @@
                 "UserBlockingTaskPriority_MayBlock"}};
 
   for (const auto& test : tests) {
-    Task task(FROM_HERE, Bind(&DoNothing), test.traits, TimeDelta());
+    Task task(FROM_HERE, DoNothing(), test.traits, TimeDelta());
     ASSERT_TRUE(tracker.WillPostTask(task));
 
     HistogramTester tester;
diff --git a/base/task_scheduler/task_unittest.cc b/base/task_scheduler/task_unittest.cc
index b399f66..31a59de 100644
--- a/base/task_scheduler/task_unittest.cc
+++ b/base/task_scheduler/task_unittest.cc
@@ -18,19 +18,19 @@
 // adjusted to SKIP_ON_SHUTDOWN. The shutown behavior of other delayed tasks
 // should not change.
 TEST(TaskSchedulerTaskTest, ShutdownBehaviorChangeWithDelay) {
-  Task continue_on_shutdown(FROM_HERE, BindOnce(&DoNothing),
+  Task continue_on_shutdown(FROM_HERE, DoNothing(),
                             {TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
                             TimeDelta::FromSeconds(1));
   EXPECT_EQ(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN,
             continue_on_shutdown.traits.shutdown_behavior());
 
-  Task skip_on_shutdown(FROM_HERE, BindOnce(&DoNothing),
+  Task skip_on_shutdown(FROM_HERE, DoNothing(),
                         {TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
                         TimeDelta::FromSeconds(1));
   EXPECT_EQ(TaskShutdownBehavior::SKIP_ON_SHUTDOWN,
             skip_on_shutdown.traits.shutdown_behavior());
 
-  Task block_shutdown(FROM_HERE, BindOnce(&DoNothing),
+  Task block_shutdown(FROM_HERE, DoNothing(),
                       {TaskShutdownBehavior::BLOCK_SHUTDOWN},
                       TimeDelta::FromSeconds(1));
   EXPECT_EQ(TaskShutdownBehavior::SKIP_ON_SHUTDOWN,
@@ -39,18 +39,18 @@
 
 // Verify that the shutdown behavior of undelayed tasks is not adjusted.
 TEST(TaskSchedulerTaskTest, NoShutdownBehaviorChangeNoDelay) {
-  Task continue_on_shutdown(FROM_HERE, BindOnce(&DoNothing),
+  Task continue_on_shutdown(FROM_HERE, DoNothing(),
                             {TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
                             TimeDelta());
   EXPECT_EQ(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN,
             continue_on_shutdown.traits.shutdown_behavior());
 
-  Task skip_on_shutdown(FROM_HERE, BindOnce(&DoNothing),
+  Task skip_on_shutdown(FROM_HERE, DoNothing(),
                         {TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, TimeDelta());
   EXPECT_EQ(TaskShutdownBehavior::SKIP_ON_SHUTDOWN,
             skip_on_shutdown.traits.shutdown_behavior());
 
-  Task block_shutdown(FROM_HERE, BindOnce(&DoNothing),
+  Task block_shutdown(FROM_HERE, DoNothing(),
                       {TaskShutdownBehavior::BLOCK_SHUTDOWN}, TimeDelta());
   EXPECT_EQ(TaskShutdownBehavior::BLOCK_SHUTDOWN,
             block_shutdown.traits.shutdown_behavior());
diff --git a/base/test/scoped_mock_time_message_loop_task_runner_unittest.cc b/base/test/scoped_mock_time_message_loop_task_runner_unittest.cc
index 4eefdea..7615fd5 100644
--- a/base/test/scoped_mock_time_message_loop_task_runner_unittest.cc
+++ b/base/test/scoped_mock_time_message_loop_task_runner_unittest.cc
@@ -76,8 +76,8 @@
   bool task_10_has_run = false;
   bool task_11_has_run = false;
 
-  Closure task_1 = Bind(&DoNothing);
-  Closure task_2 = Bind(&DoNothing);
+  Closure task_1 = DoNothing();
+  Closure task_2 = DoNothing();
   Closure task_10 = Bind(&AssignTrue, &task_10_has_run);
   Closure task_11 = Bind(&AssignTrue, &task_11_has_run);
 
diff --git a/base/test/scoped_task_environment_unittest.cc b/base/test/scoped_task_environment_unittest.cc
index 0aa95a5..be58bd7 100644
--- a/base/test/scoped_task_environment_unittest.cc
+++ b/base/test/scoped_task_environment_unittest.cc
@@ -241,12 +241,12 @@
       ScopedTaskEnvironment::ExecutionMode::QUEUED);
 
   constexpr base::TimeDelta kShortTaskDelay = TimeDelta::FromDays(1);
-  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-      FROM_HERE, base::BindOnce(&base::DoNothing), kShortTaskDelay);
+  ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, base::DoNothing(),
+                                                 kShortTaskDelay);
 
   constexpr base::TimeDelta kLongTaskDelay = TimeDelta::FromDays(7);
-  ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-      FROM_HERE, base::BindOnce(&base::DoNothing), kLongTaskDelay);
+  ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, base::DoNothing(),
+                                                 kLongTaskDelay);
 
   std::unique_ptr<base::TickClock> tick_clock =
       scoped_task_environment.GetMockTickClock();
diff --git a/base/timer/mock_timer_unittest.cc b/base/timer/mock_timer_unittest.cc
index ed05f39..61716a4 100644
--- a/base/timer/mock_timer_unittest.cc
+++ b/base/timer/mock_timer_unittest.cc
@@ -63,9 +63,6 @@
   DISALLOW_COPY_AND_ASSIGN(HasWeakPtr);
 };
 
-void DoNothingWithWeakPtr(HasWeakPtr* has_weak_ptr) {
-}
-
 TEST(MockTimerTest, DoesNotRetainClosure) {
   HasWeakPtr *has_weak_ptr = new HasWeakPtr();
   base::WeakPtr<HasWeakPtr> weak_ptr(has_weak_ptr->AsWeakPtr());
@@ -73,7 +70,7 @@
   base::TimeDelta delay = base::TimeDelta::FromSeconds(2);
   ASSERT_TRUE(weak_ptr.get());
   timer.Start(FROM_HERE, delay,
-              base::Bind(&DoNothingWithWeakPtr,
+              base::Bind(base::DoNothing::Repeatedly<HasWeakPtr*>(),
                          base::Owned(has_weak_ptr)));
   ASSERT_TRUE(weak_ptr.get());
   timer.Fire();
diff --git a/base/timer/timer_unittest.cc b/base/timer/timer_unittest.cc
index 7b5c5b5..a868441 100644
--- a/base/timer/timer_unittest.cc
+++ b/base/timer/timer_unittest.cc
@@ -854,7 +854,7 @@
   // Task will be scheduled from sequence #1.
   task_runner1->PostTask(
       FROM_HERE, BindOnce(&TimerSequenceTest::StartTimer, Unretained(this),
-                          TimeDelta::FromHours(1), Bind(&DoNothing)));
+                          TimeDelta::FromHours(1), DoNothing()));
 
   // Abandon task - must be called from scheduling sequence (#1).
   task_runner1->PostTask(
diff --git a/components/policy/core/common/async_policy_provider.cc b/components/policy/core/common/async_policy_provider.cc
index 7e05e25..9fe4153 100644
--- a/components/policy/core/common/async_policy_provider.cc
+++ b/components/policy/core/common/async_policy_provider.cc
@@ -84,10 +84,8 @@
   refresh_callback_.Reset(
       base::Bind(&AsyncPolicyProvider::ReloadAfterRefreshSync,
                  weak_factory_.GetWeakPtr()));
-  loader_->task_runner()->PostTaskAndReply(
-      FROM_HERE,
-      base::Bind(base::DoNothing),
-      refresh_callback_.callback());
+  loader_->task_runner()->PostTaskAndReply(FROM_HERE, base::DoNothing(),
+                                           refresh_callback_.callback());
 }
 
 void AsyncPolicyProvider::ReloadAfterRefreshSync() {
diff --git a/components/timers/alarm_timer_unittest.cc b/components/timers/alarm_timer_unittest.cc
index ecbeb21..1a10edb 100644
--- a/components/timers/alarm_timer_unittest.cc
+++ b/components/timers/alarm_timer_unittest.cc
@@ -281,8 +281,7 @@
     base::FileDescriptorWatcher file_descriptor_watcher(&loop);
     timers::OneShotAlarmTimer timer;
     EXPECT_FALSE(timer.IsRunning());
-    timer.Start(FROM_HERE, base::TimeDelta::FromDays(1),
-                base::Bind(&base::DoNothing));
+    timer.Start(FROM_HERE, base::TimeDelta::FromDays(1), base::DoNothing());
 
     // Allow FileDescriptorWatcher to start watching the timer. Without this, a
     // task posted by FileDescriptorWatcher::WatchReadable() is leaked.
@@ -299,8 +298,7 @@
     base::FileDescriptorWatcher file_descriptor_watcher(&loop);
     timers::SimpleAlarmTimer timer;
     EXPECT_FALSE(timer.IsRunning());
-    timer.Start(FROM_HERE, base::TimeDelta::FromDays(1),
-                base::Bind(&base::DoNothing));
+    timer.Start(FROM_HERE, base::TimeDelta::FromDays(1), base::DoNothing());
 
     // Allow FileDescriptorWatcher to start watching the timer. Without this, a
     // task posted by FileDescriptorWatcher::WatchReadable() is leaked.
@@ -321,8 +319,7 @@
   base::FileDescriptorWatcher file_descriptor_watcher(&loop);
   timers::RepeatingAlarmTimer timer;
   EXPECT_FALSE(timer.IsRunning());
-  timer.Start(FROM_HERE, base::TimeDelta::FromDays(1),
-              base::Bind(&base::DoNothing));
+  timer.Start(FROM_HERE, base::TimeDelta::FromDays(1), base::DoNothing());
 
   // Allow FileDescriptorWatcher to start watching the timer. Without this, a
   // task posted by FileDescriptorWatcher::WatchReadable() is leaked.
@@ -344,8 +341,7 @@
   base::FileDescriptorWatcher file_descriptor_watcher(&loop);
   timers::SimpleAlarmTimer timer;
   EXPECT_FALSE(timer.IsRunning());
-  timer.Start(FROM_HERE, base::TimeDelta::FromDays(1),
-              base::Bind(&base::DoNothing));
+  timer.Start(FROM_HERE, base::TimeDelta::FromDays(1), base::DoNothing());
 
   // Allow FileDescriptorWatcher to start watching the timer. Without this, a
   // task posted by FileDescriptorWatcher::WatchReadable() is leaked.
diff --git a/dbus/bus_unittest.cc b/dbus/bus_unittest.cc
index 127acec..f00d1e9 100644
--- a/dbus/bus_unittest.cc
+++ b/dbus/bus_unittest.cc
@@ -145,10 +145,9 @@
   ASSERT_FALSE(bus->shutdown_completed());
 
   // Try to remove a non existant object proxy should return false.
-  ASSERT_FALSE(
-      bus->RemoveObjectProxy("org.chromium.TestService",
-                             ObjectPath("/org/chromium/TestObject"),
-                             base::Bind(&base::DoNothing)));
+  ASSERT_FALSE(bus->RemoveObjectProxy("org.chromium.TestService",
+                                      ObjectPath("/org/chromium/TestObject"),
+                                      base::DoNothing()));
 
   ObjectProxy* object_proxy1 =
       bus->GetObjectProxy("org.chromium.TestService",
@@ -162,10 +161,9 @@
   // Remove the object from the bus. This will invalidate any other usage of
   // object_proxy1 other than destroy it. We keep this object for a comparison
   // at a later time.
-  ASSERT_TRUE(
-      bus->RemoveObjectProxy("org.chromium.TestService",
-                             ObjectPath("/org/chromium/TestObject"),
-                             base::Bind(&base::DoNothing)));
+  ASSERT_TRUE(bus->RemoveObjectProxy("org.chromium.TestService",
+                                     ObjectPath("/org/chromium/TestObject"),
+                                     base::DoNothing()));
 
   // This should return a different object because the first object was removed
   // from the bus, but not deleted from memory.
diff --git a/dbus/end_to_end_async_unittest.cc b/dbus/end_to_end_async_unittest.cc
index 84f21ec..73e11c4 100644
--- a/dbus/end_to_end_async_unittest.cc
+++ b/dbus/end_to_end_async_unittest.cc
@@ -439,7 +439,7 @@
   // This results in cancelling the pending method call.
   bus_->RemoveObjectProxy(test_service_->service_name(),
                           ObjectPath("/org/chromium/TestObject"),
-                          base::Bind(&base::DoNothing));
+                          base::DoNothing());
 
   // We shouldn't receive any responses. Wait for a while just to make sure.
   run_loop_.reset(new base::RunLoop);
@@ -542,9 +542,7 @@
 
   // Call the method with an empty callback.
   const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
-  object_proxy_->CallMethod(&method_call,
-                            timeout_ms,
-                            ObjectProxy::EmptyResponseCallback());
+  object_proxy_->CallMethod(&method_call, timeout_ms, base::DoNothing());
   // Post a delayed task to quit the message loop.
   run_loop_.reset(new base::RunLoop);
   message_loop_.task_runner()->PostDelayedTask(
diff --git a/dbus/object_proxy.cc b/dbus/object_proxy.cc
index c8c56df..1c0b337 100644
--- a/dbus/object_proxy.cc
+++ b/dbus/object_proxy.cc
@@ -50,10 +50,6 @@
 // The NameOwnerChanged member in |kDBusSystemObjectInterface|.
 constexpr char kNameOwnerChangedMember[] = "NameOwnerChanged";
 
-// An empty function used for ObjectProxy::EmptyResponseCallback().
-void EmptyResponseCallbackBody(Response* /*response*/) {
-}
-
 }  // namespace
 
 ObjectProxy::ReplyCallbackHolder::ReplyCallbackHolder(
@@ -313,11 +309,6 @@
   pending_calls_.clear();
 }
 
-// static
-ObjectProxy::ResponseCallback ObjectProxy::EmptyResponseCallback() {
-  return base::Bind(&EmptyResponseCallbackBody);
-}
-
 void ObjectProxy::StartAsyncMethodCall(int timeout_ms,
                                        DBusMessage* request_message,
                                        ReplyCallbackHolder callback_holder,
diff --git a/dbus/object_proxy.h b/dbus/object_proxy.h
index 966b78d..22e44f1 100644
--- a/dbus/object_proxy.h
+++ b/dbus/object_proxy.h
@@ -127,9 +127,7 @@
   // |callback| will be called in the origin thread, once the method call
   // is complete. As it's called in the origin thread, |callback| can
   // safely reference objects in the origin thread (i.e. UI thread in most
-  // cases). If the caller is not interested in the response from the
-  // method (i.e. calling a method that does not return a value),
-  // EmptyResponseCallback() can be passed to the |callback| parameter.
+  // cases).
   //
   // If the method call is successful, a pointer to Response object will
   // be passed to the callback. If unsuccessful, nullptr will be passed to
@@ -159,9 +157,7 @@
   // |callback| and |error_callback| will be called in the origin thread, once
   // the method call is complete. As it's called in the origin thread,
   // |callback| can safely reference objects in the origin thread (i.e.
-  // UI thread in most cases). If the caller is not interested in the response
-  // from the method (i.e. calling a method that does not return a value),
-  // EmptyResponseCallback() can be passed to the |callback| parameter.
+  // UI thread in most cases).
   //
   // If the method call is successful, |callback| will be invoked with a
   // Response object. If unsuccessful, |error_callback| will be invoked with an
@@ -216,10 +212,6 @@
 
   const ObjectPath& object_path() const { return object_path_; }
 
-  // Returns an empty callback that does nothing. Can be used for
-  // CallMethod().
-  static ResponseCallback EmptyResponseCallback();
-
  protected:
   // This is protected, so we can define sub classes.
   virtual ~ObjectProxy();
diff --git a/mojo/edk/embedder/scoped_ipc_support.cc b/mojo/edk/embedder/scoped_ipc_support.cc
index 476ad64..03813bb 100644
--- a/mojo/edk/embedder/scoped_ipc_support.cc
+++ b/mojo/edk/embedder/scoped_ipc_support.cc
@@ -33,7 +33,7 @@
 
 ScopedIPCSupport::~ScopedIPCSupport() {
   if (shutdown_policy_ == ShutdownPolicy::FAST) {
-    ShutdownIPCSupport(base::Bind(&base::DoNothing));
+    ShutdownIPCSupport(base::DoNothing());
     return;
   }
 
diff --git a/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc b/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc
index 322b266..85cec97 100644
--- a/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/associated_interface_unittest.cc
@@ -761,8 +761,8 @@
   ptr0.set_connection_error_handler(base::Bind(&Fail));
 
   bool ptr0_callback_run = false;
-  ptr0->Echo(123, ExpectValueSetFlagAndRunClosure(
-                      123, &ptr0_callback_run, base::Bind(&base::DoNothing)));
+  ptr0->Echo(123, ExpectValueSetFlagAndRunClosure(123, &ptr0_callback_run,
+                                                  base::DoNothing()));
   ptr0.FlushForTesting();
   EXPECT_TRUE(ptr0_callback_run);
 }
@@ -803,8 +803,8 @@
   ptr0.Bind(std::move(ptr_info));
 
   bool ptr0_callback_run = false;
-  ptr0->Echo(123, ExpectValueSetFlagAndRunClosure(
-                      123, &ptr0_callback_run, base::Bind(&base::DoNothing)));
+  ptr0->Echo(123, ExpectValueSetFlagAndRunClosure(123, &ptr0_callback_run,
+                                                  base::DoNothing()));
   // Because the flush is sent from the binding, it only guarantees that the
   // request has been received, not the response. The second flush waits for the
   // response to be received.
diff --git a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc b/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
index bba81b9..7655bcd 100644
--- a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
+++ b/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc
@@ -7,6 +7,7 @@
 #include <utility>
 
 #include "base/bind.h"
+#include "base/bind_helpers.h"
 #include "base/callback.h"
 #include "base/callback_helpers.h"
 #include "base/memory/ptr_util.h"
@@ -742,11 +743,11 @@
 
   MathCalculatorUI calculator_ui(std::move(calc));
 
-  calculator_ui.Add(2.0, base::Bind(&base::DoNothing));
+  calculator_ui.Add(2.0, base::DoNothing());
   calculator_ui.GetInterfacePtr().FlushForTesting();
   EXPECT_EQ(2.0, calculator_ui.GetOutput());
 
-  calculator_ui.Multiply(5.0, base::Bind(&base::DoNothing));
+  calculator_ui.Multiply(5.0, base::DoNothing());
   calculator_ui.GetInterfacePtr().FlushForTesting();
 
   EXPECT_EQ(10.0, calculator_ui.GetOutput());
@@ -813,8 +814,8 @@
   // Make a call with the proxy's lifetime bound to the response callback.
   sample::PingTest* raw_proxy = ptr.get();
   ptr.set_connection_error_handler(run_loop.QuitClosure());
-  raw_proxy->Ping(
-      base::Bind([](sample::PingTestPtr ptr) {}, base::Passed(&ptr)));
+  raw_proxy->Ping(base::Bind(base::DoNothing::Repeatedly<sample::PingTestPtr>(),
+                             base::Passed(&ptr)));
 
   // Trigger an error on |ptr|. This will ultimately lead to the proxy's
   // response callbacks being destroyed, which will in turn lead to the proxy