diff --git a/crates/gen_lsp_server/src/lib.rs b/crates/gen_lsp_server/src/lib.rs
index b47db0df42d..476c12cc16d 100644
--- a/crates/gen_lsp_server/src/lib.rs
+++ b/crates/gen_lsp_server/src/lib.rs
@@ -25,11 +25,9 @@ pub use {
     stdio::{stdio_transport, Threads},
 };
 
-pub type LspServer = fn(&mut Receiver<RawMessage>, &mut Sender<RawMessage>) -> Result<()>;
-
 pub fn run_server(
     caps: ServerCapabilities,
-    server: LspServer,
+    server: impl FnOnce(&mut Receiver<RawMessage>, &mut Sender<RawMessage>) -> Result<()>,
     mut receiver: Receiver<RawMessage>,
     mut sender: Sender<RawMessage>,
 ) -> Result<()> {
diff --git a/crates/server/src/main.rs b/crates/server/src/main.rs
index 3e3bd44a13e..ecc1f58f8a4 100644
--- a/crates/server/src/main.rs
+++ b/crates/server/src/main.rs
@@ -55,7 +55,13 @@ fn main() -> Result<()> {
 
 fn main_inner() -> Result<()> {
     let (receiver, sender, threads) = stdio_transport();
-    run_server(caps::server_capabilities(), main_loop::main_loop, receiver, sender)?;
+    let root = ::std::env::current_dir()?;
+    run_server(
+        caps::server_capabilities(),
+        |r, s| main_loop::main_loop(root, r, s),
+        receiver,
+        sender,
+    )?;
     info!("shutting down IO...");
     threads.join()?;
     info!("... IO is down");
diff --git a/crates/server/src/main_loop/mod.rs b/crates/server/src/main_loop/mod.rs
index 34d07780532..75d65dcbf25 100644
--- a/crates/server/src/main_loop/mod.rs
+++ b/crates/server/src/main_loop/mod.rs
@@ -2,6 +2,7 @@ mod handlers;
 mod subscriptions;
 
 use std::{
+    path::PathBuf,
     collections::{HashMap},
 };
 
@@ -26,14 +27,13 @@ enum Task {
 }
 
 pub(super) fn main_loop(
-    receriver: &mut Receiver<RawMessage>,
-    sender: &mut Sender<RawMessage>,
+    root: PathBuf,
+    msg_receriver: &mut Receiver<RawMessage>,
+    msg_sender: &mut Sender<RawMessage>,
 ) -> Result<()> {
     let pool = ThreadPool::new(4);
     let (task_sender, task_receiver) = bounded::<Task>(16);
-    let (fs_events_receiver, watcher) = vfs::watch(vec![
-        ::std::env::current_dir()?,
-    ]);
+    let (fs_events_receiver, watcher) = vfs::watch(vec![root]);
 
     info!("server initialized, serving requests");
     let mut state = ServerWorldState::new();
@@ -42,8 +42,8 @@ pub(super) fn main_loop(
     let mut subs = Subscriptions::new();
     main_loop_inner(
         &pool,
-        receriver,
-        sender,
+        msg_receriver,
+        msg_sender,
         task_receiver.clone(),
         task_sender,
         fs_events_receiver,
@@ -53,7 +53,7 @@ pub(super) fn main_loop(
     )?;
 
     info!("waiting for background jobs to finish...");
-    task_receiver.for_each(drop);
+    task_receiver.for_each(|task| on_task(task, msg_sender, &mut pending_requests));
     pool.join();
     info!("...background jobs have finished");
 
@@ -95,22 +95,8 @@ fn main_loop_inner(
         };
         let mut state_changed = false;
         match event {
-            Event::FsWatcherDead => {
-                fs_receiver = None;
-            }
-            Event::Task(task) => {
-                match task {
-                    Task::Respond(response) => {
-                        if let Some(handle) = pending_requests.remove(&response.id) {
-                            assert!(handle.has_completed());
-                        }
-                        msg_sender.send(RawMessage::Response(response))
-                    }
-                    Task::Notify(n) =>
-                        msg_sender.send(RawMessage::Notification(n)),
-                }
-                continue;
-            }
+            Event::FsWatcherDead => fs_receiver = None,
+            Event::Task(task) => on_task(task, msg_sender, pending_requests),
             Event::Fs(events) => {
                 trace!("fs change, {} events", events.len());
                 state.apply_fs_changes(events);
@@ -158,6 +144,23 @@ fn main_loop_inner(
     }
 }
 
+fn on_task(
+    task: Task,
+    msg_sender: &mut Sender<RawMessage>,
+    pending_requests: &mut HashMap<u64, JobHandle>,
+) {
+    match task {
+        Task::Respond(response) => {
+            if let Some(handle) = pending_requests.remove(&response.id) {
+                assert!(handle.has_completed());
+            }
+            msg_sender.send(RawMessage::Response(response))
+        }
+        Task::Notify(n) =>
+            msg_sender.send(RawMessage::Notification(n)),
+    }
+}
+
 fn on_request(
     world: &mut ServerWorldState,
     pending_requests: &mut HashMap<u64, JobHandle>,
@@ -280,15 +283,12 @@ impl<'a> PoolDispatcher<'a> {
             None => return Ok(self),
             Some(req) => req,
         };
-        let world = self.world;
-        let sender = self.sender;
-        let pool = self.pool;
         match req.cast::<R>() {
             Ok((id, params)) => {
                 let (handle, token) = JobHandle::new();
-                let world = world.snapshot();
-                let sender = sender.clone();
-                pool.execute(move || {
+                let world = self.world.snapshot();
+                let sender = self.sender.clone();
+                self.pool.execute(move || {
                     let resp = match f(world, params, token) {
                         Ok(resp) => RawResponse::ok(id, resp),
                         Err(e) => RawResponse::err(id, ErrorCode::InternalError as i32, e.to_string()),
diff --git a/crates/server/src/req.rs b/crates/server/src/req.rs
index c6d2f2efbc6..f5212727196 100644
--- a/crates/server/src/req.rs
+++ b/crates/server/src/req.rs
@@ -1,6 +1,4 @@
 use std::collections::HashMap;
-
-use serde::{ser::Serialize, de::DeserializeOwned};
 use languageserver_types::{TextDocumentIdentifier, Range, Url, Position, Location};
 use url_serde;
 
@@ -18,24 +16,6 @@ pub use languageserver_types::{
     TextDocumentEdit,
 };
 
-
-pub trait ClientRequest: 'static {
-    type Params: DeserializeOwned + Send + 'static;
-    type Result: Serialize + Send + 'static;
-    const METHOD: &'static str;
-}
-
-impl<T> ClientRequest for T
-    where T: Request + 'static,
-          T::Params: DeserializeOwned + Send + 'static,
-          T::Result: Serialize + Send + 'static,
-{
-    type Params = <T as Request>::Params;
-    type Result = <T as Request>::Result;
-    const METHOD: &'static str = <T as Request>::METHOD;
-}
-
-
 pub enum SyntaxTree {}
 
 impl Request for SyntaxTree {