From 303306cf5ede678719ec1324bb02d3d02c014183 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sat, 14 Jul 2018 23:28:39 +0100 Subject: [PATCH 01/10] Add unaligned volatile intrinsics --- src/libcore/intrinsics.rs | 9 +++++++++ src/librustc_codegen_llvm/builder.rs | 8 +++++++- src/librustc_codegen_llvm/intrinsic.rs | 14 ++++++++++++-- src/librustc_codegen_llvm/mir/operand.rs | 4 ++++ src/librustc_typeck/check/intrinsic.rs | 4 ++-- .../run-make-fulldeps/volatile-intrinsics/main.rs | 13 ++++++++++--- 6 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 89fe2d941a350..854cb5f4e3b3f 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1085,6 +1085,15 @@ extern "rust-intrinsic" { /// [`std::ptr::write_volatile`](../../std/ptr/fn.write_volatile.html). pub fn volatile_store(dst: *mut T, val: T); + /// Perform a volatile load from the `src` pointer + /// The pointer is not required to be aligned. + #[cfg(not(stage0))] + pub fn unaligned_volatile_load(src: *const T) -> T; + /// Perform a volatile store to the `dst` pointer. + /// The pointer is not required to be aligned. + #[cfg(not(stage0))] + pub fn unaligned_volatile_store(dst: *mut T, val: T); + /// Returns the square root of an `f32` pub fn sqrtf32(x: f32) -> f32; /// Returns the square root of an `f64` diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 7b4998e85881e..c8dc579cd62e9 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -54,6 +54,7 @@ bitflags! { pub struct MemFlags: u8 { const VOLATILE = 1 << 0; const NONTEMPORAL = 1 << 1; + const UNALIGNED = 1 << 2; } } @@ -602,7 +603,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let ptr = self.check_store(val, ptr); unsafe { let store = llvm::LLVMBuildStore(self.llbuilder, val, ptr); - llvm::LLVMSetAlignment(store, align.abi() as c_uint); + let align = if flags.contains(MemFlags::UNALIGNED) { + 1 + } else { + align.abi() as c_uint + }; + llvm::LLVMSetAlignment(store, align); if flags.contains(MemFlags::VOLATILE) { llvm::LLVMSetVolatile(store, llvm::True); } diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 6bb5456f9034f..567595b699798 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -234,15 +234,20 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, memset_intrinsic(bx, true, substs.type_at(0), args[0].immediate(), args[1].immediate(), args[2].immediate()) } - "volatile_load" => { + "volatile_load" | "unaligned_volatile_load" => { let tp_ty = substs.type_at(0); let mut ptr = args[0].immediate(); if let PassMode::Cast(ty) = fn_ty.ret.mode { ptr = bx.pointercast(ptr, ty.llvm_type(cx).ptr_to()); } let load = bx.volatile_load(ptr); + let align = if name == "unaligned_volatile_load" { + 1 + } else { + cx.align_of(tp_ty).abi() as u32 + }; unsafe { - llvm::LLVMSetAlignment(load, cx.align_of(tp_ty).abi() as u32); + llvm::LLVMSetAlignment(load, align); } to_immediate(bx, load, cx.layout_of(tp_ty)) }, @@ -251,6 +256,11 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, args[1].val.volatile_store(bx, dst); return; }, + "unaligned_volatile_store" => { + let dst = args[0].deref(bx.cx); + args[1].val.unaligned_volatile_store(bx, dst); + return; + }, "prefetch_read_data" | "prefetch_write_data" | "prefetch_read_instruction" | "prefetch_write_instruction" => { let expect = cx.get_intrinsic(&("llvm.prefetch")); diff --git a/src/librustc_codegen_llvm/mir/operand.rs b/src/librustc_codegen_llvm/mir/operand.rs index 3d3a4400bd810..49cc07d6854a7 100644 --- a/src/librustc_codegen_llvm/mir/operand.rs +++ b/src/librustc_codegen_llvm/mir/operand.rs @@ -286,6 +286,10 @@ impl<'a, 'tcx> OperandValue { self.store_with_flags(bx, dest, MemFlags::VOLATILE); } + pub fn unaligned_volatile_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { + self.store_with_flags(bx, dest, MemFlags::VOLATILE | MemFlags::UNALIGNED); + } + pub fn nontemporal_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { self.store_with_flags(bx, dest, MemFlags::NONTEMPORAL); } diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index c93023edcea08..46cf9d1fa7fad 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -270,9 +270,9 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, "roundf32" => (0, vec![ tcx.types.f32 ], tcx.types.f32), "roundf64" => (0, vec![ tcx.types.f64 ], tcx.types.f64), - "volatile_load" => + "volatile_load" | "unaligned_volatile_load" => (1, vec![ tcx.mk_imm_ptr(param(0)) ], param(0)), - "volatile_store" => + "volatile_store" | "unaligned_volatile_store" => (1, vec![ tcx.mk_mut_ptr(param(0)), param(0) ], tcx.mk_nil()), "ctpop" | "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | diff --git a/src/test/run-make-fulldeps/volatile-intrinsics/main.rs b/src/test/run-make-fulldeps/volatile-intrinsics/main.rs index 4d0d7672101c3..d214a20139c9c 100644 --- a/src/test/run-make-fulldeps/volatile-intrinsics/main.rs +++ b/src/test/run-make-fulldeps/volatile-intrinsics/main.rs @@ -10,17 +10,24 @@ #![feature(core_intrinsics, volatile)] -use std::intrinsics::{volatile_load, volatile_store}; +use std::intrinsics::{ + unaligned_volatile_load, unaligned_volatile_store, volatile_load, volatile_store, +}; use std::ptr::{read_volatile, write_volatile}; pub fn main() { unsafe { - let mut i : isize = 1; + let mut i: isize = 1; volatile_store(&mut i, 2); assert_eq!(volatile_load(&i), 2); } unsafe { - let mut i : isize = 1; + let mut i: isize = 1; + unaligned_volatile_store(&mut i, 2); + assert_eq!(unaligned_volatile_load(&i), 2); + } + unsafe { + let mut i: isize = 1; write_volatile(&mut i, 2); assert_eq!(read_volatile(&i), 2); } From b1d2a91f3260b5ee045310f4eb28abd2c62773e1 Mon Sep 17 00:00:00 2001 From: Marco Neumann Date: Sun, 15 Jul 2018 17:37:46 +0200 Subject: [PATCH 02/10] impl PartialEq+Eq for BuildHasherDefault --- src/libcore/hash/mod.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index e6f8dfffd6330..e7907e0344493 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -542,6 +542,16 @@ impl Default for BuildHasherDefault { } } +#[stable(since = "1.29.0", feature = "build_hasher_eq")] +impl PartialEq for BuildHasherDefault { + fn eq(&self, _other: &BuildHasherDefault) -> bool { + true + } +} + +#[stable(since = "1.29.0", feature = "build_hasher_eq")] +impl Eq for BuildHasherDefault {} + ////////////////////////////////////////////////////////////////////////////// mod impls { From 1581971635b725764f23be86a618decffb0d754e Mon Sep 17 00:00:00 2001 From: jD91mZM2 Date: Tue, 24 Jul 2018 05:27:45 +0200 Subject: [PATCH 03/10] Stablize Redox Unix Sockets --- src/libstd/sys/redox/ext/net.rs | 42 ++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/libstd/sys/redox/ext/net.rs b/src/libstd/sys/redox/ext/net.rs index 4c5f857462193..2ab7770324254 100644 --- a/src/libstd/sys/redox/ext/net.rs +++ b/src/libstd/sys/redox/ext/net.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![unstable(feature = "unix_socket_redox", reason = "new feature", issue="51553")] +#![stable(feature = "unix_socket_redox", since = "1.29")] //! Unix-specific networking functionality @@ -37,6 +37,7 @@ use sys::{cvt, fd::FileDesc, syscall}; /// let addr = socket.local_addr().expect("Couldn't get local address"); /// ``` #[derive(Clone)] +#[stable(feature = "unix_socket_redox", since = "1.29")] pub struct SocketAddr(()); impl SocketAddr { @@ -64,6 +65,7 @@ impl SocketAddr { /// let addr = socket.local_addr().expect("Couldn't get local address"); /// assert_eq!(addr.as_pathname(), None); /// ``` + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn as_pathname(&self) -> Option<&Path> { None } @@ -91,10 +93,12 @@ impl SocketAddr { /// let addr = socket.local_addr().expect("Couldn't get local address"); /// assert_eq!(addr.is_unnamed(), true); /// ``` + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn is_unnamed(&self) -> bool { false } } +#[stable(feature = "unix_socket_redox", since = "1.29")] impl fmt::Debug for SocketAddr { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "SocketAddr") @@ -115,8 +119,10 @@ impl fmt::Debug for SocketAddr { /// stream.read_to_string(&mut response).unwrap(); /// println!("{}", response); /// ``` +#[stable(feature = "unix_socket_redox", since = "1.29")] pub struct UnixStream(FileDesc); +#[stable(feature = "unix_socket_redox", since = "1.29")] impl fmt::Debug for UnixStream { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let mut builder = fmt.debug_struct("UnixStream"); @@ -147,6 +153,7 @@ impl UnixStream { /// } /// }; /// ``` + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn connect>(path: P) -> io::Result { if let Some(s) = path.as_ref().to_str() { cvt(syscall::open(format!("chan:{}", s), syscall::O_CLOEXEC)) @@ -177,6 +184,7 @@ impl UnixStream { /// } /// }; /// ``` + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn pair() -> io::Result<(UnixStream, UnixStream)> { let server = cvt(syscall::open("chan:", syscall::O_CREAT | syscall::O_CLOEXEC)) .map(FileDesc::new)?; @@ -200,6 +208,7 @@ impl UnixStream { /// let socket = UnixStream::connect("/tmp/sock").unwrap(); /// let sock_copy = socket.try_clone().expect("Couldn't clone socket"); /// ``` + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn try_clone(&self) -> io::Result { self.0.duplicate().map(UnixStream) } @@ -214,6 +223,7 @@ impl UnixStream { /// let socket = UnixStream::connect("/tmp/sock").unwrap(); /// let addr = socket.local_addr().expect("Couldn't get local address"); /// ``` + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn local_addr(&self) -> io::Result { Err(Error::new(ErrorKind::Other, "UnixStream::local_addr unimplemented on redox")) } @@ -228,6 +238,7 @@ impl UnixStream { /// let socket = UnixStream::connect("/tmp/sock").unwrap(); /// let addr = socket.peer_addr().expect("Couldn't get peer address"); /// ``` + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn peer_addr(&self) -> io::Result { Err(Error::new(ErrorKind::Other, "UnixStream::peer_addr unimplemented on redox")) } @@ -266,6 +277,7 @@ impl UnixStream { /// let err = result.unwrap_err(); /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput) /// ``` + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn set_read_timeout(&self, _timeout: Option) -> io::Result<()> { Err(Error::new(ErrorKind::Other, "UnixStream::set_read_timeout unimplemented on redox")) } @@ -304,6 +316,7 @@ impl UnixStream { /// let err = result.unwrap_err(); /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput) /// ``` + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn set_write_timeout(&self, _timeout: Option) -> io::Result<()> { Err(Error::new(ErrorKind::Other, "UnixStream::set_write_timeout unimplemented on redox")) } @@ -320,6 +333,7 @@ impl UnixStream { /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout"); /// assert_eq!(socket.read_timeout().unwrap(), Some(Duration::new(1, 0))); /// ``` + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn read_timeout(&self) -> io::Result> { Err(Error::new(ErrorKind::Other, "UnixStream::read_timeout unimplemented on redox")) } @@ -336,6 +350,7 @@ impl UnixStream { /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout"); /// assert_eq!(socket.write_timeout().unwrap(), Some(Duration::new(1, 0))); /// ``` + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn write_timeout(&self) -> io::Result> { Err(Error::new(ErrorKind::Other, "UnixStream::write_timeout unimplemented on redox")) } @@ -350,6 +365,7 @@ impl UnixStream { /// let socket = UnixStream::connect("/tmp/sock").unwrap(); /// socket.set_nonblocking(true).expect("Couldn't set nonblocking"); /// ``` + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { self.0.set_nonblocking(nonblocking) } @@ -369,6 +385,7 @@ impl UnixStream { /// /// # Platform specific /// On Redox this always returns None. + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn take_error(&self) -> io::Result> { Ok(None) } @@ -390,11 +407,13 @@ impl UnixStream { /// let socket = UnixStream::connect("/tmp/sock").unwrap(); /// socket.shutdown(Shutdown::Both).expect("shutdown function failed"); /// ``` + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn shutdown(&self, _how: Shutdown) -> io::Result<()> { Err(Error::new(ErrorKind::Other, "UnixStream::shutdown unimplemented on redox")) } } +#[stable(feature = "unix_socket_redox", since = "1.29")] impl io::Read for UnixStream { fn read(&mut self, buf: &mut [u8]) -> io::Result { io::Read::read(&mut &*self, buf) @@ -406,6 +425,7 @@ impl io::Read for UnixStream { } } +#[stable(feature = "unix_socket_redox", since = "1.29")] impl<'a> io::Read for &'a UnixStream { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.0.read(buf) @@ -417,6 +437,7 @@ impl<'a> io::Read for &'a UnixStream { } } +#[stable(feature = "unix_socket_redox", since = "1.29")] impl io::Write for UnixStream { fn write(&mut self, buf: &[u8]) -> io::Result { io::Write::write(&mut &*self, buf) @@ -427,6 +448,7 @@ impl io::Write for UnixStream { } } +#[stable(feature = "unix_socket_redox", since = "1.29")] impl<'a> io::Write for &'a UnixStream { fn write(&mut self, buf: &[u8]) -> io::Result { self.0.write(buf) @@ -437,18 +459,21 @@ impl<'a> io::Write for &'a UnixStream { } } +#[stable(feature = "unix_socket_redox", since = "1.29")] impl AsRawFd for UnixStream { fn as_raw_fd(&self) -> RawFd { self.0.raw() } } +#[stable(feature = "unix_socket_redox", since = "1.29")] impl FromRawFd for UnixStream { unsafe fn from_raw_fd(fd: RawFd) -> UnixStream { UnixStream(FileDesc::new(fd)) } } +#[stable(feature = "unix_socket_redox", since = "1.29")] impl IntoRawFd for UnixStream { fn into_raw_fd(self) -> RawFd { self.0.into_raw() @@ -483,8 +508,10 @@ impl IntoRawFd for UnixStream { /// } /// } /// ``` +#[stable(feature = "unix_socket_redox", since = "1.29")] pub struct UnixListener(FileDesc); +#[stable(feature = "unix_socket_redox", since = "1.29")] impl fmt::Debug for UnixListener { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let mut builder = fmt.debug_struct("UnixListener"); @@ -512,6 +539,7 @@ impl UnixListener { /// } /// }; /// ``` + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn bind>(path: P) -> io::Result { if let Some(s) = path.as_ref().to_str() { cvt(syscall::open(format!("chan:{}", s), syscall::O_CREAT | syscall::O_CLOEXEC)) @@ -545,6 +573,7 @@ impl UnixListener { /// Err(e) => println!("accept function failed: {:?}", e), /// } /// ``` + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> { self.0.duplicate_path(b"listen").map(|fd| (UnixStream(fd), SocketAddr(()))) } @@ -564,6 +593,7 @@ impl UnixListener { /// /// let listener_copy = listener.try_clone().expect("try_clone failed"); /// ``` + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn try_clone(&self) -> io::Result { self.0.duplicate().map(UnixListener) } @@ -579,6 +609,7 @@ impl UnixListener { /// /// let addr = listener.local_addr().expect("Couldn't get local address"); /// ``` + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn local_addr(&self) -> io::Result { Err(Error::new(ErrorKind::Other, "UnixListener::local_addr unimplemented on redox")) } @@ -594,6 +625,7 @@ impl UnixListener { /// /// listener.set_nonblocking(true).expect("Couldn't set non blocking"); /// ``` + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { self.0.set_nonblocking(nonblocking) } @@ -614,6 +646,7 @@ impl UnixListener { /// /// # Platform specific /// On Redox this always returns None. + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn take_error(&self) -> io::Result> { Ok(None) } @@ -649,29 +682,34 @@ impl UnixListener { /// } /// } /// ``` + #[stable(feature = "unix_socket_redox", since = "1.29")] pub fn incoming<'a>(&'a self) -> Incoming<'a> { Incoming { listener: self } } } +#[stable(feature = "unix_socket_redox", since = "1.29")] impl AsRawFd for UnixListener { fn as_raw_fd(&self) -> RawFd { self.0.raw() } } +#[stable(feature = "unix_socket_redox", since = "1.29")] impl FromRawFd for UnixListener { unsafe fn from_raw_fd(fd: RawFd) -> UnixListener { UnixListener(FileDesc::new(fd)) } } +#[stable(feature = "unix_socket_redox", since = "1.29")] impl IntoRawFd for UnixListener { fn into_raw_fd(self) -> RawFd { self.0.into_raw() } } +#[stable(feature = "unix_socket_redox", since = "1.29")] impl<'a> IntoIterator for &'a UnixListener { type Item = io::Result; type IntoIter = Incoming<'a>; @@ -712,10 +750,12 @@ impl<'a> IntoIterator for &'a UnixListener { /// } /// ``` #[derive(Debug)] +#[stable(feature = "unix_socket_redox", since = "1.29")] pub struct Incoming<'a> { listener: &'a UnixListener, } +#[stable(feature = "unix_socket_redox", since = "1.29")] impl<'a> Iterator for Incoming<'a> { type Item = io::Result; From 4f3ab4986ec96d9c93f34dc53d0a4a1279288451 Mon Sep 17 00:00:00 2001 From: Colin Wallace Date: Mon, 23 Jul 2018 22:00:51 -0700 Subject: [PATCH 04/10] libstd: Prefer `Option::map`/etc over `match` where applicable --- src/libstd/net/parser.rs | 5 +---- src/libstd/path.rs | 5 +---- src/libstd/sys_common/backtrace.rs | 9 ++++----- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/libstd/net/parser.rs b/src/libstd/net/parser.rs index ae5037cc44e80..008c5da171ffc 100644 --- a/src/libstd/net/parser.rs +++ b/src/libstd/net/parser.rs @@ -53,10 +53,7 @@ impl<'a> Parser<'a> { F: FnOnce(&mut Parser) -> Option, { self.read_atomically(move |p| { - match cb(p) { - Some(x) => if p.is_eof() {Some(x)} else {None}, - None => None, - } + cb(p).filter(|_| p.is_eof()) }) } diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 0c60129494d5c..688a7e99f10ed 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1065,10 +1065,7 @@ impl<'a> Iterator for Ancestors<'a> { fn next(&mut self) -> Option { let next = self.next; - self.next = match next { - Some(path) => path.parent(), - None => None, - }; + self.next = next.and_then(Path::parent); next } } diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs index 61d7ed463dd38..2db47bd59475e 100644 --- a/src/libstd/sys_common/backtrace.rs +++ b/src/libstd/sys_common/backtrace.rs @@ -156,16 +156,15 @@ pub fn log_enabled() -> Option { _ => return Some(PrintFormat::Full), } - let val = match env::var_os("RUST_BACKTRACE") { - Some(x) => if &x == "0" { + let val = env::var_os("RUST_BACKTRACE").and_then(|x| + if &x == "0" { None } else if &x == "full" { Some(PrintFormat::Full) } else { Some(PrintFormat::Short) - }, - None => None, - }; + } + ); ENABLED.store(match val { Some(v) => v as isize, None => 1, From 727bd7de7e6332482ee2765d46bfd00d89386d4b Mon Sep 17 00:00:00 2001 From: Colin Wallace Date: Mon, 23 Jul 2018 22:04:33 -0700 Subject: [PATCH 05/10] libcore: Prefer `Option::map` over `match` where applicable --- src/libcore/str/mod.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 3e215de58dd21..86b8349fa3c89 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -696,13 +696,10 @@ impl<'a> Iterator for CharIndices<'a> { impl<'a> DoubleEndedIterator for CharIndices<'a> { #[inline] fn next_back(&mut self) -> Option<(usize, char)> { - match self.iter.next_back() { - None => None, - Some(ch) => { - let index = self.front_offset + self.iter.iter.len(); - Some((index, ch)) - } - } + self.iter.next_back().map(|ch| { + let index = self.front_offset + self.iter.iter.len(); + (index, ch) + }) } } From 10d82137b3fe45a3b0f0c1bd9080ee46b5259ac1 Mon Sep 17 00:00:00 2001 From: Colin Wallace Date: Mon, 23 Jul 2018 22:05:45 -0700 Subject: [PATCH 06/10] librustc: Prefer `Option::map`/etc over `match` where applicable --- src/librustc/traits/on_unimplemented.rs | 9 ++++----- src/librustc/ty/mod.rs | 13 +++++-------- src/librustc_metadata/locator.rs | 17 +++++++---------- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index 925d3504f75fc..e1395c3fa4427 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -190,11 +190,10 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { for command in self.subcommands.iter().chain(Some(self)).rev() { if let Some(ref condition) = command.condition { if !attr::eval_condition(condition, &tcx.sess.parse_sess, &mut |c| { - options.contains(&(c.name().as_str().to_string(), - match c.value_str().map(|s| s.as_str().to_string()) { - Some(s) => Some(s), - None => None - })) + options.contains(&( + c.name().as_str().to_string(), + c.value_str().map(|s| s.as_str().to_string()) + )) }) { debug!("evaluate: skipping {:?} due to condition", command); continue diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index bd24b93f0293f..c2795bae01029 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2697,15 +2697,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.opt_associated_item(def_id) }; - match item { - Some(trait_item) => { - match trait_item.container { - TraitContainer(_) => None, - ImplContainer(def_id) => Some(def_id), - } + item.and_then(|trait_item| + match trait_item.container { + TraitContainer(_) => None, + ImplContainer(def_id) => Some(def_id), } - None => None - } + ) } /// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err` diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index b747624338c83..42af5db82942a 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -824,17 +824,14 @@ impl<'a> Context<'a> { if rlib.is_none() && rmeta.is_none() && dylib.is_none() { return None; } - match slot { - Some((_, metadata)) => { - Some(Library { - dylib, - rlib, - rmeta, - metadata, - }) + slot.map(|(_, metadata)| + Library { + dylib, + rlib, + rmeta, + metadata, } - None => None, - } + ) } } From cbe5f1c4207673b9059e832ef2f134b4f87b380d Mon Sep 17 00:00:00 2001 From: Colin Wallace Date: Mon, 23 Jul 2018 22:06:45 -0700 Subject: [PATCH 07/10] libsyntax_ext: Prefer `Option::map` over `match` where applicable --- src/libsyntax_ext/deriving/generic/ty.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs index dcccb187bef4b..a0845e0982d2a 100644 --- a/src/libsyntax_ext/deriving/generic/ty.rs +++ b/src/libsyntax_ext/deriving/generic/ty.rs @@ -138,17 +138,13 @@ pub fn nil_ty<'r>() -> Ty<'r> { } fn mk_lifetime(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Option { - match *lt { - Some(s) => Some(cx.lifetime(span, Ident::from_str(s))), - None => None, - } + lt.map(|s| + cx.lifetime(span, Ident::from_str(s)) + ) } fn mk_lifetimes(cx: &ExtCtxt, span: Span, lt: &Option<&str>) -> Vec { - match *lt { - Some(s) => vec![cx.lifetime(span, Ident::from_str(s))], - None => vec![], - } + mk_lifetime(cx, span, lt).into_iter().collect() } impl<'a> Ty<'a> { From 2e33a557de4cddfebd9fa3f6b64d6ed603482e75 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 23 Jul 2018 14:56:36 +0200 Subject: [PATCH 08/10] Allow declaring existential types inside blocks --- src/libsyntax/parse/parser.rs | 6 +++++ .../impl-trait/existential_type_in_fn_body.rs | 22 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/test/ui/impl-trait/existential_type_in_fn_body.rs diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 2eaa56ebeb826..564eba0a553fa 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4391,6 +4391,11 @@ impl<'a> Parser<'a> { self.token.is_keyword(keywords::Extern) && self.look_ahead(1, |t| t != &token::ModSep) } + fn is_existential_type_decl(&self) -> bool { + self.token.is_keyword(keywords::Existential) && + self.look_ahead(1, |t| t.is_keyword(keywords::Type)) + } + fn is_auto_trait_item(&mut self) -> bool { // auto trait (self.token.is_keyword(keywords::Auto) @@ -4495,6 +4500,7 @@ impl<'a> Parser<'a> { !self.is_union_item() && !self.is_crate_vis() && !self.is_extern_non_path() && + !self.is_existential_type_decl() && !self.is_auto_trait_item() { let pth = self.parse_path(PathStyle::Expr)?; diff --git a/src/test/ui/impl-trait/existential_type_in_fn_body.rs b/src/test/ui/impl-trait/existential_type_in_fn_body.rs new file mode 100644 index 0000000000000..20f9e0d77c312 --- /dev/null +++ b/src/test/ui/impl-trait/existential_type_in_fn_body.rs @@ -0,0 +1,22 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-pass + +#![feature(existential_type)] + +use std::fmt::Debug; + +fn main() { + existential type Existential: Debug; + + fn f() -> Existential {} + println!("{:?}", f()); +} From fb089156220ec2932b11de21226296c7fe3503f3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 24 Jul 2018 18:23:10 +0200 Subject: [PATCH 09/10] clarify offset function safety concerns --- src/libcore/ptr.rs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index d020e14be4cbd..be82ab44cd1fc 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -591,7 +591,7 @@ impl *const T { /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of an allocated object. + /// byte past the end of *the same* allocated object. /// /// * The computed offset, **in bytes**, cannot overflow an `isize`. /// @@ -643,9 +643,15 @@ impl *const T { /// /// The resulting pointer does not need to be in bounds, but it is /// potentially hazardous to dereference (which requires `unsafe`). + /// In particular, the resulting pointer may *not* be used to access a + /// different allocated object than the one `self` points to. In other + /// words, `x.wrapping_offset(y.wrapping_offset_from(x))` is + /// *not* the same as `y`, and dereferencing it is undefined behavior + /// unless `x` and `y` point into the same allocated object. /// /// Always use `.offset(count)` instead when possible, because `offset` - /// allows the compiler to optimize better. + /// allows the compiler to optimize better. If you need to cross object + /// boundaries, cast the pointer to an integer and do the arithmetic there. /// /// # Examples /// @@ -1340,7 +1346,7 @@ impl *mut T { /// Behavior: /// /// * Both the starting and resulting pointer must be either in bounds or one - /// byte past the end of an allocated object. + /// byte past the end of *the same* allocated object. /// /// * The computed offset, **in bytes**, cannot overflow an `isize`. /// @@ -1391,9 +1397,15 @@ impl *mut T { /// /// The resulting pointer does not need to be in bounds, but it is /// potentially hazardous to dereference (which requires `unsafe`). + /// In particular, the resulting pointer may *not* be used to access a + /// different allocated object than the one `self` points to. In other + /// words, `x.wrapping_offset(y.wrapping_offset_from(x))` is + /// *not* the same as `y`, and dereferencing it is undefined behavior + /// unless `x` and `y` point into the same allocated object. /// /// Always use `.offset(count)` instead when possible, because `offset` - /// allows the compiler to optimize better. + /// allows the compiler to optimize better. If you need to cross object + /// boundaries, cast the pointer to an integer and do the arithmetic there. /// /// # Examples /// From 3cce003f15c78527ae470c3e62f6c9a8f3931609 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 24 Jul 2018 22:35:15 +0200 Subject: [PATCH 10/10] Release notes: add some missing 1.28 libs stabilization --- RELEASES.md | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 1e1ae4a8b6af9..b983851f88198 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -52,6 +52,16 @@ Stabilized APIs --------------- - [`Iterator::step_by`] - [`Path::ancestors`] +- [`SystemTime::UNIX_EPOCH`] +- [`alloc::GlobalAlloc`] +- [`alloc::Layout`] +- [`alloc::LayoutErr`] +- [`alloc::System`] +- [`alloc::alloc`] +- [`alloc::alloc_zeroed`] +- [`alloc::dealloc`] +- [`alloc::realloc`] +- [`alloc::handle_alloc_error`] - [`btree_map::Entry::or_default`] - [`fmt::Alignment`] - [`hash_map::Entry::or_default`] @@ -122,6 +132,16 @@ Compatibility Notes [cargo/5584]: https://github.com/rust-lang/cargo/pull/5584/ [`Iterator::step_by`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.step_by [`Path::ancestors`]: https://doc.rust-lang.org/std/path/struct.Path.html#method.ancestors +[`SystemTime::UNIX_EPOCH`]: https://doc.rust-lang.org/std/time/struct.SystemTime.html#associatedconstant.UNIX_EPOCH +[`alloc::GlobalAlloc`]: https://doc.rust-lang.org/std/alloc/trait.GlobalAlloc.html +[`alloc::Layout`]: https://doc.rust-lang.org/std/alloc/struct.Layout.html +[`alloc::LayoutErr`]: https://doc.rust-lang.org/std/alloc/struct.LayoutErr.html +[`alloc::System`]: https://doc.rust-lang.org/std/alloc/struct.System.html +[`alloc::alloc`]: https://doc.rust-lang.org/std/alloc/fn.alloc.html +[`alloc::alloc_zeroed`]: https://doc.rust-lang.org/std/alloc/fn.alloc_zeroed.html +[`alloc::dealloc`]: https://doc.rust-lang.org/std/alloc/fn.dealloc.html +[`alloc::realloc`]: https://doc.rust-lang.org/std/alloc/fn.realloc.html +[`alloc::handle_alloc_error`]: https://doc.rust-lang.org/std/alloc/fn.handle_alloc_error.html [`btree_map::Entry::or_default`]: https://doc.rust-lang.org/std/collections/btree_map/enum.Entry.html#method.or_default [`fmt::Alignment`]: https://doc.rust-lang.org/std/fmt/enum.Alignment.html [`hash_map::Entry::or_default`]: https://doc.rust-lang.org/std/collections/btree_map/enum.Entry.html#method.or_default @@ -3162,7 +3182,7 @@ Stabilized APIs * [`UnixDatagram::shutdown`](http://doc.rust-lang.org/std/os/unix/net/struct.UnixDatagram.html#method.shutdown) * RawFd impls for `UnixDatagram` * `{BTree,Hash}Map::values_mut` -* [`<[_]>::binary_search_by_key`](http://doc.rust-lang.org/beta/std/primitive.slice.html#method.binary_search_by_key) +* [`<[_]>::binary_search_by_key`](http://doc.rust-lang.org/std/primitive.slice.html#method.binary_search_by_key) Libraries --------- @@ -4080,7 +4100,7 @@ Compatibility Notes [1.6bh]: https://github.com/rust-lang/rust/pull/29811 [1.6c]: https://github.com/rust-lang/cargo/pull/2192 [1.6cc]: https://github.com/rust-lang/cargo/pull/2131 -[1.6co]: http://doc.rust-lang.org/beta/core/index.html +[1.6co]: http://doc.rust-lang.org/core/index.html [1.6dv]: https://github.com/rust-lang/rust/pull/30000 [1.6f]: https://github.com/rust-lang/rust/pull/29129 [1.6m]: https://github.com/rust-lang/rust/pull/29828