Auto merge of #62335 - Mark-Simulacrum:rollup-0pcaz5a, r=Mark-Simulacrum
Rollup of 15 pull requests Successful merges: - #62021 (MSVC link output improve) - #62064 (nth_back for chunks_exact) - #62128 (Adjust warning of -C extra-filename with -o.) - #62161 (Add missing links for TryFrom docs) - #62183 (std: Move a process test out of libstd) - #62186 (Add missing type urls in Into trait) - #62196 (Add Vec::leak) - #62199 (import gdb for explicit access to gdb.current_objfile()) - #62229 (Enable intptrcast for explicit casts) - #62250 (Improve box clone doctests to ensure the documentation is valid) - #62255 (Switch tracking issue for `#![feature(slice_patterns)]`) - #62285 (Fix michaelwoerister's mailmap) - #62304 (HashMap is UnwindSafe) - #62319 (Fix mismatching Kleene operators) - #62327 (Fixed document bug, those replaced each other) Failed merges: r? @ghost
This commit is contained in:
commit
088b987307
2
.mailmap
2
.mailmap
@ -167,6 +167,8 @@ Matthijs Hofstra <thiezz@gmail.com>
|
||||
Melody Horn <melody@boringcactus.com> <mathphreak@gmail.com>
|
||||
Michael Williams <m.t.williams@live.com>
|
||||
Michael Woerister <michaelwoerister@posteo> <michaelwoerister@gmail>
|
||||
Michael Woerister <michaelwoerister@posteo> <michaelwoerister@users.noreply.github.com>
|
||||
Michael Woerister <michaelwoerister@posteo> <michaelwoerister@posteo.net>
|
||||
Mickaël Raybaud-Roig <raybaudroigm@gmail.com> m-r-r <raybaudroigm@gmail.com>
|
||||
Ms2ger <ms2ger@gmail.com> <Ms2ger@gmail.com>
|
||||
Mukilan Thiagarajan <mukilanthiagarajan@gmail.com>
|
||||
|
@ -1,8 +1,8 @@
|
||||
# `slice_patterns`
|
||||
|
||||
The tracking issue for this feature is: [#23121]
|
||||
The tracking issue for this feature is: [#62254]
|
||||
|
||||
[#23121]: https://github.com/rust-lang/rust/issues/23121
|
||||
[#62254]: https://github.com/rust-lang/rust/issues/62254
|
||||
|
||||
------------------------
|
||||
|
||||
|
@ -1,2 +1,3 @@
|
||||
import gdb
|
||||
import gdb_rust_pretty_printing
|
||||
gdb_rust_pretty_printing.register_printers(gdb.current_objfile())
|
||||
|
@ -367,12 +367,19 @@ impl<T: Clone> Clone for Box<T> {
|
||||
/// ```
|
||||
/// let x = Box::new(5);
|
||||
/// let y = x.clone();
|
||||
///
|
||||
/// // The value is the same
|
||||
/// assert_eq!(x, y);
|
||||
///
|
||||
/// // But they are unique objects
|
||||
/// assert_ne!(&*x as *const i32, &*y as *const i32);
|
||||
/// ```
|
||||
#[rustfmt::skip]
|
||||
#[inline]
|
||||
fn clone(&self) -> Box<T> {
|
||||
box { (**self).clone() }
|
||||
}
|
||||
|
||||
/// Copies `source`'s contents into `self` without creating a new allocation.
|
||||
///
|
||||
/// # Examples
|
||||
@ -380,10 +387,15 @@ impl<T: Clone> Clone for Box<T> {
|
||||
/// ```
|
||||
/// let x = Box::new(5);
|
||||
/// let mut y = Box::new(10);
|
||||
/// let yp: *const i32 = &*y;
|
||||
///
|
||||
/// y.clone_from(&x);
|
||||
///
|
||||
/// assert_eq!(*y, 5);
|
||||
/// // The value is the same
|
||||
/// assert_eq!(x, y);
|
||||
///
|
||||
/// // And no allocation occurred
|
||||
/// assert_eq!(yp, &*y);
|
||||
/// ```
|
||||
#[inline]
|
||||
fn clone_from(&mut self, source: &Box<T>) {
|
||||
|
@ -1367,6 +1367,40 @@ impl<T> Vec<T> {
|
||||
self.truncate(new_len);
|
||||
}
|
||||
}
|
||||
|
||||
/// Consumes and leaks the `Vec`, returning a mutable reference to the contents,
|
||||
/// `&'a mut [T]`. Note that the type `T` must outlive the chosen lifetime
|
||||
/// `'a`. If the type has only static references, or none at all, then this
|
||||
/// may be chosen to be `'static`.
|
||||
///
|
||||
/// This function is similar to the `leak` function on `Box`.
|
||||
///
|
||||
/// This function is mainly useful for data that lives for the remainder of
|
||||
/// the program's life. Dropping the returned reference will cause a memory
|
||||
/// leak.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Simple usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(vec_leak)]
|
||||
///
|
||||
/// fn main() {
|
||||
/// let x = vec![1, 2, 3];
|
||||
/// let static_ref: &'static mut [usize] = Vec::leak(x);
|
||||
/// static_ref[0] += 1;
|
||||
/// assert_eq!(static_ref, &[2, 2, 3]);
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "vec_leak", issue = "62195")]
|
||||
#[inline]
|
||||
pub fn leak<'a>(vec: Vec<T>) -> &'a mut [T]
|
||||
where
|
||||
T: 'a // Technically not needed, but kept to be explicit.
|
||||
{
|
||||
Box::leak(vec.into_boxed_slice())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> Vec<T> {
|
||||
|
@ -251,12 +251,12 @@ pub trait AsMut<T: ?Sized> {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// [`String`] implements `Into<Vec<u8>>`:
|
||||
/// [`String`] implements [`Into`]`<`[`Vec`]`<`[`u8`]`>>`:
|
||||
///
|
||||
/// In order to express that we want a generic function to take all arguments that can be
|
||||
/// converted to a specified type `T`, we can use a trait bound of [`Into`]`<T>`.
|
||||
/// For example: The function `is_hello` takes all arguments that can be converted into a
|
||||
/// `Vec<u8>`.
|
||||
/// [`Vec`]`<`[`u8`]`>`.
|
||||
///
|
||||
/// ```
|
||||
/// fn is_hello<T: Into<Vec<u8>>>(s: T) {
|
||||
@ -274,6 +274,7 @@ pub trait AsMut<T: ?Sized> {
|
||||
/// [`String`]: ../../std/string/struct.String.html
|
||||
/// [`From`]: trait.From.html
|
||||
/// [`Into`]: trait.Into.html
|
||||
/// [`Vec`]: ../../std/vec/struct.Vec.html
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait Into<T>: Sized {
|
||||
/// Performs the conversion.
|
||||
@ -410,12 +411,12 @@ pub trait TryInto<T>: Sized {
|
||||
///
|
||||
/// This is useful when you are doing a type conversion that may
|
||||
/// trivially succeed but may also need special handling.
|
||||
/// For example, there is no way to convert an `i64` into an `i32`
|
||||
/// using the [`From`] trait, because an `i64` may contain a value
|
||||
/// that an `i32` cannot represent and so the conversion would lose data.
|
||||
/// This might be handled by truncating the `i64` to an `i32` (essentially
|
||||
/// giving the `i64`'s value modulo `i32::MAX`) or by simply returning
|
||||
/// `i32::MAX`, or by some other method. The `From` trait is intended
|
||||
/// For example, there is no way to convert an [`i64`] into an [`i32`]
|
||||
/// using the [`From`] trait, because an [`i64`] may contain a value
|
||||
/// that an [`i32`] cannot represent and so the conversion would lose data.
|
||||
/// This might be handled by truncating the [`i64`] to an [`i32`] (essentially
|
||||
/// giving the [`i64`]'s value modulo [`i32::MAX`]) or by simply returning
|
||||
/// [`i32::MAX`], or by some other method. The [`From`] trait is intended
|
||||
/// for perfect conversions, so the `TryFrom` trait informs the
|
||||
/// programmer when a type conversion could go bad and lets them
|
||||
/// decide how to handle it.
|
||||
@ -425,8 +426,8 @@ pub trait TryInto<T>: Sized {
|
||||
/// - `TryFrom<T> for U` implies [`TryInto`]`<U> for T`
|
||||
/// - [`try_from`] is reflexive, which means that `TryFrom<T> for T`
|
||||
/// is implemented and cannot fail -- the associated `Error` type for
|
||||
/// calling `T::try_from()` on a value of type `T` is `Infallible`.
|
||||
/// When the `!` type is stablized `Infallible` and `!` will be
|
||||
/// calling `T::try_from()` on a value of type `T` is [`Infallible`].
|
||||
/// When the [`!`] type is stablized [`Infallible`] and [`!`] will be
|
||||
/// equivalent.
|
||||
///
|
||||
/// `TryFrom<T>` can be implemented as follows:
|
||||
@ -451,7 +452,7 @@ pub trait TryInto<T>: Sized {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// As described, [`i32`] implements `TryFrom<i64>`:
|
||||
/// As described, [`i32`] implements `TryFrom<`[`i64`]`>`:
|
||||
///
|
||||
/// ```
|
||||
/// use std::convert::TryFrom;
|
||||
@ -474,6 +475,8 @@ pub trait TryInto<T>: Sized {
|
||||
///
|
||||
/// [`try_from`]: trait.TryFrom.html#tymethod.try_from
|
||||
/// [`TryInto`]: trait.TryInto.html
|
||||
/// [`i32::MAX`]: ../../std/i32/constant.MAX.html
|
||||
/// [`!`]: ../../std/primitive.never.html
|
||||
#[stable(feature = "try_from", since = "1.34.0")]
|
||||
pub trait TryFrom<T>: Sized {
|
||||
/// The type returned in the event of a conversion error.
|
||||
|
@ -4453,6 +4453,21 @@ impl<'a, T> DoubleEndedIterator for ChunksExact<'a, T> {
|
||||
Some(snd)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
|
||||
let len = self.len();
|
||||
if n >= len {
|
||||
self.v = &[];
|
||||
None
|
||||
} else {
|
||||
let start = (len - 1 - n) * self.chunk_size;
|
||||
let end = start + self.chunk_size;
|
||||
let nth_back = &self.v[start..end];
|
||||
self.v = &self.v[..start];
|
||||
Some(nth_back)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "chunks_exact", since = "1.31.0")]
|
||||
|
@ -3716,10 +3716,10 @@ impl str {
|
||||
///
|
||||
/// # Text directionality
|
||||
///
|
||||
/// A string is a sequence of bytes. 'Left' in this context means the first
|
||||
/// position of that byte string; for a language like Arabic or Hebrew
|
||||
/// which are 'right to left' rather than 'left to right', this will be
|
||||
/// the _right_ side, not the left.
|
||||
/// A string is a sequence of bytes. `start` in this context means the first
|
||||
/// position of that byte string; for a left-to-right language like English or
|
||||
/// Russian, this will be left side, and for right-to-left languages like
|
||||
/// like Arabic or Hebrew, this will be the right side.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -3755,10 +3755,10 @@ impl str {
|
||||
///
|
||||
/// # Text directionality
|
||||
///
|
||||
/// A string is a sequence of bytes. 'Right' in this context means the last
|
||||
/// position of that byte string; for a language like Arabic or Hebrew
|
||||
/// which are 'right to left' rather than 'left to right', this will be
|
||||
/// the _left_ side, not the right.
|
||||
/// A string is a sequence of bytes. `end` in this context means the last
|
||||
/// position of that byte string; for a left-to-right language like English or
|
||||
/// Russian, this will be right side, and for right-to-left languages like
|
||||
/// like Arabic or Hebrew, this will be the left side.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -3804,10 +3804,10 @@ impl str {
|
||||
///
|
||||
/// # Text directionality
|
||||
///
|
||||
/// A string is a sequence of bytes. `start` in this context means the first
|
||||
/// position of that byte string; for a left-to-right language like English or
|
||||
/// Russian, this will be left side, and for right-to-left languages like
|
||||
/// like Arabic or Hebrew, this will be the right side.
|
||||
/// A string is a sequence of bytes. 'Left' in this context means the first
|
||||
/// position of that byte string; for a language like Arabic or Hebrew
|
||||
/// which are 'right to left' rather than 'left to right', this will be
|
||||
/// the _right_ side, not the left.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -3840,10 +3840,10 @@ impl str {
|
||||
///
|
||||
/// # Text directionality
|
||||
///
|
||||
/// A string is a sequence of bytes. `end` in this context means the last
|
||||
/// position of that byte string; for a left-to-right language like English or
|
||||
/// Russian, this will be right side, and for right-to-left languages like
|
||||
/// like Arabic or Hebrew, this will be the left side.
|
||||
/// A string is a sequence of bytes. 'Right' in this context means the last
|
||||
/// position of that byte string; for a language like Arabic or Hebrew
|
||||
/// which are 'right to left' rather than 'left to right', this will be
|
||||
/// the _left_ side, not the right.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -151,7 +151,7 @@ macro_rules! assert_none {
|
||||
stringify!($what), b);
|
||||
}
|
||||
}
|
||||
)*
|
||||
)+
|
||||
}};
|
||||
($what:ident, $($str:tt),+,) => (assert_none!($what,$($str),+))
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use std::str::pattern::*;
|
||||
macro_rules! search_asserts {
|
||||
($haystack:expr, $needle:expr, $testname:expr, [$($func:ident),*], $result:expr) => {
|
||||
let mut searcher = $needle.into_searcher($haystack);
|
||||
let arr = [$( Step::from(searcher.$func()) ),+];
|
||||
let arr = [$( Step::from(searcher.$func()) ),*];
|
||||
assert_eq!(&arr[..], &$result, $testname);
|
||||
}
|
||||
}
|
||||
|
@ -275,6 +275,25 @@ fn test_chunks_exact_nth() {
|
||||
assert_eq!(c2.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_chunks_exact_nth_back() {
|
||||
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
|
||||
let mut c = v.chunks_exact(2);
|
||||
assert_eq!(c.nth_back(1).unwrap(), &[2, 3]);
|
||||
assert_eq!(c.next().unwrap(), &[0, 1]);
|
||||
assert_eq!(c.next(), None);
|
||||
|
||||
let v2: &[i32] = &[0, 1, 2, 3, 4];
|
||||
let mut c2 = v2.chunks_exact(3);
|
||||
assert_eq!(c2.nth_back(0).unwrap(), &[0, 1, 2]);
|
||||
assert_eq!(c2.next(), None);
|
||||
assert_eq!(c2.next_back(), None);
|
||||
|
||||
let v3: &[i32] = &[0, 1, 2, 3, 4];
|
||||
let mut c3 = v3.chunks_exact(10);
|
||||
assert_eq!(c3.nth_back(0), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_chunks_exact_last() {
|
||||
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
|
||||
|
@ -653,10 +653,14 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
|
||||
linker_error.emit();
|
||||
|
||||
if sess.target.target.options.is_like_msvc && linker_not_found {
|
||||
sess.note_without_error("the msvc targets depend on the msvc linker \
|
||||
but `link.exe` was not found");
|
||||
sess.note_without_error("please ensure that VS 2013, VS 2015 or VS 2017 \
|
||||
was installed with the Visual C++ option");
|
||||
sess.note_without_error(
|
||||
"the msvc targets depend on the msvc linker \
|
||||
but `link.exe` was not found",
|
||||
);
|
||||
sess.note_without_error(
|
||||
"please ensure that VS 2013, VS 2015, VS 2017 or VS 2019 \
|
||||
was installed with the Visual C++ option",
|
||||
);
|
||||
}
|
||||
sess.abort_if_errors();
|
||||
}
|
||||
|
@ -642,14 +642,14 @@ pub fn build_output_filenames(
|
||||
);
|
||||
None
|
||||
} else {
|
||||
if !sess.opts.cg.extra_filename.is_empty() {
|
||||
sess.warn("ignoring -C extra-filename flag due to -o flag");
|
||||
}
|
||||
Some(out_file.clone())
|
||||
};
|
||||
if *odir != None {
|
||||
sess.warn("ignoring --out-dir flag due to -o flag");
|
||||
}
|
||||
if !sess.opts.cg.extra_filename.is_empty() {
|
||||
sess.warn("ignoring -C extra-filename flag due to -o flag");
|
||||
}
|
||||
|
||||
OutputFilenames {
|
||||
out_directory: out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(),
|
||||
|
@ -1,7 +1,7 @@
|
||||
use rustc::ty::{self, Ty, TypeAndMut};
|
||||
use rustc::ty::layout::{self, TyLayout, Size};
|
||||
use rustc::ty::adjustment::{PointerCast};
|
||||
use syntax::ast::{FloatTy, IntTy, UintTy};
|
||||
use syntax::ast::FloatTy;
|
||||
use syntax::symbol::sym;
|
||||
|
||||
use rustc_apfloat::ieee::{Single, Double};
|
||||
@ -151,7 +151,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
|
||||
"Unexpected cast from type {:?}", src_layout.ty
|
||||
);
|
||||
match val.to_bits_or_ptr(src_layout.size, self) {
|
||||
Err(ptr) => self.cast_from_ptr(ptr, dest_layout.ty),
|
||||
Err(ptr) => self.cast_from_ptr(ptr, src_layout, dest_layout),
|
||||
Ok(data) => self.cast_from_int(data, src_layout, dest_layout),
|
||||
}
|
||||
}
|
||||
@ -239,17 +239,25 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
|
||||
fn cast_from_ptr(
|
||||
&self,
|
||||
ptr: Pointer<M::PointerTag>,
|
||||
ty: Ty<'tcx>
|
||||
src_layout: TyLayout<'tcx>,
|
||||
dest_layout: TyLayout<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar<M::PointerTag>> {
|
||||
use rustc::ty::TyKind::*;
|
||||
match ty.sty {
|
||||
|
||||
match dest_layout.ty.sty {
|
||||
// Casting to a reference or fn pointer is not permitted by rustc,
|
||||
// no need to support it here.
|
||||
RawPtr(_) |
|
||||
Int(IntTy::Isize) |
|
||||
Uint(UintTy::Usize) => Ok(ptr.into()),
|
||||
Int(_) | Uint(_) => err!(ReadPointerAsBytes),
|
||||
_ => err!(Unimplemented(format!("ptr to {:?} cast", ty))),
|
||||
RawPtr(_) => Ok(ptr.into()),
|
||||
Int(_) | Uint(_) => {
|
||||
let size = self.memory.pointer_size();
|
||||
|
||||
match self.force_bits(Scalar::Ptr(ptr), size) {
|
||||
Ok(bits) => self.cast_from_int(bits, src_layout, dest_layout),
|
||||
Err(_) if dest_layout.size == size => Ok(ptr.into()),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
_ => bug!("invalid MIR: ptr to {:?} cast", dest_layout.ty)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,10 @@ pub fn opts() -> TargetOptions {
|
||||
target_family: Some("windows".to_string()),
|
||||
is_like_windows: true,
|
||||
is_like_msvc: true,
|
||||
// set VSLANG to 1033 can prevent link.exe from using
|
||||
// language packs, and avoid generating Non-UTF-8 error
|
||||
// messages if a link error occurred.
|
||||
link_env: vec![("VSLANG".to_string(), "1033".to_string())],
|
||||
pre_link_args: args,
|
||||
crt_static_allows_dylibs: true,
|
||||
crt_static_respected: true,
|
||||
|
@ -458,7 +458,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
match ty.sty {
|
||||
ty::Array(..) | ty::Slice(..) => {
|
||||
err.help("the semantics of slice patterns changed \
|
||||
recently; see issue #23121");
|
||||
recently; see issue #62254");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -2608,6 +2608,12 @@ mod test_map {
|
||||
use realstd::collections::CollectionAllocErr::*;
|
||||
use realstd::usize;
|
||||
|
||||
// https://github.com/rust-lang/rust/issues/62301
|
||||
fn _assert_hashmap_is_unwind_safe() {
|
||||
fn assert_unwind_safe<T: crate::panic::UnwindSafe>() {}
|
||||
assert_unwind_safe::<HashMap<(), crate::cell::UnsafeCell<()>>>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero_capacities() {
|
||||
type HM = HashMap<i32, i32>;
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
use crate::any::Any;
|
||||
use crate::cell::UnsafeCell;
|
||||
use crate::collections;
|
||||
use crate::fmt;
|
||||
use crate::future::Future;
|
||||
use crate::pin::Pin;
|
||||
@ -285,6 +286,11 @@ impl RefUnwindSafe for atomic::AtomicBool {}
|
||||
#[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
|
||||
impl<T> RefUnwindSafe for atomic::AtomicPtr<T> {}
|
||||
|
||||
// https://github.com/rust-lang/rust/issues/62301
|
||||
#[stable(feature = "hashbrown", since = "1.36.0")]
|
||||
impl<K, V, S> UnwindSafe for collections::HashMap<K, V, S>
|
||||
where K: UnwindSafe, V: UnwindSafe, S: UnwindSafe {}
|
||||
|
||||
#[stable(feature = "catch_unwind", since = "1.9.0")]
|
||||
impl<T> Deref for AssertUnwindSafe<T> {
|
||||
type Target = T;
|
||||
|
@ -1765,33 +1765,6 @@ mod tests {
|
||||
assert_eq!(out, "foobar\n");
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_os = "android", ignore)]
|
||||
#[cfg(unix)]
|
||||
fn uid_works() {
|
||||
use crate::os::unix::prelude::*;
|
||||
|
||||
let mut p = Command::new("/bin/sh")
|
||||
.arg("-c").arg("true")
|
||||
.uid(unsafe { libc::getuid() })
|
||||
.gid(unsafe { libc::getgid() })
|
||||
.spawn().unwrap();
|
||||
assert!(p.wait().unwrap().success());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_os = "android", ignore)]
|
||||
#[cfg(unix)]
|
||||
fn uid_to_root_fails() {
|
||||
use crate::os::unix::prelude::*;
|
||||
|
||||
// if we're already root, this isn't a valid test. Most of the bots run
|
||||
// as non-root though (android is an exception).
|
||||
if unsafe { libc::getuid() == 0 } { return }
|
||||
assert!(Command::new("/bin/ls").uid(0).gid(0).spawn().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_os = "android", ignore)]
|
||||
fn test_process_status() {
|
||||
|
@ -323,7 +323,7 @@ declare_features! (
|
||||
(active, nll, "1.0.0", Some(43234), None),
|
||||
|
||||
// Allows using slice patterns.
|
||||
(active, slice_patterns, "1.0.0", Some(23121), None),
|
||||
(active, slice_patterns, "1.0.0", Some(62254), None),
|
||||
|
||||
// Allows the definition of `const` functions with some advanced features.
|
||||
(active, const_fn, "1.2.0", Some(57563), None),
|
||||
@ -610,7 +610,7 @@ declare_features! (
|
||||
(removed, allocator, "1.0.0", None, None, None),
|
||||
(removed, simd, "1.0.0", Some(27731), None,
|
||||
Some("removed in favor of `#[repr(simd)]`")),
|
||||
(removed, advanced_slice_patterns, "1.0.0", Some(23121), None,
|
||||
(removed, advanced_slice_patterns, "1.0.0", Some(62254), None,
|
||||
Some("merged into `#![feature(slice_patterns)]`")),
|
||||
(removed, macro_reexport, "1.0.0", Some(29638), None,
|
||||
Some("subsumed by `pub use`")),
|
||||
|
26
src/test/run-pass/command-uid-gid.rs
Normal file
26
src/test/run-pass/command-uid-gid.rs
Normal file
@ -0,0 +1,26 @@
|
||||
#![feature(rustc_private)]
|
||||
|
||||
fn main() {
|
||||
#[cfg(unix)]
|
||||
run()
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn run() {
|
||||
extern crate libc;
|
||||
use std::process::Command;
|
||||
use std::os::unix::prelude::*;
|
||||
|
||||
let mut p = Command::new("/bin/sh")
|
||||
.arg("-c").arg("true")
|
||||
.uid(unsafe { libc::getuid() })
|
||||
.gid(unsafe { libc::getgid() })
|
||||
.spawn().unwrap();
|
||||
assert!(p.wait().unwrap().success());
|
||||
|
||||
// if we're already root, this isn't a valid test. Most of the bots run
|
||||
// as non-root though (android is an exception).
|
||||
if unsafe { libc::getuid() != 0 } {
|
||||
assert!(Command::new("/bin/ls").uid(0).gid(0).spawn().is_err());
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized
|
||||
LL | [1, 2, ..] => {}
|
||||
| ^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/23121
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/62254
|
||||
= help: add #![feature(slice_patterns)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: syntax for subslices in slice patterns is not yet stabilized
|
||||
@ -13,7 +13,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized
|
||||
LL | [1, .., 5] => {}
|
||||
| ^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/23121
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/62254
|
||||
= help: add #![feature(slice_patterns)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: syntax for subslices in slice patterns is not yet stabilized
|
||||
@ -22,7 +22,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized
|
||||
LL | [.., 4, 5] => {}
|
||||
| ^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/23121
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/62254
|
||||
= help: add #![feature(slice_patterns)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: syntax for subslices in slice patterns is not yet stabilized
|
||||
@ -31,7 +31,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized
|
||||
LL | [ xs.., 4, 5 ] => {}
|
||||
| ^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/23121
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/62254
|
||||
= help: add #![feature(slice_patterns)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: syntax for subslices in slice patterns is not yet stabilized
|
||||
@ -40,7 +40,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized
|
||||
LL | [ 1, xs.., 5 ] => {}
|
||||
| ^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/23121
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/62254
|
||||
= help: add #![feature(slice_patterns)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: syntax for subslices in slice patterns is not yet stabilized
|
||||
@ -49,7 +49,7 @@ error[E0658]: syntax for subslices in slice patterns is not yet stabilized
|
||||
LL | [ 1, 2, xs.. ] => {}
|
||||
| ^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/23121
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/62254
|
||||
= help: add #![feature(slice_patterns)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
Loading…
x
Reference in New Issue
Block a user