From bf7bea479863164b144c1fcaa60e5798c8e9c353 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 16 May 2022 14:14:21 -0400 Subject: [PATCH 1/5] Update CI channel to beta --- src/ci/channel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/channel b/src/ci/channel index bf867e0ae5b6c..65b2df87f7df3 100644 --- a/src/ci/channel +++ b/src/ci/channel @@ -1 +1 @@ -nightly +beta From 0c75a0ef96fead9a011aac3bd34279ee3f955a95 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 17 May 2022 10:59:26 -0400 Subject: [PATCH 2/5] Bump rls --- Cargo.lock | 50 ++++++++++++++++++++++---------------------------- Cargo.toml | 2 ++ src/tools/rls | 2 +- 3 files changed, 25 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index afe1814de6720..2f143b097b7f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -364,7 +364,7 @@ dependencies = [ "tar", "tempfile", "termcolor", - "toml_edit 0.14.3", + "toml_edit", "unicode-width", "unicode-xid", "url 2.2.2", @@ -451,7 +451,7 @@ dependencies = [ "snapbox", "tar", "termcolor", - "toml_edit 0.14.3", + "toml_edit", "url 2.2.2", ] @@ -2041,15 +2041,6 @@ dependencies = [ "unicase", ] -[[package]] -name = "kstring" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b310ccceade8121d7d77fee406160e457c2f4e7c7982d589da3499bc7ea4526" -dependencies = [ - "serde", -] - [[package]] name = "kstring" version = "2.0.0" @@ -3003,8 +2994,6 @@ dependencies = [ [[package]] name = "racer" version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64954e44fc0d1dcc64e0b9f2b155249ad62849eba25354b76ae1598d1e8f0fa0" dependencies = [ "bitflags", "clap 2.34.0", @@ -3012,10 +3001,28 @@ dependencies = [ "env_logger 0.7.1", "humantime 2.0.1", "lazy_static", + "lazycell", "log", + "racer-cargo-metadata", "rls-span", ] +[[package]] +name = "racer-cargo-metadata" +version = "0.1.2" +dependencies = [ + "racer-interner", + "serde", + "serde_json", +] + +[[package]] +name = "racer-interner" +version = "0.1.0" +dependencies = [ + "serde", +] + [[package]] name = "rand" version = "0.7.3" @@ -3246,7 +3253,7 @@ dependencies = [ "tokio-stream", "tokio-util", "toml", - "toml_edit 0.13.4", + "toml_edit", "url 2.2.2", "walkdir", ] @@ -5320,19 +5327,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_edit" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744e9ed5b352340aa47ce033716991b5589e23781acb97cad37d4ea70560f55b" -dependencies = [ - "combine", - "indexmap", - "itertools", - "kstring 1.0.6", - "serde", -] - [[package]] name = "toml_edit" version = "0.14.3" @@ -5342,7 +5336,7 @@ dependencies = [ "combine", "indexmap", "itertools", - "kstring 2.0.0", + "kstring", "serde", ] diff --git a/Cargo.toml b/Cargo.toml index 4e78399606445..a82389492bbd8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,8 @@ members = [ "src/tools/cargo/crates/credential/cargo-credential-wincred", "src/tools/rustdoc", "src/tools/rls", + "src/tools/rls/racer/metadata", + "src/tools/rls/racer/interner", "src/tools/rustfmt", "src/tools/miri", "src/tools/miri/cargo-miri", diff --git a/src/tools/rls b/src/tools/rls index e6f71c9cadf9b..294e0696b8d5a 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit e6f71c9cadf9bbd2eff21334d1d51016c7f5e19d +Subproject commit 294e0696b8d5a06afb7cb6fd1c2c4638bbb1f148 From fba04fdb141461aefb58d0ffb15857cfc146758f Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 17 May 2022 18:40:34 -0400 Subject: [PATCH 3/5] Revert "Note the importance of using sync pipes" This reverts commit 1e7c15634d3b81b595d669382e45e6e136c730e1. --- library/std/src/sys/windows/process.rs | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs index 8e5325b80e4a5..dd931688becaa 100644 --- a/library/std/src/sys/windows/process.rs +++ b/library/std/src/sys/windows/process.rs @@ -527,25 +527,10 @@ impl Stdio { }, Stdio::MakePipe => { - // Handles that are passed to a child process must be synchronous - // because they will be read synchronously (see #95759). - // Therefore we prefer to make both ends of a pipe synchronous - // just in case our end of the pipe is passed to another process. - // - // However, we may need to read from both the child's stdout and - // stderr simultaneously when waiting for output. This requires - // async reads so as to avoid blocking either pipe. - // - // The solution used here is to make handles synchronous - // except for our side of the stdout and sterr pipes. - // If our side of those pipes do end up being given to another - // process then we use a "pipe relay" to synchronize access - // (see `Stdio::AsyncPipe` below). + // If stdin then make synchronous let pipes = if stdio_id == c::STD_INPUT_HANDLE { - // For stdin both sides of the pipe are synchronous. Pipes::new_synchronous(false, true)? } else { - // For stdout/stderr our side of the pipe is async and their side is synchronous. pipe::anon_pipe(true, true)? }; *pipe = Some(pipes.ours); @@ -582,9 +567,6 @@ impl Stdio { impl From for Stdio { fn from(pipe: AnonPipe) -> Stdio { - // Note that it's very important we don't give async handles to child processes. - // Therefore if the pipe is asynchronous we must have a way to turn it synchronous. - // See #95759. match pipe { AnonPipe::Sync(handle) => Stdio::Handle(handle), AnonPipe::Async(handle) => Stdio::AsyncPipe(handle), From 79256566a9da361793eba86ff1a40caf1560903d Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 17 May 2022 18:40:35 -0400 Subject: [PATCH 4/5] Revert "Windows: Make stdin pipes synchronous" This reverts commit 949b978ec9d63b0eea23d89bad16c6f022ac34a3. --- library/std/src/sys/windows/c.rs | 6 -- library/std/src/sys/windows/pipe.rs | 90 +++++++------------------- library/std/src/sys/windows/process.rs | 20 ++---- 3 files changed, 31 insertions(+), 85 deletions(-) diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index 0692da1d79519..5f14edaf067c0 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -1022,12 +1022,6 @@ extern "system" { bWaitAll: BOOL, dwMilliseconds: DWORD, ) -> DWORD; - pub fn CreatePipe( - hReadPipe: *mut HANDLE, - hWritePipe: *mut HANDLE, - lpPipeAttributes: *const SECURITY_ATTRIBUTES, - nSize: DWORD, - ) -> BOOL; pub fn CreateNamedPipeW( lpName: LPCWSTR, dwOpenMode: DWORD, diff --git a/library/std/src/sys/windows/pipe.rs b/library/std/src/sys/windows/pipe.rs index 928bf2439c3e1..013c776c476c3 100644 --- a/library/std/src/sys/windows/pipe.rs +++ b/library/std/src/sys/windows/pipe.rs @@ -18,20 +18,13 @@ use crate::sys_common::IntoInner; // Anonymous pipes //////////////////////////////////////////////////////////////////////////////// -// A 64kb pipe capacity is the same as a typical Linux default. -const PIPE_BUFFER_CAPACITY: u32 = 64 * 1024; - -pub enum AnonPipe { - Sync(Handle), - Async(Handle), +pub struct AnonPipe { + inner: Handle, } impl IntoInner for AnonPipe { fn into_inner(self) -> Handle { - match self { - Self::Sync(handle) => handle, - Self::Async(handle) => handle, - } + self.inner } } @@ -39,35 +32,6 @@ pub struct Pipes { pub ours: AnonPipe, pub theirs: AnonPipe, } -impl Pipes { - /// Create a new pair of pipes where both pipes are synchronous. - /// - /// These must not be used asynchronously. - pub fn new_synchronous( - ours_readable: bool, - their_handle_inheritable: bool, - ) -> io::Result { - unsafe { - // If `CreatePipe` succeeds, these will be our pipes. - let mut read = ptr::null_mut(); - let mut write = ptr::null_mut(); - - if c::CreatePipe(&mut read, &mut write, ptr::null(), PIPE_BUFFER_CAPACITY) == 0 { - Err(io::Error::last_os_error()) - } else { - let (ours, theirs) = if ours_readable { (read, write) } else { (write, read) }; - let ours = Handle::from_raw_handle(ours); - let theirs = Handle::from_raw_handle(theirs); - - if their_handle_inheritable { - theirs.set_inheritable()?; - } - - Ok(Pipes { ours: AnonPipe::Sync(ours), theirs: AnonPipe::Sync(theirs) }) - } - } - } -} /// Although this looks similar to `anon_pipe` in the Unix module it's actually /// subtly different. Here we'll return two pipes in the `Pipes` return value, @@ -89,6 +53,9 @@ impl Pipes { /// with `OVERLAPPED` instances, but also works out ok if it's only ever used /// once at a time (which we do indeed guarantee). pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Result { + // A 64kb pipe capacity is the same as a typical Linux default. + const PIPE_BUFFER_CAPACITY: u32 = 64 * 1024; + // Note that we specifically do *not* use `CreatePipe` here because // unfortunately the anonymous pipes returned do not support overlapped // operations. Instead, we create a "hopefully unique" name and create a @@ -189,9 +156,12 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res }; opts.security_attributes(&mut sa); let theirs = File::open(Path::new(&name), &opts)?; - let theirs = AnonPipe::Sync(theirs.into_inner()); + let theirs = AnonPipe { inner: theirs.into_inner() }; - Ok(Pipes { ours: AnonPipe::Async(ours), theirs }) + Ok(Pipes { + ours: AnonPipe { inner: ours }, + theirs: AnonPipe { inner: theirs.into_inner() }, + }) } } @@ -201,12 +171,12 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res /// This is achieved by creating a new set of pipes and spawning a thread that /// relays messages between the source and the synchronous pipe. pub fn spawn_pipe_relay( - source: &Handle, + source: &AnonPipe, ours_readable: bool, their_handle_inheritable: bool, ) -> io::Result { // We need this handle to live for the lifetime of the thread spawned below. - let source = AnonPipe::Async(source.duplicate(0, true, c::DUPLICATE_SAME_ACCESS)?); + let source = source.duplicate()?; // create a new pair of anon pipes. let Pipes { theirs, ours } = anon_pipe(ours_readable, their_handle_inheritable)?; @@ -257,24 +227,19 @@ type AlertableIoFn = unsafe extern "system" fn( impl AnonPipe { pub fn handle(&self) -> &Handle { - match self { - Self::Async(ref handle) => handle, - Self::Sync(ref handle) => handle, - } + &self.inner } pub fn into_handle(self) -> Handle { - self.into_inner() + self.inner + } + fn duplicate(&self) -> io::Result { + self.inner.duplicate(0, false, c::DUPLICATE_SAME_ACCESS).map(|inner| AnonPipe { inner }) } pub fn read(&self, buf: &mut [u8]) -> io::Result { let result = unsafe { let len = crate::cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD; - match self { - Self::Sync(ref handle) => handle.read(buf), - Self::Async(_) => { - self.alertable_io_internal(c::ReadFileEx, buf.as_mut_ptr() as _, len) - } - } + self.alertable_io_internal(c::ReadFileEx, buf.as_mut_ptr() as _, len) }; match result { @@ -288,33 +253,28 @@ impl AnonPipe { } pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { - io::default_read_vectored(|buf| self.read(buf), bufs) + self.inner.read_vectored(bufs) } #[inline] pub fn is_read_vectored(&self) -> bool { - false + self.inner.is_read_vectored() } pub fn write(&self, buf: &[u8]) -> io::Result { unsafe { let len = crate::cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD; - match self { - Self::Sync(ref handle) => handle.write(buf), - Self::Async(_) => { - self.alertable_io_internal(c::WriteFileEx, buf.as_ptr() as _, len) - } - } + self.alertable_io_internal(c::WriteFileEx, buf.as_ptr() as _, len) } } pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { - io::default_write_vectored(|buf| self.write(buf), bufs) + self.inner.write_vectored(bufs) } #[inline] pub fn is_write_vectored(&self) -> bool { - false + self.inner.is_write_vectored() } /// Synchronizes asynchronous reads or writes using our anonymous pipe. @@ -386,7 +346,7 @@ impl AnonPipe { // Asynchronous read of the pipe. // If successful, `callback` will be called once it completes. - let result = io(self.handle().as_handle(), buf, len, &mut overlapped, callback); + let result = io(self.inner.as_handle(), buf, len, &mut overlapped, callback); if result == c::FALSE { // We can return here because the call failed. // After this we must not return until the I/O completes. diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs index dd931688becaa..9fd399f4ba1d3 100644 --- a/library/std/src/sys/windows/process.rs +++ b/library/std/src/sys/windows/process.rs @@ -23,7 +23,7 @@ use crate::sys::cvt; use crate::sys::fs::{File, OpenOptions}; use crate::sys::handle::Handle; use crate::sys::path; -use crate::sys::pipe::{self, AnonPipe, Pipes}; +use crate::sys::pipe::{self, AnonPipe}; use crate::sys::stdio; use crate::sys_common::mutex::StaticMutex; use crate::sys_common::process::{CommandEnv, CommandEnvs}; @@ -172,7 +172,7 @@ pub enum Stdio { Inherit, Null, MakePipe, - AsyncPipe(Handle), + Pipe(AnonPipe), Handle(Handle), } @@ -527,18 +527,13 @@ impl Stdio { }, Stdio::MakePipe => { - // If stdin then make synchronous - let pipes = if stdio_id == c::STD_INPUT_HANDLE { - Pipes::new_synchronous(false, true)? - } else { - pipe::anon_pipe(true, true)? - }; + let ours_readable = stdio_id != c::STD_INPUT_HANDLE; + let pipes = pipe::anon_pipe(ours_readable, true)?; *pipe = Some(pipes.ours); Ok(pipes.theirs.into_handle()) } - Stdio::AsyncPipe(ref source) => { - // We need to synchronize asynchronous pipes by using a pipe relay. + Stdio::Pipe(ref source) => { let ours_readable = stdio_id != c::STD_INPUT_HANDLE; pipe::spawn_pipe_relay(source, ours_readable, true).map(AnonPipe::into_handle) } @@ -567,10 +562,7 @@ impl Stdio { impl From for Stdio { fn from(pipe: AnonPipe) -> Stdio { - match pipe { - AnonPipe::Sync(handle) => Stdio::Handle(handle), - AnonPipe::Async(handle) => Stdio::AsyncPipe(handle), - } + Stdio::Pipe(pipe) } } From 61aebf7570fa2b270a1689482884f90a57185491 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 17 May 2022 18:40:37 -0400 Subject: [PATCH 5/5] Revert "Add `set_inheritable` for Windows `Handle`s" This reverts commit b89b0567427932fe37851a314610d795258f1834. --- library/std/src/os/windows/io/handle.rs | 12 ------------ library/std/src/sys/windows/handle.rs | 4 ---- 2 files changed, 16 deletions(-) diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs index f27970eaaf122..90a5b7466fec4 100644 --- a/library/std/src/os/windows/io/handle.rs +++ b/library/std/src/os/windows/io/handle.rs @@ -204,18 +204,6 @@ impl OwnedHandle { })?; unsafe { Ok(Self::from_raw_handle(ret)) } } - - /// Allow child processes to inherit the handle. - pub(crate) fn set_inheritable(&self) -> io::Result<()> { - cvt(unsafe { - c::SetHandleInformation( - self.as_raw_handle(), - c::HANDLE_FLAG_INHERIT, - c::HANDLE_FLAG_INHERIT, - ) - })?; - Ok(()) - } } impl TryFrom for OwnedHandle { diff --git a/library/std/src/sys/windows/handle.rs b/library/std/src/sys/windows/handle.rs index 3b609825a79da..ef9a8bd690031 100644 --- a/library/std/src/sys/windows/handle.rs +++ b/library/std/src/sys/windows/handle.rs @@ -221,10 +221,6 @@ impl Handle { Ok(Self(self.0.duplicate(access, inherit, options)?)) } - pub(crate) fn set_inheritable(&self) -> io::Result<()> { - self.0.set_inheritable() - } - /// Performs a synchronous read. /// /// If the handle is opened for asynchronous I/O then this abort the process.