From b7c0813eb74db4706f7eb1943d0160e6501f6bc1 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 18 Feb 2015 16:39:32 -0800 Subject: [PATCH] Round 4 test fixes and rebase conflicts --- src/libcollections/lib.rs | 2 +- src/libcollections/linked_list.rs | 2 +- src/libcollections/slice.rs | 4 +- src/libcore/marker.rs | 6 +- src/libstd/sys/windows/c.rs | 2 +- src/libstd/sys/windows/process.rs | 166 +++++++++++++++++- .../compile-fail/object-safety-phantom-fn.rs | 6 + ...c-type-in-supertrait-outlives-container.rs | 3 - ...egions-assoc-type-outlives-container-wc.rs | 3 - .../regions-assoc-type-outlives-container.rs | 3 - src/test/run-pass/trait-impl.rs | 2 +- 11 files changed, 180 insertions(+), 19 deletions(-) diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 8fce626755ee..6569ab9c05ac 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -147,7 +147,6 @@ mod std { #[cfg(test)] mod prelude { // from core. - pub use core::borrow::IntoCow; pub use core::clone::Clone; pub use core::cmp::{PartialEq, Eq, PartialOrd, Ord}; pub use core::cmp::Ordering::{Less, Equal, Greater}; @@ -173,6 +172,7 @@ mod prelude { pub use unicode::char::CharExt; // from collections. + pub use borrow::IntoCow; pub use slice::SliceConcatExt; pub use string::{String, ToString}; pub use vec::Vec; diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs index 1c4b34b4650f..c142819a5189 100644 --- a/src/libcollections/linked_list.rs +++ b/src/libcollections/linked_list.rs @@ -1041,7 +1041,7 @@ mod tests { } #[cfg(test)] - fn list_from(v: &[T]) -> DList { + fn list_from(v: &[T]) -> LinkedList { v.iter().cloned().collect() } diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 0abe7f120eac..776b8b3af147 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -1997,9 +1997,9 @@ mod tests { #[test] fn test_lexicographic_permutations_empty_and_short() { - let empty : &mut[i32] = &mut[..]; + let empty : &mut[i32] = &mut[]; assert!(empty.next_permutation() == false); - let b: &mut[i32] = &mut[..]; + let b: &mut[i32] = &mut[]; assert!(empty == b); assert!(empty.prev_permutation() == false); assert!(empty == b); diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index dbe6db86adab..d284eb341792 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -301,7 +301,7 @@ impl MarkerTrait for T { } /// As an example, consider a trait with no methods like `Even`, meant /// to represent types that are "even": /// -/// ```rust +/// ```rust,ignore /// trait Even { } /// ``` /// @@ -310,7 +310,7 @@ impl MarkerTrait for T { } /// categorize types (and hence instances of those types) as "even" or /// not, so if we *were* going to have a method, it might look like: /// -/// ```rust +/// ```rust,ignore /// trait Even { /// fn is_even(self) -> bool { true } /// } @@ -319,7 +319,7 @@ impl MarkerTrait for T { } /// Therefore, we can model a method like this as follows: /// /// ```rust -/// use std::marker::PhantomFn +/// use std::marker::PhantomFn; /// trait Even : PhantomFn { } /// ``` /// diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index f861255a00a1..2d1a5e10bd63 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -283,7 +283,7 @@ pub mod compat { fallback: usize) -> usize { let mut module: Vec = module.utf16_units().collect(); module.push(0); - let symbol = CString::from_slice(symbol.as_bytes()); + let symbol = CString::new(symbol).unwrap(); let func = unsafe { let handle = GetModuleHandleW(module.as_ptr()); GetProcAddress(handle, symbol.as_ptr()) as usize diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index 96ffc4daddd4..e001cd9a1ec8 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -10,7 +10,7 @@ use prelude::v1::*; -use collections::hash_map::Hasher; +#[cfg(stage0)] use collections::hash_map::Hasher; use collections; use env; use ffi::CString; @@ -106,6 +106,7 @@ impl Process { } #[allow(deprecated)] + #[cfg(stage0)] pub fn spawn(cfg: &C, in_fd: Option

, out_fd: Option

, err_fd: Option

) -> IoResult @@ -267,6 +268,169 @@ impl Process { }) } } + #[allow(deprecated)] + #[cfg(not(stage0))] + pub fn spawn(cfg: &C, in_fd: Option

, + out_fd: Option

, err_fd: Option

) + -> IoResult + where C: ProcessConfig, P: AsInner, + K: BytesContainer + Eq + Hash, V: BytesContainer + { + use libc::types::os::arch::extra::{DWORD, HANDLE, STARTUPINFO}; + use libc::consts::os::extra::{ + TRUE, FALSE, + STARTF_USESTDHANDLES, + INVALID_HANDLE_VALUE, + DUPLICATE_SAME_ACCESS + }; + use libc::funcs::extra::kernel32::{ + GetCurrentProcess, + DuplicateHandle, + CloseHandle, + CreateProcessW + }; + use libc::funcs::extra::msvcrt::get_osfhandle; + + use mem; + use iter::IteratorExt; + use str::StrExt; + + if cfg.gid().is_some() || cfg.uid().is_some() { + return Err(IoError { + kind: old_io::IoUnavailable, + desc: "unsupported gid/uid requested on windows", + detail: None, + }) + } + + // To have the spawning semantics of unix/windows stay the same, we need to + // read the *child's* PATH if one is provided. See #15149 for more details. + let program = cfg.env().and_then(|env| { + for (key, v) in env { + if b"PATH" != key.container_as_bytes() { continue } + + // Split the value and test each path to see if the + // program exists. + for path in os::split_paths(v.container_as_bytes()) { + let path = path.join(cfg.program().as_bytes()) + .with_extension(env::consts::EXE_EXTENSION); + if path.exists() { + return Some(CString::from_slice(path.as_vec())) + } + } + break + } + None + }); + + unsafe { + let mut si = zeroed_startupinfo(); + si.cb = mem::size_of::() as DWORD; + si.dwFlags = STARTF_USESTDHANDLES; + + let cur_proc = GetCurrentProcess(); + + // Similarly to unix, we don't actually leave holes for the stdio file + // descriptors, but rather open up /dev/null equivalents. These + // equivalents are drawn from libuv's windows process spawning. + let set_fd = |fd: &Option

, slot: &mut HANDLE, + is_stdin: bool| { + match *fd { + None => { + let access = if is_stdin { + libc::FILE_GENERIC_READ + } else { + libc::FILE_GENERIC_WRITE | libc::FILE_READ_ATTRIBUTES + }; + let size = mem::size_of::(); + let mut sa = libc::SECURITY_ATTRIBUTES { + nLength: size as libc::DWORD, + lpSecurityDescriptor: ptr::null_mut(), + bInheritHandle: 1, + }; + let mut filename: Vec = "NUL".utf16_units().collect(); + filename.push(0); + *slot = libc::CreateFileW(filename.as_ptr(), + access, + libc::FILE_SHARE_READ | + libc::FILE_SHARE_WRITE, + &mut sa, + libc::OPEN_EXISTING, + 0, + ptr::null_mut()); + if *slot == INVALID_HANDLE_VALUE { + return Err(super::last_error()) + } + } + Some(ref fd) => { + let orig = get_osfhandle(fd.as_inner().fd()) as HANDLE; + if orig == INVALID_HANDLE_VALUE { + return Err(super::last_error()) + } + if DuplicateHandle(cur_proc, orig, cur_proc, slot, + 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE { + return Err(super::last_error()) + } + } + } + Ok(()) + }; + + try!(set_fd(&in_fd, &mut si.hStdInput, true)); + try!(set_fd(&out_fd, &mut si.hStdOutput, false)); + try!(set_fd(&err_fd, &mut si.hStdError, false)); + + let cmd_str = make_command_line(program.as_ref().unwrap_or(cfg.program()), + cfg.args()); + let mut pi = zeroed_process_information(); + let mut create_err = None; + + // stolen from the libuv code. + let mut flags = libc::CREATE_UNICODE_ENVIRONMENT; + if cfg.detach() { + flags |= libc::DETACHED_PROCESS | libc::CREATE_NEW_PROCESS_GROUP; + } + + with_envp(cfg.env(), |envp| { + with_dirp(cfg.cwd(), |dirp| { + let mut cmd_str: Vec = cmd_str.utf16_units().collect(); + cmd_str.push(0); + let _lock = CREATE_PROCESS_LOCK.lock().unwrap(); + let created = CreateProcessW(ptr::null(), + cmd_str.as_mut_ptr(), + ptr::null_mut(), + ptr::null_mut(), + TRUE, + flags, envp, dirp, + &mut si, &mut pi); + if created == FALSE { + create_err = Some(super::last_error()); + } + }) + }); + + assert!(CloseHandle(si.hStdInput) != 0); + assert!(CloseHandle(si.hStdOutput) != 0); + assert!(CloseHandle(si.hStdError) != 0); + + match create_err { + Some(err) => return Err(err), + None => {} + } + + // We close the thread handle because we don't care about keeping the + // thread id valid, and we aren't keeping the thread handle around to be + // able to close it later. We don't close the process handle however + // because std::we want the process id to stay valid at least until the + // calling code closes the process handle. + assert!(CloseHandle(pi.hThread) != 0); + + Ok(Process { + pid: pi.dwProcessId as pid_t, + handle: pi.hProcess as *mut () + }) + } + } /// Waits for a process to exit and returns the exit code, failing /// if there is no process with the specified id. diff --git a/src/test/compile-fail/object-safety-phantom-fn.rs b/src/test/compile-fail/object-safety-phantom-fn.rs index fb30ce5c2455..1c95ee43d27a 100644 --- a/src/test/compile-fail/object-safety-phantom-fn.rs +++ b/src/test/compile-fail/object-safety-phantom-fn.rs @@ -11,10 +11,16 @@ // Check that `Self` appearing in a phantom fn does not make a trait not object safe. #![feature(rustc_attrs)] +#![allow(dead_code)] + +use std::marker::PhantomFn; trait Baz : PhantomFn { } +trait Bar : PhantomFn<(Self, T)> { +} + fn make_bar>(t: &T) -> &Bar { t } diff --git a/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs b/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs index fa26c9c54c8f..e96c345034bc 100644 --- a/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs +++ b/src/test/compile-fail/regions-assoc-type-in-supertrait-outlives-container.rs @@ -15,9 +15,6 @@ #![allow(dead_code)] -use std::mem::transmute; -use std::ops::Deref; - /////////////////////////////////////////////////////////////////////////// pub trait TheTrait { diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs b/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs index 6ee65fbdf919..6d8a02ab1748 100644 --- a/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs +++ b/src/test/compile-fail/regions-assoc-type-outlives-container-wc.rs @@ -15,9 +15,6 @@ #![allow(dead_code)] -use std::mem::transmute; -use std::ops::Deref; - /////////////////////////////////////////////////////////////////////////// pub trait TheTrait { diff --git a/src/test/compile-fail/regions-assoc-type-outlives-container.rs b/src/test/compile-fail/regions-assoc-type-outlives-container.rs index 49a0726fa3b7..5fafec50a4b5 100644 --- a/src/test/compile-fail/regions-assoc-type-outlives-container.rs +++ b/src/test/compile-fail/regions-assoc-type-outlives-container.rs @@ -14,9 +14,6 @@ #![allow(dead_code)] -use std::mem::transmute; -use std::ops::Deref; - /////////////////////////////////////////////////////////////////////////// pub trait TheTrait { diff --git a/src/test/run-pass/trait-impl.rs b/src/test/run-pass/trait-impl.rs index 7db1d7d031e3..325fba8a0ee4 100644 --- a/src/test/run-pass/trait-impl.rs +++ b/src/test/run-pass/trait-impl.rs @@ -17,7 +17,7 @@ use traitimpl::Bar; static mut COUNT: uint = 1; trait T { - fn foo(&self) {} + fn t(&self) {} } impl<'a> T+'a {