about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-06-15 09:45:55 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-06-15 09:45:55 +0000
commit257a15b93942a1e38e561576af471a6a1e63bcff (patch)
tree3586eda54dab85be6d24325e597a1d8f060e36b7
parent9dbf985df5515f4b9b40a7dcf74f916fa8d57ee3 (diff)
parent408e173bb9737f9484ca773ee57cc791f5c57e16 (diff)
downloadrust-257a15b93942a1e38e561576af471a6a1e63bcff.tar.gz
rust-257a15b93942a1e38e561576af471a6a1e63bcff.zip
Merge #1404
1404: Fight down failures! r=matklad a=mominul

issue #1400 

Now only `ra_tools` crate depends on `failure`, should I also fight those? :grin:

Co-authored-by: Muhammad Mominul Huque <mominul2082@gmail.com>
-rw-r--r--Cargo.lock6
-rw-r--r--crates/gen_lsp_server/Cargo.toml1
-rw-r--r--crates/gen_lsp_server/examples/01_gen_lsp_server.rs6
-rw-r--r--crates/gen_lsp_server/examples/02_gen_lsp_server_with_logging.rs6
-rw-r--r--crates/gen_lsp_server/src/lib.rs22
-rw-r--r--crates/gen_lsp_server/src/msg.rs8
-rw-r--r--crates/gen_lsp_server/src/stdio.rs5
-rw-r--r--crates/ra_batch/Cargo.toml2
-rw-r--r--crates/ra_batch/src/lib.rs6
-rw-r--r--crates/ra_cli/Cargo.toml1
-rw-r--r--crates/ra_cli/src/main.rs4
-rw-r--r--crates/ra_lsp_server/Cargo.toml2
-rw-r--r--crates/ra_lsp_server/src/lib.rs2
-rw-r--r--crates/ra_lsp_server/src/main.rs2
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs36
-rw-r--r--crates/ra_lsp_server/src/world.rs11
-rw-r--r--crates/ra_project_model/Cargo.toml2
-rw-r--r--crates/ra_project_model/src/cargo_workspace.rs3
-rw-r--r--crates/ra_project_model/src/lib.rs6
-rw-r--r--crates/ra_project_model/src/sysroot.rs6
-rw-r--r--crates/ra_syntax/src/lib.rs2
21 files changed, 61 insertions, 78 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 2c1c7099e91..03b5794fa1b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -490,7 +490,6 @@ name = "gen_lsp_server"
 version = "0.2.0"
 dependencies = [
  "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "flexi_logger 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "lsp-types 0.57.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1021,7 +1020,6 @@ dependencies = [
 name = "ra_batch"
 version = "0.1.0"
 dependencies = [
- "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "ra_db 0.1.0",
  "ra_hir 0.1.0",
@@ -1037,7 +1035,6 @@ name = "ra_cli"
 version = "0.1.0"
 dependencies = [
  "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "flexi_logger 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "indicatif 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1129,8 +1126,6 @@ name = "ra_lsp_server"
 version = "0.1.0"
 dependencies = [
  "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "flexi_logger 0.11.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "gen_lsp_server 0.2.0",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1188,7 +1183,6 @@ name = "ra_project_model"
 version = "0.1.0"
 dependencies = [
  "cargo_metadata 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "ra_arena 0.1.0",
  "ra_db 0.1.0",
diff --git a/crates/gen_lsp_server/Cargo.toml b/crates/gen_lsp_server/Cargo.toml
index fa2fefea55a..d375606d0ba 100644
--- a/crates/gen_lsp_server/Cargo.toml
+++ b/crates/gen_lsp_server/Cargo.toml
@@ -10,7 +10,6 @@ description = "Generic LSP server scaffold."
 [dependencies]
 lsp-types = "0.57.0"
 log = "0.4.3"
-failure = "0.1.4"
 serde_json = "1.0.34"
 serde = { version = "1.0.83", features = ["derive"] }
 crossbeam-channel = "0.3.5"
diff --git a/crates/gen_lsp_server/examples/01_gen_lsp_server.rs b/crates/gen_lsp_server/examples/01_gen_lsp_server.rs
index 60c581075f7..bc497f74a1e 100644
--- a/crates/gen_lsp_server/examples/01_gen_lsp_server.rs
+++ b/crates/gen_lsp_server/examples/01_gen_lsp_server.rs
@@ -1,3 +1,5 @@
+use std::error::Error;

+

 use crossbeam_channel::{Sender, Receiver};

 use lsp_types::{

     ServerCapabilities, InitializeParams,

@@ -5,7 +7,7 @@ use lsp_types::{
 };

 use gen_lsp_server::{run_server, stdio_transport, handle_shutdown, RawMessage, RawResponse};

 

-fn main() -> Result<(), failure::Error> {

+fn main() -> Result<(), Box<dyn Error + Sync + Send>> {

     let (receiver, sender, io_threads) = stdio_transport();

     run_server(ServerCapabilities::default(), receiver, sender, main_loop)?;

     io_threads.join()?;

@@ -16,7 +18,7 @@ fn main_loop(
     _params: InitializeParams,

     receiver: &Receiver<RawMessage>,

     sender: &Sender<RawMessage>,

-) -> Result<(), failure::Error> {

+) -> Result<(), Box<dyn Error + Sync + Send>> {

     for msg in receiver {

         match msg {

             RawMessage::Request(req) => {

diff --git a/crates/gen_lsp_server/examples/02_gen_lsp_server_with_logging.rs b/crates/gen_lsp_server/examples/02_gen_lsp_server_with_logging.rs
index 27e4f1cbc66..1a6174462cf 100644
--- a/crates/gen_lsp_server/examples/02_gen_lsp_server_with_logging.rs
+++ b/crates/gen_lsp_server/examples/02_gen_lsp_server_with_logging.rs
@@ -42,6 +42,8 @@
 //! {"jsonrpc": "2.0", "method": "exit", "params": null}

 //! ```

 

+use std::error::Error;

+

 use crossbeam_channel::{Sender, Receiver};

 use lsp_types::{

     ServerCapabilities, InitializeParams,

@@ -52,7 +54,7 @@ use gen_lsp_server::{
     run_server, stdio_transport, handle_shutdown, RawMessage, RawResponse, RawRequest,

 };

 

-fn main() -> Result<(), failure::Error> {

+fn main() -> Result<(), Box<dyn Error + Sync + Send>> {

     // Set up logging. Because `stdio_transport` gets a lock on stdout and stdin, we must have

     // our logging only write out to stderr.

     flexi_logger::Logger::with_str("info").start().unwrap();

@@ -75,7 +77,7 @@ fn main_loop(
     _params: InitializeParams,

     receiver: &Receiver<RawMessage>,

     sender: &Sender<RawMessage>,

-) -> Result<(), failure::Error> {

+) -> Result<(), Box<dyn Error + Sync + Send>> {

     info!("starting example main loop");

     for msg in receiver {

         info!("got msg: {:?}", msg);

diff --git a/crates/gen_lsp_server/src/lib.rs b/crates/gen_lsp_server/src/lib.rs
index 1cd5a3a7c72..7ecef83cb18 100644
--- a/crates/gen_lsp_server/src/lib.rs
+++ b/crates/gen_lsp_server/src/lib.rs
@@ -5,11 +5,12 @@
 //! Run with `RUST_LOG=gen_lsp_server=debug` to see all the messages.
 //!
 //! ```no_run
+//! use std::error::Error;
 //! use crossbeam_channel::{Sender, Receiver};
 //! use lsp_types::{ServerCapabilities, InitializeParams, request::{GotoDefinition, GotoDefinitionResponse}};
 //! use gen_lsp_server::{run_server, stdio_transport, handle_shutdown, RawMessage, RawResponse};
 //!
-//! fn main() -> Result<(), failure::Error> {
+//! fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
 //!     let (receiver, sender, io_threads) = stdio_transport();
 //!     run_server(
 //!         ServerCapabilities::default(),
@@ -25,7 +26,7 @@
 //!     _params: InitializeParams,
 //!     receiver: &Receiver<RawMessage>,
 //!     sender: &Sender<RawMessage>,
-//! ) -> Result<(), failure::Error> {
+//! ) -> Result<(), Box<dyn Error + Send + Sync>> {
 //!     for msg in receiver {
 //!         match msg {
 //!             RawMessage::Request(req) => {
@@ -54,7 +55,7 @@
 //! }
 //! ```
 
-use failure::{bail, format_err};
+use std::error::Error;
 
 mod msg;
 mod stdio;
@@ -66,7 +67,7 @@ use lsp_types::{
     InitializeParams, InitializeResult, ServerCapabilities,
 };
 
-pub type Result<T> = ::std::result::Result<T, failure::Error>;
+pub type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>;
 pub use crate::{
     msg::{ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse, RawResponseError},
     stdio::{stdio_transport, Threads},
@@ -92,8 +93,8 @@ pub fn run_server(
     match receiver.recv() {
         Ok(RawMessage::Notification(n)) => n
             .cast::<Exit>()
-            .map_err(|n| format_err!("unexpected notification during shutdown: {:?}", n))?,
-        m => bail!("unexpected message during shutdown: {:?}", m),
+            .map_err(|n| format!("unexpected notification during shutdown: {:?}", n))?,
+        m => Err(format!("unexpected message during shutdown: {:?}", m))?,
     }
     log::info!("lsp server shutdown complete");
     Ok(())
@@ -118,19 +119,18 @@ fn initialize(
 ) -> Result<InitializeParams> {
     let (id, params) = match receiver.recv() {
         Ok(RawMessage::Request(req)) => match req.cast::<Initialize>() {
-            Err(req) => bail!("expected initialize request, got {:?}", req),
+            Err(req) => Err(format!("expected initialize request, got {:?}", req))?,
             Ok(req) => req,
         },
-        msg => bail!("expected initialize request, got {:?}", msg),
+        msg => Err(format!("expected initialize request, got {:?}", msg))?,
     };
     let resp = RawResponse::ok::<Initialize>(id, &InitializeResult { capabilities: caps });
     sender.send(RawMessage::Response(resp)).unwrap();
     match receiver.recv() {
         Ok(RawMessage::Notification(n)) => {
-            n.cast::<Initialized>()
-                .map_err(|_| format_err!("expected initialized notification"))?;
+            n.cast::<Initialized>().map_err(|_| "expected initialized notification")?;
         }
-        _ => bail!("expected initialized notification"),
+        _ => Err(format!("expected initialized notification"))?,
     }
     Ok(params)
 }
diff --git a/crates/gen_lsp_server/src/msg.rs b/crates/gen_lsp_server/src/msg.rs
index 1d39ba4bcdd..2928e4f8bde 100644
--- a/crates/gen_lsp_server/src/msg.rs
+++ b/crates/gen_lsp_server/src/msg.rs
@@ -3,7 +3,6 @@ use std::io::{BufRead, Write};
 use lsp_types::{notification::Notification, request::Request};
 use serde::{Deserialize, Serialize};
 use serde_json::{from_str, from_value, to_string, to_value, Value};
-use failure::{bail, format_err};
 
 use crate::Result;
 
@@ -175,7 +174,7 @@ fn read_msg_text(inp: &mut impl BufRead) -> Result<Option<String>> {
             return Ok(None);
         }
         if !buf.ends_with("\r\n") {
-            bail!("malformed header: {:?}", buf);
+            Err(format!("malformed header: {:?}", buf))?;
         }
         let buf = &buf[..buf.len() - 2];
         if buf.is_empty() {
@@ -183,13 +182,12 @@ fn read_msg_text(inp: &mut impl BufRead) -> Result<Option<String>> {
         }
         let mut parts = buf.splitn(2, ": ");
         let header_name = parts.next().unwrap();
-        let header_value =
-            parts.next().ok_or_else(|| format_err!("malformed header: {:?}", buf))?;
+        let header_value = parts.next().ok_or_else(|| format!("malformed header: {:?}", buf))?;
         if header_name == "Content-Length" {
             size = Some(header_value.parse::<usize>()?);
         }
     }
-    let size = size.ok_or_else(|| format_err!("no Content-Length"))?;
+    let size = size.ok_or("no Content-Length")?;
     let mut buf = buf.into_bytes();
     buf.resize(size, 0);
     inp.read_exact(&mut buf)?;
diff --git a/crates/gen_lsp_server/src/stdio.rs b/crates/gen_lsp_server/src/stdio.rs
index 2d6418400a3..f8931f2dcea 100644
--- a/crates/gen_lsp_server/src/stdio.rs
+++ b/crates/gen_lsp_server/src/stdio.rs
@@ -4,7 +4,6 @@ use std::{
 };
 
 use crossbeam_channel::{bounded, Receiver, Sender};
-use failure::bail;
 use lsp_types::notification::Exit;
 
 use crate::{RawMessage, Result};
@@ -48,11 +47,11 @@ impl Threads {
     pub fn join(self) -> Result<()> {
         match self.reader.join() {
             Ok(r) => r?,
-            Err(_) => bail!("reader panicked"),
+            Err(_) => Err("reader panicked")?,
         }
         match self.writer.join() {
             Ok(r) => r,
-            Err(_) => bail!("writer panicked"),
+            Err(_) => Err("writer panicked")?,
         }
     }
 }
diff --git a/crates/ra_batch/Cargo.toml b/crates/ra_batch/Cargo.toml
index 3037e27c418..8bf085bbfbc 100644
--- a/crates/ra_batch/Cargo.toml
+++ b/crates/ra_batch/Cargo.toml
@@ -8,8 +8,6 @@ authors = ["rust-analyzer developers"]
 log = "0.4.5"
 rustc-hash = "1.0"
 
-failure = "0.1.4"
-
 ra_vfs = "0.2.0"
 ra_syntax = { path = "../ra_syntax" }
 ra_db = { path = "../ra_db" }
diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs
index c59821f4467..96b32d9fe46 100644
--- a/crates/ra_batch/src/lib.rs
+++ b/crates/ra_batch/src/lib.rs
@@ -1,8 +1,6 @@
 mod vfs_filter;
 
-use std::sync::Arc;
-use std::path::Path;
-use std::collections::HashSet;
+use std::{sync::Arc, path::Path, collections::HashSet, error::Error};
 
 use rustc_hash::FxHashMap;
 
@@ -14,7 +12,7 @@ use ra_project_model::ProjectWorkspace;
 use ra_vfs::{Vfs, VfsChange};
 use vfs_filter::IncludeRustFiles;
 
-type Result<T> = std::result::Result<T, failure::Error>;
+type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>;
 
 #[salsa::database(
     ra_db::SourceDatabaseStorage,
diff --git a/crates/ra_cli/Cargo.toml b/crates/ra_cli/Cargo.toml
index 3117f4fda19..57bd0c3d7de 100644
--- a/crates/ra_cli/Cargo.toml
+++ b/crates/ra_cli/Cargo.toml
@@ -7,7 +7,6 @@ publish = false
 
 [dependencies]
 clap = "2.32.0"
-failure = "0.1.4"
 join_to_string = "0.1.1"
 flexi_logger = "0.11.0"
 indicatif = "0.11.0"
diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs
index c9ca13bbc80..1db98aec130 100644
--- a/crates/ra_cli/src/main.rs
+++ b/crates/ra_cli/src/main.rs
@@ -1,6 +1,6 @@
 mod analysis_stats;
 
-use std::io::Read;
+use std::{io::Read, error::Error};
 
 use clap::{App, Arg, SubCommand};
 use ra_ide_api::{file_structure, Analysis};
@@ -8,7 +8,7 @@ use ra_syntax::{SourceFile, TreeArc, AstNode};
 use flexi_logger::Logger;
 use ra_prof::profile;
 
-type Result<T> = ::std::result::Result<T, failure::Error>;
+type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>;
 
 fn main() -> Result<()> {
     Logger::with_env().start()?;
diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml
index d52e0165fb3..142467cc903 100644
--- a/crates/ra_lsp_server/Cargo.toml
+++ b/crates/ra_lsp_server/Cargo.toml
@@ -7,8 +7,6 @@ authors = ["rust-analyzer developers"]
 [dependencies]
 threadpool = "1.7.1"
 relative-path = "0.4.0"
-failure = "0.1.4"
-failure_derive = "0.1.4"
 serde_json = "1.0.34"
 serde = { version = "1.0.83", features = ["derive"] }
 crossbeam-channel = "0.3.5"
diff --git a/crates/ra_lsp_server/src/lib.rs b/crates/ra_lsp_server/src/lib.rs
index aabde420b45..14cfa401f5c 100644
--- a/crates/ra_lsp_server/src/lib.rs
+++ b/crates/ra_lsp_server/src/lib.rs
@@ -9,5 +9,5 @@ pub mod req;
 pub mod init;
 mod world;
 
-pub type Result<T> = ::std::result::Result<T, ::failure::Error>;
+pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
 pub use crate::{caps::server_capabilities, main_loop::main_loop, main_loop::LspError, init::InitializationOptions};
diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs
index 3c3e8b5b0ef..7749d97d6ed 100644
--- a/crates/ra_lsp_server/src/main.rs
+++ b/crates/ra_lsp_server/src/main.rs
@@ -25,7 +25,7 @@ fn main() -> Result<()> {
         }
         Err(_) => {
             log::error!("server panicked");
-            failure::bail!("server panicked")
+            Err("server panicked")?
         }
     }
 }
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs
index 0790ea472ec..aeb8a22992a 100644
--- a/crates/ra_lsp_server/src/main_loop.rs
+++ b/crates/ra_lsp_server/src/main_loop.rs
@@ -2,11 +2,9 @@ mod handlers;
 mod subscriptions;
 pub(crate) mod pending_requests;
 
-use std::{fmt, path::PathBuf, sync::Arc, time::Instant};
+use std::{fmt, path::PathBuf, sync::Arc, time::Instant, error::Error};
 
 use crossbeam_channel::{select, unbounded, Receiver, RecvError, Sender};
-use failure::{bail, format_err};
-use failure_derive::Fail;
 use gen_lsp_server::{
     handle_shutdown, ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse,
 };
@@ -32,8 +30,7 @@ use crate::{
 const THREADPOOL_SIZE: usize = 8;
 const MAX_IN_FLIGHT_LIBS: usize = THREADPOOL_SIZE - 3;
 
-#[derive(Debug, Fail)]
-#[fail(display = "Language Server request failed with {}. ({})", code, message)]
+#[derive(Debug)]
 pub struct LspError {
     pub code: i32,
     pub message: String,
@@ -45,6 +42,14 @@ impl LspError {
     }
 }
 
+impl fmt::Display for LspError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "Language Server request failed with {}. ({})", self.code, self.message)
+    }
+}
+
+impl Error for LspError {}
+
 pub fn main_loop(
     ws_roots: Vec<PathBuf>,
     options: InitializationOptions,
@@ -177,12 +182,12 @@ fn main_loop_inner(
         let event = select! {
             recv(msg_receiver) -> msg => match msg {
                 Ok(msg) => Event::Msg(msg),
-                Err(RecvError) => bail!("client exited without shutdown"),
+                Err(RecvError) => Err("client exited without shutdown")?,
             },
             recv(task_receiver) -> task => Event::Task(task.unwrap()),
             recv(state.vfs.read().task_receiver()) -> task => match task {
                 Ok(task) => Event::Vfs(task),
-                Err(RecvError) => bail!("vfs died"),
+                Err(RecvError) => Err("vfs died")?,
             },
             recv(libdata_receiver) -> data => Event::Lib(data.unwrap())
         };
@@ -380,7 +385,7 @@ fn on_notification(
     let not = match not.cast::<req::DidOpenTextDocument>() {
         Ok(params) => {
             let uri = params.text_document.uri;
-            let path = uri.to_file_path().map_err(|()| format_err!("invalid uri: {}", uri))?;
+            let path = uri.to_file_path().map_err(|()| format!("invalid uri: {}", uri))?;
             if let Some(file_id) =
                 state.vfs.write().add_file_overlay(&path, params.text_document.text)
             {
@@ -393,9 +398,8 @@ fn on_notification(
     let not = match not.cast::<req::DidChangeTextDocument>() {
         Ok(mut params) => {
             let uri = params.text_document.uri;
-            let path = uri.to_file_path().map_err(|()| format_err!("invalid uri: {}", uri))?;
-            let text =
-                params.content_changes.pop().ok_or_else(|| format_err!("empty changes"))?.text;
+            let path = uri.to_file_path().map_err(|()| format!("invalid uri: {}", uri))?;
+            let text = params.content_changes.pop().ok_or_else(|| format!("empty changes"))?.text;
             state.vfs.write().change_file_overlay(path.as_path(), text);
             return Ok(());
         }
@@ -404,7 +408,7 @@ fn on_notification(
     let not = match not.cast::<req::DidCloseTextDocument>() {
         Ok(params) => {
             let uri = params.text_document.uri;
-            let path = uri.to_file_path().map_err(|()| format_err!("invalid uri: {}", uri))?;
+            let path = uri.to_file_path().map_err(|()| format!("invalid uri: {}", uri))?;
             if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) {
                 subs.remove_sub(FileId(file_id.0));
             }
@@ -543,11 +547,7 @@ where
                         error: None,
                     }
                 } else {
-                    RawResponse::err(
-                        id,
-                        ErrorCode::InternalError as i32,
-                        format!("{}\n{}", e, e.backtrace()),
-                    )
+                    RawResponse::err(id, ErrorCode::InternalError as i32, e.to_string())
                 }
             }
         },
@@ -599,6 +599,6 @@ fn show_message(typ: req::MessageType, message: impl Into<String>, sender: &Send
     sender.send(not.into()).unwrap();
 }
 
-fn is_canceled(e: &failure::Error) -> bool {
+fn is_canceled(e: &Box<dyn std::error::Error + Send + Sync>) -> bool {
     e.downcast_ref::<Canceled>().is_some()
 }
diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs
index f9ce570ca34..7822e1c1c5c 100644
--- a/crates/ra_lsp_server/src/world.rs
+++ b/crates/ra_lsp_server/src/world.rs
@@ -11,7 +11,6 @@ use ra_ide_api::{
 use ra_vfs::{Vfs, VfsChange, VfsFile, VfsRoot};
 use relative_path::RelativePathBuf;
 use parking_lot::RwLock;
-use failure::{Error, format_err};
 use gen_lsp_server::ErrorCode;
 
 use crate::{
@@ -169,13 +168,13 @@ impl WorldSnapshot {
     }
 
     pub fn uri_to_file_id(&self, uri: &Url) -> Result<FileId> {
-        let path = uri.to_file_path().map_err(|()| format_err!("invalid uri: {}", uri))?;
+        let path = uri.to_file_path().map_err(|()| format!("invalid uri: {}", uri))?;
         let file = self.vfs.read().path2file(&path).ok_or_else(|| {
             // Show warning as this file is outside current workspace
-            Error::from(LspError {
+            LspError {
                 code: ErrorCode::InvalidRequest as i32,
                 message: "Rust file outside current workspace is not supported yet.".to_string(),
-            })
+            }
         })?;
         Ok(FileId(file.0))
     }
@@ -183,7 +182,7 @@ impl WorldSnapshot {
     pub fn file_id_to_uri(&self, id: FileId) -> Result<Url> {
         let path = self.vfs.read().file2path(VfsFile(id.0));
         let url = Url::from_file_path(&path)
-            .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?;
+            .map_err(|_| format!("can't convert path to url: {}", path.display()))?;
         Ok(url)
     }
 
@@ -191,7 +190,7 @@ impl WorldSnapshot {
         let base = self.vfs.read().root2path(VfsRoot(root.0));
         let path = path.to_path(base);
         let url = Url::from_file_path(&path)
-            .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?;
+            .map_err(|_| format!("can't convert path to url: {}", path.display()))?;
         Ok(url)
     }
 
diff --git a/crates/ra_project_model/Cargo.toml b/crates/ra_project_model/Cargo.toml
index cf4adf35cd5..c1a91d9502b 100644
--- a/crates/ra_project_model/Cargo.toml
+++ b/crates/ra_project_model/Cargo.toml
@@ -9,8 +9,6 @@ log = "0.4.5"
 rustc-hash = "1.0"
 relative-path = "0.4.0"
 
-failure = "0.1.4"
-
 walkdir = "2.2.7"
 
 cargo_metadata = "0.7.0"
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs
index 5a165778881..d5ebf2c7a84 100644
--- a/crates/ra_project_model/src/cargo_workspace.rs
+++ b/crates/ra_project_model/src/cargo_workspace.rs
@@ -3,7 +3,6 @@ use std::path::{Path, PathBuf};
 use cargo_metadata::{MetadataCommand, CargoOpt};
 use ra_arena::{Arena, RawId, impl_arena_id};
 use rustc_hash::FxHashMap;
-use failure::format_err;
 use ra_db::Edition;
 
 use crate::Result;
@@ -127,7 +126,7 @@ impl CargoWorkspace {
         if let Some(parent) = cargo_toml.parent() {
             meta.current_dir(parent);
         }
-        let meta = meta.exec().map_err(|e| format_err!("cargo metadata failed: {}", e))?;
+        let meta = meta.exec().map_err(|e| format!("cargo metadata failed: {}", e))?;
         let mut pkg_by_id = FxHashMap::default();
         let mut packages = Arena::default();
         let mut targets = Arena::default();
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs
index 4ae7f685c71..a3af153f1aa 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/ra_project_model/src/lib.rs
@@ -6,9 +6,9 @@ use std::{
     fs::File,
     io::BufReader,
     path::{Path, PathBuf},
+    error::Error
 };
 
-use failure::bail;
 use rustc_hash::FxHashMap;
 
 use ra_db::{CrateGraph, FileId, Edition};
@@ -24,7 +24,7 @@ pub use crate::{
 };
 
 // FIXME use proper error enum
-pub type Result<T> = ::std::result::Result<T, ::failure::Error>;
+pub type Result<T> = ::std::result::Result<T, Box<dyn Error + Send + Sync>>;
 
 #[derive(Debug, Clone)]
 pub enum ProjectWorkspace {
@@ -298,5 +298,5 @@ fn find_cargo_toml(path: &Path) -> Result<PathBuf> {
         }
         curr = path.parent();
     }
-    bail!("can't find Cargo.toml at {}", path.display())
+    Err(format!("can't find Cargo.toml at {}", path.display()))?
 }
diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs
index 72ccb61a778..9e0d8aaac73 100644
--- a/crates/ra_project_model/src/sysroot.rs
+++ b/crates/ra_project_model/src/sysroot.rs
@@ -38,18 +38,18 @@ impl Sysroot {
             .args(&["--print", "sysroot"])
             .output()?;
         if !rustc_output.status.success() {
-            failure::bail!("failed to locate sysroot")
+            Err("failed to locate sysroot")?
         }
         let stdout = String::from_utf8(rustc_output.stdout)?;
         let sysroot_path = Path::new(stdout.trim());
         let src = sysroot_path.join("lib/rustlib/src/rust/src");
         if !src.exists() {
-            failure::bail!(
+            Err(format!(
                 "can't load standard library from sysroot\n\
                  {:?}\n\
                  try running `rustup component add rust-src`",
                 src,
-            );
+            ))?;
         }
 
         let mut sysroot = Sysroot { crates: Arena::default() };
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs
index 8c0ba6f2d3d..e46ad12dbf1 100644
--- a/crates/ra_syntax/src/lib.rs
+++ b/crates/ra_syntax/src/lib.rs
@@ -11,7 +11,7 @@
 //!
 //! The most interesting modules here are `syntax_node` (which defines concrete
 //! syntax tree) and `ast` (which defines abstract syntax tree on top of the
-//! CST). The actual parser live in a separate `ra_parser` crate, thought the
+//! CST). The actual parser live in a separate `ra_parser` crate, though the
 //! lexer lives in this crate.
 //!
 //! See `api_walkthrough` test in this file for a quick API tour!