Rls: Failing to build the lib portion of a project crashes the RLS on the bin portion

Created on 15 Aug 2017  路  10Comments  路  Source: rust-lang/rls

Using neovim LanguageClient, running the latest nightly toolchain/rls/src/etc I get the following (every time):

22:41:55 DEBUG     => {"jsonrpc":"2.0","method":"textDocument/didChange","params":{"contentChanges":[{"text":"extern crate abstract_ns;\nextern crate futures;\nextern crate getopts;\nextern crate ns_dns_tokio;\nextern crate rand;\nextern crate tokio_core;\nextern crate tokio_io;\n\nuse abstract_ns::Resolver;\nuse futures::{Future, Stream};\nuse futures::future;\nuse getopts::Options;\nuse ns_dns_tokio::DnsResolver;\nuse std::collections:\nuse std::env;\nuse tokio_core::net::UdpSocket;\nuse tokio_core::reactor::Core;\nuse tokio_io::{AsyncRead, io};\n\nstatic mut DEBUG: bool = false;\n\nfn print_usage(program: &str, opts: Options) {\n    let program_path = std::path::PathBuf::from(program);\n    let program_name = program_path.file_stem().unwrap().to_str().unwrap();\n    let brief = format!(\"Usage: {} [-b BIND_ADDR] -l LOCAL_PORT -h REMOTE_ADDR -r REMOTE_PORT\",\n                        program_name);\n    print!(\"{}\", opts.usage(&brief));\n}\n\nfn main() {\n    let args: Vec<String> = env::args().collect();\n    let program = args[0].clone();\n\n    let mut opts = Options::new();\n    opts.reqopt(\"l\",\n                \"local-port\",\n                \"The local port to which udpproxy should bind to\",\n                \"LOCAL_PORT\");\n    opts.reqopt(\"r\",\n                \"remote-port\",\n                \"The remote port to which UDP packets should be forwarded\",\n                \"REMOTE_PORT\");\n    opts.reqopt(\"h\",\n                \"host\",\n                \"The remote address to which packets will be forwarded\",\n                \"REMOTE_ADDR\");\n    opts.optopt(\"b\",\n                \"bind\",\n                \"The address on which to listen for incoming requests\",\n                \"BIND_ADDR\");\n    opts.optflag(\"d\", \"debug\", \"Enable debug mode\");\n\n    let matches = opts.parse(&args[1..])\n        .unwrap_or_else(|_| {\n            print_usage(&program, opts);\n            std::process::exit(-1);\n        });\n\n    unsafe {\n        DEBUG = matches.opt_present(\"d\");\n    }\n    let local_port: i32 = matches.opt_str(\"l\").unwrap().parse().unwrap();\n    let remote_port: i32 = matches.opt_str(\"r\").unwrap().parse().unwrap();\n    let remote_host = matches.opt_str(\"h\").unwrap();\n    let bind_addr = match matches.opt_str(\"b\") {\n        Some(addr) => addr,\n        None => \"127.0.0.1\".to_owned(),\n    };\n\n    forward(&bind_addr, local_port, &remote_host, remote_port);\n}\n\nfn debug(msg: String) {\n    let debug: bool;\n    unsafe {\n        debug = DEBUG;\n    }\n\n    if debug {\n        println!(\"{}\", msg);\n    }\n}\n\nfn forward(bind_ip: &str, local_port: i32, remote_host: &str, remote_port: i32) {\n    //this is the main event loop, powered by tokio core\n    let mut core = Core::new().unwrap();\n    let handle = core.handle();\n\n    //listen on the specified IP and port\n    let bind_addr = format!(\"{}:{}\", bind_ip, local_port);\n    let bind_sock = bind_addr.parse().unwrap();\n    let listener = UdpSocket::bind(&bind_sock, &handle)\n        .expect(&format!(\"Unable to bind to {}\", &bind_addr));\n    println!(\"Listening on {}\", listener.local_addr().unwrap());\n\n    //we have either been provided an IP address or a host name\n    //instead of trying to check its format, just trying creating a SocketAddr from it\n    let parse_result = format!(\"{}:{}\", remote_host, remote_port).parse::<std::net::SocketAddr>();\n    let server = future::result(parse_result)\n        .or_else(|_| {\n            //it's a hostname; we're going to need to resolve it\n            //create an async dns resolver\n            let resolver = DnsResolver::system_config(&handle).unwrap();\n\n            resolver.resolve(&format!(\"{}:{}\", remote_host, remote_port))\n                .map(move |resolved| {\n                    resolved.pick_one()\n                        .expect(&format!(\"No valid IP addresses for target {}\", remote_host))\n                })\n                .map_err(|err| println!(\"{:?}\", err))\n        })\n        .and_then(|remote_addr| {\n            println!(\"Resolved {}:{} to {}\",\n                     remote_host,\n                     remote_port,\n                     remote_addr);\n\n            let remote_addr = remote_addr.clone();\n            let handle = handle.clone();\n            listener.incoming()\n                .for_each(move |(client, client_addr)| {\n                    println!(\"New connection from {}\", client_addr);\n\n                    //establish connection to upstream for each incoming client connection\n                    let handle = handle.clone();\n                    TcpStream::connect(&remote_addr, &handle).and_then(move |remote| {\n                        let (client_recv, client_send) = client.split();\n                        let (remote_recv, remote_send) = remote.split();\n\n                        let remote_bytes_copied = io::copy(remote_recv, client_send);\n                        let client_bytes_copied = io::copy(client_recv, remote_send);\n\n                        fn error_handler<T, V>(err: T, client_addr: V)\n                            where T: std::fmt::Debug,\n                                  V: std::fmt::Display\n                        {\n                            println!(\"Error writing from upstream server to remote client {}!\",\n                                     client_addr);\n                            println!(\"{:?}\", err);\n                            ()\n                        };\n\n                        let client_addr_clone = client_addr.clone();\n                        let async1 = remote_bytes_copied.map(move |(count, _, _)| {\n                                debug(format!(\"Transferred {} bytes from upstream server to \\\n                                               remote client {}\",\n                                              count,\n                                              client_addr_clone))\n                            })\n                            .map_err(move |err| error_handler(err, client_addr_clone));\n\n                        let client_addr_clone = client_addr;\n                        let async2 = client_bytes_copied.map(move |(count, _, _)| {\n                                debug(format!(\"Transferred {} bytes from remote client {} to \\\n                                               upstream server\",\n                                              count,\n                                              client_addr_clone))\n                            })\n                            .map_err(move |err| error_handler(err, client_addr_clone));\n\n                        handle.spawn(async1);\n                        handle.spawn(async2);\n\n                        Ok(())\n                    })\n                })\n                .map_err(|err| println!(\"{:?}\", err))\n        });\n\n    core.run(server).unwrap();\n}\n"}],"textDocument":{"version":2,"uri":"file:///mnt/d/GIT/udpproxy/src/main.rs"}}}
22:41:55 DEBUG     <= {"jsonrpc":"2.0","method":"rustDocument/diagnosticsBegin","params":null}
22:41:55 WARNING  no handler implemented for rustDocument_diagnosticsBegin
22:41:56 INFO     textDocument/didChange
22:41:56 DEBUG     => {"jsonrpc":"2.0","method":"textDocument/didChange","params":{"contentChanges":[{"text":"extern crate abstract_ns;\nextern crate futures;\nextern crate getopts;\nextern crate ns_dns_tokio;\nextern crate rand;\nextern crate tokio_core;\nextern crate tokio_io;\n\nuse abstract_ns::Resolver;\nuse futures::{Future, Stream};\nuse futures::future;\nuse getopts::Options;\nuse ns_dns_tokio::DnsResolver;\nuse std::collections::\nuse std::env;\nuse tokio_core::net::UdpSocket;\nuse tokio_core::reactor::Core;\nuse tokio_io::{AsyncRead, io};\n\nstatic mut DEBUG: bool = false;\n\nfn print_usage(program: &str, opts: Options) {\n    let program_path = std::path::PathBuf::from(program);\n    let program_name = program_path.file_stem().unwrap().to_str().unwrap();\n    let brief = format!(\"Usage: {} [-b BIND_ADDR] -l LOCAL_PORT -h REMOTE_ADDR -r REMOTE_PORT\",\n                        program_name);\n    print!(\"{}\", opts.usage(&brief));\n}\n\nfn main() {\n    let args: Vec<String> = env::args().collect();\n    let program = args[0].clone();\n\n    let mut opts = Options::new();\n    opts.reqopt(\"l\",\n                \"local-port\",\n                \"The local port to which udpproxy should bind to\",\n                \"LOCAL_PORT\");\n    opts.reqopt(\"r\",\n                \"remote-port\",\n                \"The remote port to which UDP packets should be forwarded\",\n                \"REMOTE_PORT\");\n    opts.reqopt(\"h\",\n                \"host\",\n                \"The remote address to which packets will be forwarded\",\n                \"REMOTE_ADDR\");\n    opts.optopt(\"b\",\n                \"bind\",\n                \"The address on which to listen for incoming requests\",\n                \"BIND_ADDR\");\n    opts.optflag(\"d\", \"debug\", \"Enable debug mode\");\n\n    let matches = opts.parse(&args[1..])\n        .unwrap_or_else(|_| {\n            print_usage(&program, opts);\n            std::process::exit(-1);\n        });\n\n    unsafe {\n        DEBUG = matches.opt_present(\"d\");\n    }\n    let local_port: i32 = matches.opt_str(\"l\").unwrap().parse().unwrap();\n    let remote_port: i32 = matches.opt_str(\"r\").unwrap().parse().unwrap();\n    let remote_host = matches.opt_str(\"h\").unwrap();\n    let bind_addr = match matches.opt_str(\"b\") {\n        Some(addr) => addr,\n        None => \"127.0.0.1\".to_owned(),\n    };\n\n    forward(&bind_addr, local_port, &remote_host, remote_port);\n}\n\nfn debug(msg: String) {\n    let debug: bool;\n    unsafe {\n        debug = DEBUG;\n    }\n\n    if debug {\n        println!(\"{}\", msg);\n    }\n}\n\nfn forward(bind_ip: &str, local_port: i32, remote_host: &str, remote_port: i32) {\n    //this is the main event loop, powered by tokio core\n    let mut core = Core::new().unwrap();\n    let handle = core.handle();\n\n    //listen on the specified IP and port\n    let bind_addr = format!(\"{}:{}\", bind_ip, local_port);\n    let bind_sock = bind_addr.parse().unwrap();\n    let listener = UdpSocket::bind(&bind_sock, &handle)\n        .expect(&format!(\"Unable to bind to {}\", &bind_addr));\n    println!(\"Listening on {}\", listener.local_addr().unwrap());\n\n    //we have either been provided an IP address or a host name\n    //instead of trying to check its format, just trying creating a SocketAddr from it\n    let parse_result = format!(\"{}:{}\", remote_host, remote_port).parse::<std::net::SocketAddr>();\n    let server = future::result(parse_result)\n        .or_else(|_| {\n            //it's a hostname; we're going to need to resolve it\n            //create an async dns resolver\n            let resolver = DnsResolver::system_config(&handle).unwrap();\n\n            resolver.resolve(&format!(\"{}:{}\", remote_host, remote_port))\n                .map(move |resolved| {\n                    resolved.pick_one()\n                        .expect(&format!(\"No valid IP addresses for target {}\", remote_host))\n                })\n                .map_err(|err| println!(\"{:?}\", err))\n        })\n        .and_then(|remote_addr| {\n            println!(\"Resolved {}:{} to {}\",\n                     remote_host,\n                     remote_port,\n                     remote_addr);\n\n            let remote_addr = remote_addr.clone();\n            let handle = handle.clone();\n            listener.incoming()\n                .for_each(move |(client, client_addr)| {\n                    println!(\"New connection from {}\", client_addr);\n\n                    //establish connection to upstream for each incoming client connection\n                    let handle = handle.clone();\n                    TcpStream::connect(&remote_addr, &handle).and_then(move |remote| {\n                        let (client_recv, client_send) = client.split();\n                        let (remote_recv, remote_send) = remote.split();\n\n                        let remote_bytes_copied = io::copy(remote_recv, client_send);\n                        let client_bytes_copied = io::copy(client_recv, remote_send);\n\n                        fn error_handler<T, V>(err: T, client_addr: V)\n                            where T: std::fmt::Debug,\n                                  V: std::fmt::Display\n                        {\n                            println!(\"Error writing from upstream server to remote client {}!\",\n                                     client_addr);\n                            println!(\"{:?}\", err);\n                            ()\n                        };\n\n                        let client_addr_clone = client_addr.clone();\n                        let async1 = remote_bytes_copied.map(move |(count, _, _)| {\n                                debug(format!(\"Transferred {} bytes from upstream server to \\\n                                               remote client {}\",\n                                              count,\n                                              client_addr_clone))\n                            })\n                            .map_err(move |err| error_handler(err, client_addr_clone));\n\n                        let client_addr_clone = client_addr;\n                        let async2 = client_bytes_copied.map(move |(count, _, _)| {\n                                debug(format!(\"Transferred {} bytes from remote client {} to \\\n                                               upstream server\",\n                                              count,\n                                              client_addr_clone))\n                            })\n                            .map_err(move |err| error_handler(err, client_addr_clone));\n\n                        handle.spawn(async1);\n                        handle.spawn(async2);\n\n                        Ok(())\n                    })\n                })\n                .map_err(|err| println!(\"{:?}\", err))\n        });\n\n    core.run(server).unwrap();\n}\n"}],"textDocument":{"version":3,"uri":"file:///mnt/d/GIT/udpproxy/src/main.rs"}}}
22:41:56 DEBUG     <= {"jsonrpc":"2.0","method":"rustDocument/diagnosticsBegin","params":null}
22:41:56 WARNING  no handler implemented for rustDocument_diagnosticsBegin
22:41:56 DEBUG     <= 
22:41:56 ERROR    Failed to start language server: [b'{"message":"expected identifier, found keyword `use`","code":null,"level":"error","spans":[{"file_name":"src/main.rs","byte_start":320,"byte_end":323,"line_start":15,"line_end":15,"column_start":1,"column_end":4,"is_primary":true,"text":[{"text":"use std::env;","highlight_start":1,"highlight_end":4}],"label":null,"suggested_replacement":null,"expansion":null}],"children":[],"rendered":null}\n', b'{"message":"expected one of `::`, `;`, or `as`, found `std`","code":null,"level":"error","spans":[{"file_name":"src/main.rs","byte_start":323,"byte_end":323,"line_start":15,"line_end":15,"column_start":4,"column_end":4,"is_primary":false,"text":[{"text":"use std::env;","highlight_start":4,"highlight_end":4}],"label":"expected one of `::`, `;`, or `as` here","suggested_replacement":null,"expansion":null},{"file_name":"src/main.rs","byte_start":324,"byte_end":327,"line_start":15,"line_end":15,"column_start":5,"column_end":8,"is_primary":true,"text":[{"text":"use std::env;","highlight_start":5,"highlight_end":8}],"label":"unexpected token","suggested_replacement":null,"expansion":null}],"children":[],"rendered":null}\n', b'{"message":"aborting due to 2 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":null}\n', b'thread \'<unnamed>\' panicked at \'could not run cargo: CargoError(Internal(Msg("failed to stat `/mnt/d/GIT/udpproxy/target/rls/debug/.fingerprint/udpproxy-9ca18b3406e94519/dep-bin-udpproxy-9ca18b3406e94519`")), State { next_error: Some(Error { repr: Os { code: 2, message: "No such file or directory" } }), backtrace: None })\', /checkout/src/libcore/result.rs:860:4\n', b'note: Run with `RUST_BACKTRACE=1` for a backtrace.\n', b'thread \'<unnamed>\' panicked at \'called `Result::unwrap()` on an `Err` value: "PoisonError { inner: .. }"\', /checkout/src/libcore/result.rs:860:4\n', b'thread \'main\' panicked at \'called `Result::unwrap()` on an `Err` value: "PoisonError { inner: .. }"\', /checkout/src/libcore/result.rs:860:4\n']
22:41:57 ERROR    Failed to start language server: []

I will attempt to get the full backtrace. Any suggestions?

bug

All 10 comments

Looks like Cargo can't read a fingerprint file from disk. You could try a cargo clean of the project before using the RLS. You could also try running in VSCode to see if it is a client or server problem. I would also do a rustup update to make sure all your versions of rls, Cargo, and rustc are up to date and on the same version. (To check, are you building your own RLS or using the version from rustup?)

@nrc I'll try cargo clean and let you know. Everything was installed via rustup, and I had already updated prior to posting.

Unfortunately, I can't try another client easily as this is under WSL and VSCode would execute out of the WSL environment.

cargo clean fixed that particular problem but one or two completions later, it happened again.

This is with RUST_BACKTRACE=full:

05:57:45 WARNING  no handler implemented for rustDocument_diagnosticsBegin
05:57:45 WARNING  register completion manager source failed. Error: NvimError(b'Error calling function.',)
05:57:47 WARNING  no handler implemented for rustDocument_diagnosticsEnd
05:57:50 INFO     Begin textDocument/completion
05:57:50 INFO     textDocument/didChange
05:57:50 INFO     Begin textDocument/completion
05:57:50 DEBUG     => {"id":1,"method":"textDocument/completion","jsonrpc":"2.0","params":{"textDocument":{"uri":"file:///mnt/d/GIT/udpproxy/src/main.rs"},"position":{"character":22,"line":13}}}
05:57:50 INFO     textDocument/didChange
05:57:50 DEBUG     => {"id":2,"method":"textDocument/completion","jsonrpc":"2.0","params":{"textDocument":{"uri":"file:///mnt/d/GIT/udpproxy/src/main.rs"},"position":{"character":22,"line":13}}}
05:57:50 DEBUG     <= {"jsonrpc":"2.0","id":1,"result":[{"label":"hash_map","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/collections/mod.rs"},{"label":"hash_set","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/collections/mod.rs"},{"label":"Bound","kind":13,"detail":"pub enum Bound<T> {"},{"label":"BinaryHeap","kind":7,"detail":"pub struct BinaryHeap<T>"},{"label":"BTreeMap","kind":7,"detail":"pub struct BTreeMap<K, V>"},{"label":"BTreeSet","kind":7,"detail":"pub struct BTreeSet<T>"},{"label":"LinkedList","kind":7,"detail":"pub struct LinkedList<T>"},{"label":"VecDeque","kind":7,"detail":"pub struct VecDeque<T>"},{"label":"binary_heap","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/binary_heap.rs"},{"label":"btree_map","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/lib.rs"},{"label":"btree_set","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/lib.rs"},{"label":"linked_list","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/linked_list.rs"},{"label":"vec_deque","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/vec_deque.rs"},{"label":"HashMap","kind":7,"detail":"pub struct HashMap<K, V, S = RandomState>"},{"label":"HashSet","kind":7,"detail":"pub struct HashSet<T, S = RandomState>"},{"label":"range","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/range.rs"}]}
05:57:50 DEBUG     <= {"jsonrpc":"2.0","id":2,"result":[{"label":"hash_map","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/collections/mod.rs"},{"label":"hash_set","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/collections/mod.rs"},{"label":"Bound","kind":13,"detail":"pub enum Bound<T> {"},{"label":"BinaryHeap","kind":7,"detail":"pub struct BinaryHeap<T>"},{"label":"BTreeMap","kind":7,"detail":"pub struct BTreeMap<K, V>"},{"label":"BTreeSet","kind":7,"detail":"pub struct BTreeSet<T>"},{"label":"LinkedList","kind":7,"detail":"pub struct LinkedList<T>"},{"label":"VecDeque","kind":7,"detail":"pub struct VecDeque<T>"},{"label":"binary_heap","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/binary_heap.rs"},{"label":"btree_map","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/lib.rs"},{"label":"btree_set","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/lib.rs"},{"label":"linked_list","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/linked_list.rs"},{"label":"vec_deque","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/vec_deque.rs"},{"label":"HashMap","kind":7,"detail":"pub struct HashMap<K, V, S = RandomState>"},{"label":"HashSet","kind":7,"detail":"pub struct HashSet<T, S = RandomState>"},{"label":"range","kind":9,"detail":"/home/mqudsi/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/../liballoc/range.rs"}]}
05:57:50 INFO     textDocument/didChange
05:57:50 DEBUG     => {"method":"textDocument/didChange","jsonrpc":"2.0","params":{"contentChanges":[{"text":"extern crate abstract_ns;\nextern crate futures;\nextern crate getopts;\nextern crate ns_dns_tokio;\nextern crate rand;\nextern crate tokio_core;\nextern crate tokio_io;\n\nuse abstract_ns::Resolver;\nuse futures::{Future, Stream};\nuse futures::future;\nuse getopts::Options;\nuse ns_dns_tokio::DnsResolver;\nuse std::collections::h\nuse std::env;\nuse tokio_core::net::UdpSocket;\nuse tokio_core::reactor::Core;\nuse tokio_io::{AsyncRead, io};\n\nstatic mut DEBUG: bool = false;\n\nfn print_usage(program: &str, opts: Options) {\n    let program_path = std::path::PathBuf::from(program);\n    let program_name = program_path.file_stem().unwrap().to_str().unwrap();\n    let brief = format!(\"Usage: {} [-b BIND_ADDR] -l LOCAL_PORT -h REMOTE_ADDR -r REMOTE_PORT\",\n                        program_name);\n    print!(\"{}\", opts.usage(&brief));\n}\n\nfn main() {\n    let args: Vec<String> = env::args().collect();\n    let program = args[0].clone();\n\n    let mut opts = Options::new();\n    opts.reqopt(\"l\",\n                \"local-port\",\n                \"The local port to which udpproxy should bind to\",\n                \"LOCAL_PORT\");\n    opts.reqopt(\"r\",\n                \"remote-port\",\n                \"The remote port to which UDP packets should be forwarded\",\n                \"REMOTE_PORT\");\n    opts.reqopt(\"h\",\n                \"host\",\n                \"The remote address to which packets will be forwarded\",\n                \"REMOTE_ADDR\");\n    opts.optopt(\"b\",\n                \"bind\",\n                \"The address on which to listen for incoming requests\",\n                \"BIND_ADDR\");\n    opts.optflag(\"d\", \"debug\", \"Enable debug mode\");\n\n    let matches = opts.parse(&args[1..])\n        .unwrap_or_else(|_| {\n            print_usage(&program, opts);\n            std::process::exit(-1);\n        });\n\n    unsafe {\n        DEBUG = matches.opt_present(\"d\");\n    }\n    let local_port: i32 = matches.opt_str(\"l\").unwrap().parse().unwrap();\n    let remote_port: i32 = matches.opt_str(\"r\").unwrap().parse().unwrap();\n    let remote_host = matches.opt_str(\"h\").unwrap();\n    let bind_addr = match matches.opt_str(\"b\") {\n        Some(addr) => addr,\n        None => \"127.0.0.1\".to_owned(),\n    };\n\n    forward(&bind_addr, local_port, &remote_host, remote_port);\n}\n\nfn debug(msg: String) {\n    let debug: bool;\n    unsafe {\n        debug = DEBUG;\n    }\n\n    if debug {\n        println!(\"{}\", msg);\n    }\n}\n\nfn forward(bind_ip: &str, local_port: i32, remote_host: &str, remote_port: i32) {\n    //this is the main event loop, powered by tokio core\n    let mut core = Core::new().unwrap();\n    let handle = core.handle();\n\n    //listen on the specified IP and port\n    let bind_addr = format!(\"{}:{}\", bind_ip, local_port);\n    let bind_sock = bind_addr.parse().unwrap();\n    let listener = UdpSocket::bind(&bind_sock, &handle)\n        .expect(&format!(\"Unable to bind to {}\", &bind_addr));\n    println!(\"Listening on {}\", listener.local_addr().unwrap());\n\n    //we have either been provided an IP address or a host name\n    //instead of trying to check its format, just trying creating a SocketAddr from it\n    let parse_result = format!(\"{}:{}\", remote_host, remote_port).parse::<std::net::SocketAddr>();\n    let server = future::result(parse_result)\n        .or_else(|_| {\n            //it's a hostname; we're going to need to resolve it\n            //create an async dns resolver\n            let resolver = DnsResolver::system_config(&handle).unwrap();\n\n            resolver.resolve(&format!(\"{}:{}\", remote_host, remote_port))\n                .map(move |resolved| {\n                    resolved.pick_one()\n                        .expect(&format!(\"No valid IP addresses for target {}\", remote_host))\n                })\n                .map_err(|err| println!(\"{:?}\", err))\n        })\n        .and_then(|remote_addr| {\n            println!(\"Resolved {}:{} to {}\",\n                     remote_host,\n                     remote_port,\n                     remote_addr);\n\n            let remote_addr = remote_addr.clone();\n            let handle = handle.clone();\n            listener.incoming()\n                .for_each(move |(client, client_addr)| {\n                    println!(\"New connection from {}\", client_addr);\n\n                    //establish connection to upstream for each incoming client connection\n                    let handle = handle.clone();\n                    TcpStream::connect(&remote_addr, &handle).and_then(move |remote| {\n                        let (client_recv, client_send) = client.split();\n                        let (remote_recv, remote_send) = remote.split();\n\n                        let remote_bytes_copied = io::copy(remote_recv, client_send);\n                        let client_bytes_copied = io::copy(client_recv, remote_send);\n\n                        fn error_handler<T, V>(err: T, client_addr: V)\n                            where T: std::fmt::Debug,\n                                  V: std::fmt::Display\n                        {\n                            println!(\"Error writing from upstream server to remote client {}!\",\n                                     client_addr);\n                            println!(\"{:?}\", err);\n                            ()\n                        };\n\n                        let client_addr_clone = client_addr.clone();\n                        let async1 = remote_bytes_copied.map(move |(count, _, _)| {\n                                debug(format!(\"Transferred {} bytes from upstream server to \\\n                                               remote client {}\",\n                                              count,\n                                              client_addr_clone))\n                            })\n                            .map_err(move |err| error_handler(err, client_addr_clone));\n\n                        let client_addr_clone = client_addr;\n                        let async2 = client_bytes_copied.map(move |(count, _, _)| {\n                                debug(format!(\"Transferred {} bytes from remote client {} to \\\n                                               upstream server\",\n                                              count,\n                                              client_addr_clone))\n                            })\n                            .map_err(move |err| error_handler(err, client_addr_clone));\n\n                        handle.spawn(async1);\n                        handle.spawn(async2);\n\n                        Ok(())\n                    })\n                })\n                .map_err(|err| println!(\"{:?}\", err))\n        });\n\n    core.run(server).unwrap();\n}\n"}],"textDocument":{"version":2,"uri":"file:///mnt/d/GIT/udpproxy/src/main.rs"}}}
05:57:50 DEBUG     <= {"jsonrpc":"2.0","method":"rustDocument/diagnosticsBegin","params":null}
05:57:50 WARNING  no handler implemented for rustDocument_diagnosticsBegin
05:57:52 INFO     textDocument/didChange
05:57:52 DEBUG     => {"method":"textDocument/didChange","jsonrpc":"2.0","params":{"contentChanges":[{"text":"extern crate abstract_ns;\nextern crate futures;\nextern crate getopts;\nextern crate ns_dns_tokio;\nextern crate rand;\nextern crate tokio_core;\nextern crate tokio_io;\n\nuse abstract_ns::Resolver;\nuse futures::{Future, Stream};\nuse futures::future;\nuse getopts::Options;\nuse ns_dns_tokio::DnsResolver;\nuse std::collections::\nuse std::env;\nuse tokio_core::net::UdpSocket;\nuse tokio_core::reactor::Core;\nuse tokio_io::{AsyncRead, io};\n\nstatic mut DEBUG: bool = false;\n\nfn print_usage(program: &str, opts: Options) {\n    let program_path = std::path::PathBuf::from(program);\n    let program_name = program_path.file_stem().unwrap().to_str().unwrap();\n    let brief = format!(\"Usage: {} [-b BIND_ADDR] -l LOCAL_PORT -h REMOTE_ADDR -r REMOTE_PORT\",\n                        program_name);\n    print!(\"{}\", opts.usage(&brief));\n}\n\nfn main() {\n    let args: Vec<String> = env::args().collect();\n    let program = args[0].clone();\n\n    let mut opts = Options::new();\n    opts.reqopt(\"l\",\n                \"local-port\",\n                \"The local port to which udpproxy should bind to\",\n                \"LOCAL_PORT\");\n    opts.reqopt(\"r\",\n                \"remote-port\",\n                \"The remote port to which UDP packets should be forwarded\",\n                \"REMOTE_PORT\");\n    opts.reqopt(\"h\",\n                \"host\",\n                \"The remote address to which packets will be forwarded\",\n                \"REMOTE_ADDR\");\n    opts.optopt(\"b\",\n                \"bind\",\n                \"The address on which to listen for incoming requests\",\n                \"BIND_ADDR\");\n    opts.optflag(\"d\", \"debug\", \"Enable debug mode\");\n\n    let matches = opts.parse(&args[1..])\n        .unwrap_or_else(|_| {\n            print_usage(&program, opts);\n            std::process::exit(-1);\n        });\n\n    unsafe {\n        DEBUG = matches.opt_present(\"d\");\n    }\n    let local_port: i32 = matches.opt_str(\"l\").unwrap().parse().unwrap();\n    let remote_port: i32 = matches.opt_str(\"r\").unwrap().parse().unwrap();\n    let remote_host = matches.opt_str(\"h\").unwrap();\n    let bind_addr = match matches.opt_str(\"b\") {\n        Some(addr) => addr,\n        None => \"127.0.0.1\".to_owned(),\n    };\n\n    forward(&bind_addr, local_port, &remote_host, remote_port);\n}\n\nfn debug(msg: String) {\n    let debug: bool;\n    unsafe {\n        debug = DEBUG;\n    }\n\n    if debug {\n        println!(\"{}\", msg);\n    }\n}\n\nfn forward(bind_ip: &str, local_port: i32, remote_host: &str, remote_port: i32) {\n    //this is the main event loop, powered by tokio core\n    let mut core = Core::new().unwrap();\n    let handle = core.handle();\n\n    //listen on the specified IP and port\n    let bind_addr = format!(\"{}:{}\", bind_ip, local_port);\n    let bind_sock = bind_addr.parse().unwrap();\n    let listener = UdpSocket::bind(&bind_sock, &handle)\n        .expect(&format!(\"Unable to bind to {}\", &bind_addr));\n    println!(\"Listening on {}\", listener.local_addr().unwrap());\n\n    //we have either been provided an IP address or a host name\n    //instead of trying to check its format, just trying creating a SocketAddr from it\n    let parse_result = format!(\"{}:{}\", remote_host, remote_port).parse::<std::net::SocketAddr>();\n    let server = future::result(parse_result)\n        .or_else(|_| {\n            //it's a hostname; we're going to need to resolve it\n            //create an async dns resolver\n            let resolver = DnsResolver::system_config(&handle).unwrap();\n\n            resolver.resolve(&format!(\"{}:{}\", remote_host, remote_port))\n                .map(move |resolved| {\n                    resolved.pick_one()\n                        .expect(&format!(\"No valid IP addresses for target {}\", remote_host))\n                })\n                .map_err(|err| println!(\"{:?}\", err))\n        })\n        .and_then(|remote_addr| {\n            println!(\"Resolved {}:{} to {}\",\n                     remote_host,\n                     remote_port,\n                     remote_addr);\n\n            let remote_addr = remote_addr.clone();\n            let handle = handle.clone();\n            listener.incoming()\n                .for_each(move |(client, client_addr)| {\n                    println!(\"New connection from {}\", client_addr);\n\n                    //establish connection to upstream for each incoming client connection\n                    let handle = handle.clone();\n                    TcpStream::connect(&remote_addr, &handle).and_then(move |remote| {\n                        let (client_recv, client_send) = client.split();\n                        let (remote_recv, remote_send) = remote.split();\n\n                        let remote_bytes_copied = io::copy(remote_recv, client_send);\n                        let client_bytes_copied = io::copy(client_recv, remote_send);\n\n                        fn error_handler<T, V>(err: T, client_addr: V)\n                            where T: std::fmt::Debug,\n                                  V: std::fmt::Display\n                        {\n                            println!(\"Error writing from upstream server to remote client {}!\",\n                                     client_addr);\n                            println!(\"{:?}\", err);\n                            ()\n                        };\n\n                        let client_addr_clone = client_addr.clone();\n                        let async1 = remote_bytes_copied.map(move |(count, _, _)| {\n                                debug(format!(\"Transferred {} bytes from upstream server to \\\n                                               remote client {}\",\n                                              count,\n                                              client_addr_clone))\n                            })\n                            .map_err(move |err| error_handler(err, client_addr_clone));\n\n                        let client_addr_clone = client_addr;\n                        let async2 = client_bytes_copied.map(move |(count, _, _)| {\n                                debug(format!(\"Transferred {} bytes from remote client {} to \\\n                                               upstream server\",\n                                              count,\n                                              client_addr_clone))\n                            })\n                            .map_err(move |err| error_handler(err, client_addr_clone));\n\n                        handle.spawn(async1);\n                        handle.spawn(async2);\n\n                        Ok(())\n                    })\n                })\n                .map_err(|err| println!(\"{:?}\", err))\n        });\n\n    core.run(server).unwrap();\n}\n"}],"textDocument":{"version":3,"uri":"file:///mnt/d/GIT/udpproxy/src/main.rs"}}}
05:57:52 DEBUG     <= {"jsonrpc":"2.0","method":"rustDocument/diagnosticsBegin","params":null}
05:57:52 WARNING  no handler implemented for rustDocument_diagnosticsBegin
05:57:52 DEBUG     <= 
05:57:54 ERROR    Failed to start language server: [b'{"message":"expected identifier, found keyword `use`","code":null,"level":"error","spans":[{"file_name":"src/main.rs","byte_start":320,"byte_end":323,"line_start":15,"line_end":15,"column_start":1,"column_end":4,"is_primary":true,"text":[{"text":"use std::env;","highlight_start":1,"highlight_end":4}],"label":null,"suggested_replacement":null,"expansion":null}],"children":[],"rendered":null}\n', b'{"message":"expected one of `::`, `;`, or `as`, found `std`","code":null,"level":"error","spans":[{"file_name":"src/main.rs","byte_start":323,"byte_end":323,"line_start":15,"line_end":15,"column_start":4,"column_end":4,"is_primary":false,"text":[{"text":"use std::env;","highlight_start":4,"highlight_end":4}],"label":"expected one of `::`, `;`, or `as` here","suggested_replacement":null,"expansion":null},{"file_name":"src/main.rs","byte_start":324,"byte_end":327,"line_start":15,"line_end":15,"column_start":5,"column_end":8,"is_primary":true,"text":[{"text":"use std::env;","highlight_start":5,"highlight_end":8}],"label":"unexpected token","suggested_replacement":null,"expansion":null}],"children":[],"rendered":null}\n', b'{"message":"aborting due to 2 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":null}\n', b'thread \'<unnamed>\' panicked at \'could not run cargo: CargoError(Internal(Msg("failed to stat `/mnt/d/GIT/udpproxy/target/rls/debug/.fingerprint/udpproxy-9ca18b3406e94519/dep-bin-udpproxy-9ca18b3406e94519`")), State { next_error: Some(Error { repr: Os { code: 2, message: "No such file or directory" } }), backtrace: Some(stack backtrace:\n', b'   0:     0x7fd6e5aaac0c - backtrace::backtrace::trace::h31ca0a1f8bbf6ac2\n', b'   1:     0x7fd6e5aaad62 - backtrace::capture::Backtrace::new::hf6b7f1754ee14e12\n', b'   2:     0x7fd6e5846f34 - error_chain::make_backtrace::h441fcfb9da5c86ff\n', b'   3:     0x7fd6e5705182 - cargo::ops::cargo_rustc::fingerprint::Fingerprint::update_local::h9da3d2fdae79029c\n', b'   4:     0x7fd6e5711253 - <F as cargo::ops::cargo_rustc::job::FnBox<A, R>>::call_box::h37c2ff4b05819a4d\n', b'   5:     0x7fd6e570e6b1 - <F as cargo::ops::cargo_rustc::job::FnBox<A, R>>::call_box::h17263152bffd329c\n', b'   6:     0x7fd6e571c2d5 - cargo::ops::cargo_rustc::job_queue::JobQueue::run::{{closure}}::hb86f486459441f25\n', b'   7:     0x7fd6e55f3766 - <F as crossbeam::FnBox>::call_box::h37d6494a46c86b2b\n', b'   8:     0x7fd6e55f5f62 - std::panicking::try::do_call::h1ec7a40d5c9a3dbc\n', b'   9:     0x7fd6e34b570c - panic_unwind::__rust_maybe_catch_panic\n', b'                        at /checkout/src/libpanic_unwind/lib.rs:98\n', b'  10:     0x7fd6e56350ab - <F as alloc::boxed::FnBox<A>>::call_box::hdf351144609fbaa2\n', b'  11:     0x7fd6e3484bfb - alloc::boxed::{{impl}}::call_once<(),()>\n', b'                        at /checkout/src/liballoc/boxed.rs:692\n', b'                         - std::sys_common::thread::start_thread\n', b'                        at /checkout/src/libstd/sys_common/thread.rs:21\n', b'                         - std::sys::imp::thread::{{impl}}::new::thread_start\n', b'                        at /checkout/src/libstd/sys/unix/thread.rs:84\n', b'  12:     0x7fd6e2db76b9 - start_thread\n', b'  13:     0x7fd6e25b73dc - clone\n', b"  14:                0x0 - <unknown>) })', /checkout/src/libcore/result.rs:860:4\n", b'stack backtrace:\n', b'   0:     0x7fd6e34784d3 - std::sys::imp::backtrace::tracing::imp::unwind_backtrace::hd639a7f6daa6ea13\n', b'                               at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49\n', b'   1:     0x7fd6e3472c74 - std::sys_common::backtrace::_print::hb50ac545893876ff\n', b'                               at /checkout/src/libstd/sys_common/backtrace.rs:71\n', b'   2:     0x7fd6e3485cc3 - std::panicking::default_hook::{{closure}}::hecaa7fb15d8f3afa\n', b'                               at /checkout/src/libstd/sys_common/backtrace.rs:60\n', b'                               at /checkout/src/libstd/panicking.rs:381\n', b'   3:     0x7fd6e3485a22 - std::panicking::default_hook::h3069832862588f27\n', b'                               at /checkout/src/libstd/panicking.rs:397\n', b'   4:     0x7fd6e34861c7 - std::panicking::rust_panic_with_hook::h433501d327eb5ed9\n', b'                               at /checkout/src/libstd/panicking.rs:611\n', b'   5:     0x7fd6e3486024 - std::panicking::begin_panic::h2c8c099fbcad29db\n', b'                               at /checkout/src/libstd/panicking.rs:572\n', b'   6:     0x7fd6e3485f99 - std::panicking::begin_panic_fmt::h821787127b4b95c2\n', b'                               at /checkout/src/libstd/panicking.rs:522\n', b'   7:     0x7fd6e3485f2a - rust_begin_unwind\n', b'                               at /checkout/src/libstd/panicking.rs:498\n', b'   8:     0x7fd6e34c6670 - core::panicking::panic_fmt::h56d9d605a1f3f3aa\n', b'                               at /checkout/src/libcore/panicking.rs:71\n', b'   9:     0x7fd6e5505925 - core::result::unwrap_failed::hb546e44765872d83\n', b'  10:     0x7fd6e55680ec - rls::build::cargo::run_cargo::hdb588f0ff6849e7b\n', b'  11:     0x7fd6e54bbf27 - std::sys_common::backtrace::__rust_begin_short_backtrace::h2d6b9de92f010cf2\n', b'  12:     0x7fd6e54c28ed - std::panicking::try::do_call::hce8396101e8cf8c1\n', b'  13:     0x7fd6e34b570c - __rust_maybe_catch_panic\n', b'                               at /checkout/src/libpanic_unwind/lib.rs:98\n', b'  14:     0x7fd6e5508687 - <F as alloc::boxed::FnBox<A>>::call_box::h8066611131b038e8\n', b'  15:     0x7fd6e3484bfb - std::sys::imp::thread::Thread::new::thread_start::h511fdbf2f5a927dc\n', b'                               at /checkout/src/liballoc/boxed.rs:692\n', b'                               at /checkout/src/libstd/sys_common/thread.rs:21\n', b'                               at /checkout/src/libstd/sys/unix/thread.rs:84\n', b'  16:     0x7fd6e2db76b9 - start_thread\n', b'  17:     0x7fd6e25b73dc - clone\n', b'  18:                0x0 - <unknown>\n', b'thread \'<unnamed>\' panicked at \'called `Result::unwrap()` on an `Err` value: "PoisonError { inner: .. }"\', /checkout/src/libcore/result.rs:860:4\n', b'stack backtrace:\n', b'   0:     0x7fd6e34784d3 - std::sys::imp::backtrace::tracing::imp::unwind_backtrace::hd639a7f6daa6ea13\n', b'                               at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49\n', b'   1:     0x7fd6e3472c74 - std::sys_common::backtrace::_print::hb50ac545893876ff\n', b'                               at /checkout/src/libstd/sys_common/backtrace.rs:71\n', b'   2:     0x7fd6e3485cc3 - std::panicking::default_hook::{{closure}}::hecaa7fb15d8f3afa\n', b'                               at /checkout/src/libstd/sys_common/backtrace.rs:60\n', b'                               at /checkout/src/libstd/panicking.rs:381\n', b'   3:     0x7fd6e3485a22 - std::panicking::default_hook::h3069832862588f27\n', b'                               at /checkout/src/libstd/panicking.rs:397\n', b'   4:     0x7fd6e34861c7 - std::panicking::rust_panic_with_hook::h433501d327eb5ed9\n', b'                               at /checkout/src/libstd/panicking.rs:611\n', b'   5:     0x7fd6e3486024 - std::panicking::begin_panic::h2c8c099fbcad29db\n', b'                               at /checkout/src/libstd/panicking.rs:572\n', b'   6:     0x7fd6e3485f99 - std::panicking::begin_panic_fmt::h821787127b4b95c2\n', b'                               at /checkout/src/libstd/panicking.rs:522\n', b'   7:     0x7fd6e3485f2a - rust_begin_unwind\n', b'                               at /checkout/src/libstd/panicking.rs:498\n', b'   8:     0x7fd6e34c6670 - core::panicking::panic_fmt::h56d9d605a1f3f3aa\n', b'                               at /checkout/src/libcore/panicking.rs:71\n', b'   9:     0x7fd6e55055bf - core::result::unwrap_failed::h865b754f0bd183b6\n', b'  10:     0x7fd6e5563a09 - rls::build::environment::EnvironmentLock::lock::hf1d6176cd121e169\n', b'  11:     0x7fd6e556dace - rls::build::rustc::rustc::hae2f7267876dbd23\n', b'  12:     0x7fd6e5574fea - rls::build::BuildQueue::run_thread::h2f359e5e05b1cdf5\n', b'  13:     0x7fd6e54bb286 - std::sys_common::backtrace::__rust_begin_short_backtrace::h0c710f4cb1c48eb5\n', b'  14:     0x7fd6e54c1f92 - std::panicking::try::do_call::h929a59eea8dab156\n', b'  15:     0x7fd6e34b570c - __rust_maybe_catch_panic\n', b'                               at /checkout/src/libpanic_unwind/lib.rs:98\n', b'  16:     0x7fd6e550a66b - <F as alloc::boxed::FnBox<A>>::call_box::he20ace87c7de2cb8\n', b'  17:     0x7fd6e3484bfb - std::sys::imp::thread::Thread::new::thread_start::h511fdbf2f5a927dc\n', b'                               at /checkout/src/liballoc/boxed.rs:692\n', b'                               at /checkout/src/libstd/sys_common/thread.rs:21\n', b'                               at /checkout/src/libstd/sys/unix/thread.rs:84\n', b'  18:     0x7fd6e2db76b9 - start_thread\n', b'  19:     0x7fd6e25b73dc - clone\n', b'  20:                0x0 - <unknown>\n', b'thread \'main\' panicked at \'called `Result::unwrap()` on an `Err` value: "PoisonError { inner: .. }"\', /checkout/src/libcore/result.rs:860:4\n', b'stack backtrace:\n', b'   0:     0x7fd6e34784d3 - std::sys::imp::backtrace::tracing::imp::unwind_backtrace::hd639a7f6daa6ea13\n', b'                               at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49\n', b'   1:     0x7fd6e3472c74 - std::sys_common::backtrace::_print::hb50ac545893876ff\n', b'                               at /checkout/src/libstd/sys_common/backtrace.rs:71\n', b'   2:     0x7fd6e3485cc3 - std::panicking::default_hook::{{closure}}::hecaa7fb15d8f3afa\n', b'                               at /checkout/src/libstd/sys_common/backtrace.rs:60\n', b'                               at /checkout/src/libstd/panicking.rs:381\n', b'   3:     0x7fd6e3485a22 - std::panicking::default_hook::h3069832862588f27\n', b'                               at /checkout/src/libstd/panicking.rs:397\n', b'   4:     0x7fd6e34861c7 - std::panicking::rust_panic_with_hook::h433501d327eb5ed9\n', b'                               at /checkout/src/libstd/panicking.rs:611\n', b'   5:     0x7fd6e3486024 - std::panicking::begin_panic::h2c8c099fbcad29db\n', b'                               at /checkout/src/libstd/panicking.rs:572\n', b'   6:     0x7fd6e3485f99 - std::panicking::begin_panic_fmt::h821787127b4b95c2\n', b'                               at /checkout/src/libstd/panicking.rs:522\n', b'   7:     0x7fd6e3485f2a - rust_begin_unwind\n', b'                               at /checkout/src/libstd/panicking.rs:498\n', b'   8:     0x7fd6e34c6670 - core::panicking::panic_fmt::h56d9d605a1f3f3aa\n', b'                               at /checkout/src/libcore/panicking.rs:71\n', b'   9:     0x7fd6e5505d2f - core::result::unwrap_failed::hdf9f8b71caf03662\n', b'  10:     0x7fd6e555f595 - rls::actions::ActionHandler::build_current_project::hff9fc2b3ffb1b287\n', b'  11:     0x7fd6e557c4c9 - <rls::server::LsService<O>>::handle_message::h63a690a9a5b47e49\n', b'  12:     0x7fd6e559aa07 - rls::main::hdf6c5fc0223a5ecd\n', b'  13:     0x7fd6e34b570c - __rust_maybe_catch_panic\n', b'                               at /checkout/src/libpanic_unwind/lib.rs:98\n', b'  14:     0x7fd6e348702b - std::rt::lang_start::h0ffd459081119e40\n', b'                               at /checkout/src/libstd/panicking.rs:459\n', b'                               at /checkout/src/libstd/panic.rs:361\n', b'                               at /checkout/src/libstd/rt.rs:61\n', b'  15:     0x7fd6e24d082f - __libc_start_main\n', b'  16:     0x7fd6e548be70 - <unknown>\n']
05:57:54 ERROR    Failed to start language server: []
05:57:55 ERROR    Failed to start language server: []
05:57:55 ERROR    Failed to start language server: []
05:57:58 ERROR    Failed to start language server: []
05:57:58 ERROR    Failed to start language server: []
05:57:58 ERROR    Failed to start language server: []
05:57:59 ERROR    Failed to start language server: []
05:58:00 ERROR    Failed to start language server: []
05:58:01 ERROR    Failed to start language server: []
05:58:02 ERROR    Failed to start language server: []
05:58:03 ERROR    Failed to start language server: []
05:58:03 ERROR    Failed to start language server: []
05:58:06 ERROR    Failed to start language server: []
05:58:06 ERROR    Failed to start language server: []
05:58:06 ERROR    Failed to start language server: []
05:58:06 ERROR    Failed to start language server: []
05:58:07 ERROR    Failed to start language server: []
05:58:13 WARNING  no handler implemented for rustDocument_diagnosticsBegin
05:58:13 WARNING  register completion manager source failed. Error: NvimError(b'Error calling function.',)

It seems to be fully reproducible based off the completions that my navigation in the code are triggering.

OK, it seems that cargo clean may not be very thorough. rm -rf target _seems_ to have done the trick.

I have the strace output, if it's worth anything to you, from the failed RLS runs (attached).

strace.txt

Hello.

I'm getting the same or very similar problem now, since I updated this morning. I'm not sure this is exactly the same problem, but it seems to act in the same way. Few things of note:

  • The code I open can't be compiled now (I left yesterday in a hurry in the middle of some refactoring and opened it on another computer after updating rustc, rls and everything). If anyone is interesting in trying it themselves, I put the code into a separate branch and will leave it there for now: https://gitlab.labs.nic.cz/turris/pakon-aggregator/tree/slice-time-broken-rls
  • It is started with removed target directory, so it starts clean.
  • It crashes even without any interaction from my side, just when trying to examine the sources at startup (only the initialize and textDocument/did Open methods were sent to it). I tried multiple times.
  • When I first switch to a branch that compiles, open a file and let it crunch, than back to this one that doesn't compile, the crash disappears. The fact that there are some artifacts/caches from a successful analysis make the crash go away.
  • I don't know if it is related, but it is a lib+bin crate. I open a file in the lib (src/flow/slice.rs, if someone wants to try the exact same scenario). The logs also contain about not being able to find the aggregator crate (the lib of the project), so it may be trying to compile the bin in parallel when the lib is not there. But that's just a wild guess.

I have a log output of rls itself (I can re-run it with something more verbose than info):

rls.log.txt

The error is similar to this one too, but it happens with CARGO_INCREMENTAL=0, so maybe it's related but maybe it isn't: #425.

And yes, this is the same project as in #440.

Is this the same problem? Or, should I open a different issue? Can I help debugging it somehow? While I know close to nothing about how rls works internally, I might try some debugging (but some hints or suggestions what to check and see would really help).

Thank you

@vorner The error is due to Cargo assuming that a nonexistent fingerprint for an artifact is a fatal error for its build tasks; when a library project fails to build, its result artifact naturally won't exist, and when the bin references that nonexistent artifact Cargo then panics. Which it _should_, I can't think of what else would be a suitable response.

The problem is that RLS quits or crashes because of this. It needs to note the failure but continue operating as if that were another error causing the build to fail. I'll keep looking into it.

Now that I think about it, maybe when running rustc via cmd.exec() we should Err out like here instead, so the compilation stops there?

@jTitor I'm not sure about that.

First, I didn't open a file in the bin, but in the lib. So why did RLS even touch that bin part?

The other thing is, the logs in #440 also contain errors with missing fingerprints. However, the code compiles correctly and RLS does not crash (it just doesn't provide all the functionality). So I don't know if that deduction goes a bit too far.

Anyway, as I said, I have no real idea what happens inside RLS, just that the fingerprint error leads to the crash only sometimes.

cc #132

This is fixed now.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sunshowers picture sunshowers  路  5Comments

paulirotta picture paulirotta  路  3Comments

PumpkinSeed picture PumpkinSeed  路  3Comments

jaccarmac picture jaccarmac  路  3Comments

liufuyang picture liufuyang  路  5Comments