From 676b4bbdc40be39d12b811d6871c2df59e93cde9 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Sun, 29 Oct 2017 18:21:20 +0000 Subject: [PATCH 01/15] rustdoc: Fix duplicated impls with generics The same type can appear multiple times in impls so we need to use a set to avoid adding it multiple times. --- src/librustdoc/html/render.rs | 8 ++++---- src/test/rustdoc/issue-45584.rs | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 src/test/rustdoc/issue-45584.rs diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index d538428a7e9a9..867ac0d045920 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1325,7 +1325,7 @@ impl DocFolder for Cache { // Figure out the id of this impl. This may map to a // primitive rather than always to a struct/enum. // Note: matching twice to restrict the lifetime of the `i` borrow. - let mut dids = vec![]; + let mut dids = FxHashSet(); if let clean::Item { inner: clean::ImplItem(ref i), .. } = item { let masked_trait = i.trait_.def_id().map_or(false, |d| self.masked_crates.contains(&d.krate)); @@ -1335,7 +1335,7 @@ impl DocFolder for Cache { clean::BorrowedRef { type_: box clean::ResolvedPath { did, .. }, .. } => { - dids.push(did); + dids.insert(did); } ref t => { let did = t.primitive_type().and_then(|t| { @@ -1343,7 +1343,7 @@ impl DocFolder for Cache { }); if let Some(did) = did { - dids.push(did); + dids.insert(did); } } } @@ -1352,7 +1352,7 @@ impl DocFolder for Cache { if let Some(generics) = i.trait_.as_ref().and_then(|t| t.generics()) { for bound in generics { if let Some(did) = bound.def_id() { - dids.push(did); + dids.insert(did); } } } diff --git a/src/test/rustdoc/issue-45584.rs b/src/test/rustdoc/issue-45584.rs new file mode 100644 index 0000000000000..6d6ae3dc94a21 --- /dev/null +++ b/src/test/rustdoc/issue-45584.rs @@ -0,0 +1,25 @@ +// Copyright 2017 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. + +#![crate_name = "foo"] + +pub trait Bar {} + +// @has 'foo/struct.Foo1.html' +pub struct Foo1; +// @count - '//*[@class="impl"]' 1 +// @has - '//*[@class="impl"]' "impl Bar for Foo1" +impl Bar for Foo1 {} + +// @has 'foo/struct.Foo2.html' +pub struct Foo2; +// @count - '//*[@class="impl"]' 1 +// @has - '//*[@class="impl"]' "impl Bar<&'static Foo2, Foo2> for u8" +impl Bar<&'static Foo2, Foo2> for u8 {} From af1e4f6d7ced700a03ed0f39259d7c9f6be1fb5e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 23 Oct 2017 13:34:22 +0200 Subject: [PATCH 02/15] add missing docs for MetadataExt --- src/libstd/sys/unix/ext/fs.rs | 246 ++++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs index 3e631ad40ac7f..d23cae40cfaff 100644 --- a/src/libstd/sys/unix/ext/fs.rs +++ b/src/libstd/sys/unix/ext/fs.rs @@ -215,36 +215,282 @@ impl OpenOptionsExt for OpenOptions { // casts and rely on manual lowering to `stat` if the raw type is desired. #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { + /// Returns the ID of the device containing the file. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// + /// # use std::io; + /// # fn f() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let dev_id = meta.dev(); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn dev(&self) -> u64; + /// Returns the inode number. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// + /// # use std::io; + /// # fn f() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let inode = meta.ino(); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn ino(&self) -> u64; + /// Returns the rights applied to this file. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// + /// # use std::io; + /// # fn f() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let mode = meta.mode(); + /// let user_has_write_access = mode & 0o200; + /// let user_has_read_write_access = mode & 0o600; + /// let group_has_read_access = mode & 0o040; + /// let others_have_exec_access = mode & 0o001; + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn mode(&self) -> u32; + /// Returns the number of hard links pointing to this file. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// + /// # use std::io; + /// # fn f() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let nb_hard_links = meta.nlink(); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn nlink(&self) -> u64; + /// Returns the user ID of the owner of this file. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// + /// # use std::io; + /// # fn f() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let user_id = meta.uid(); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn uid(&self) -> u32; + /// Returns the group ID of the owner of this file. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// + /// # use std::io; + /// # fn f() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let group_id = meta.gid(); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn gid(&self) -> u32; + /// Returns the device ID of this file (if it is a special one). + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// + /// # use std::io; + /// # fn f() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let device_id = meta.rdev(); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn rdev(&self) -> u64; + /// Returns the total size of this file in bytes. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// + /// # use std::io; + /// # fn f() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let file_size = meta.size(); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn size(&self) -> u64; + /// Returns the time of the last access to the file. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// + /// # use std::io; + /// # fn f() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let last_access_time = meta.atime(); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn atime(&self) -> i64; + /// Returns the time of the last access to the file in nanoseconds. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// + /// # use std::io; + /// # fn f() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let nano_last_access_time = meta.atime_nsec(); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn atime_nsec(&self) -> i64; + /// Returns the time of the last modification of the file. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// + /// # use std::io; + /// # fn f() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let last_modification_time = meta.mtime(); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn mtime(&self) -> i64; + /// Returns the time of the last modification of the file in nanoseconds. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// + /// # use std::io; + /// # fn f() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let nano_last_modification_time = meta.mtime_nsec(); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn mtime_nsec(&self) -> i64; + /// Returns the time of the last status change of the file. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// + /// # use std::io; + /// # fn f() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let last_status_change_time = meta.ctime(); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn ctime(&self) -> i64; + /// Returns the time of the last status change of the file in nanoseconds. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// + /// # use std::io; + /// # fn f() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let nano_last_status_change_time = meta.ctime_nsec(); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn ctime_nsec(&self) -> i64; + /// Returns the blocksize for filesystem I/O. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// + /// # use std::io; + /// # fn f() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let blocksize = meta.blksize(); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn blksize(&self) -> u64; + /// Returns the number of blocks allocated to the file, in 512-byte units. + /// + /// Please note that this may be smaller than `st_size / 512` when the file has holes. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs; + /// use std::os::unix::fs::MetadataExt; + /// + /// # use std::io; + /// # fn f() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let blocks = meta.blocks(); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn blocks(&self) -> u64; } From 71534c45cc4e850c4265bc1c2491a522583e1185 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 1 Nov 2017 13:39:44 +0100 Subject: [PATCH 03/15] RwLock guards are Sync if T is Currently, the compiler requires `T` to also be `Send`. There is no reason for that. `&Rw{Read,Write}LockGuard` only provides a shared referenced to `T`, sending that across threads is safe if `T` is `Sync`. --- src/libstd/sync/rwlock.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index 5555f364e6e8d..d59a0b65a6940 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -10,7 +10,6 @@ use cell::UnsafeCell; use fmt; -use marker; use mem; use ops::{Deref, DerefMut}; use ptr; @@ -102,7 +101,10 @@ pub struct RwLockReadGuard<'a, T: ?Sized + 'a> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T: ?Sized> !marker::Send for RwLockReadGuard<'a, T> {} +impl<'a, T: ?Sized> !Send for RwLockReadGuard<'a, T> {} + +#[stable(feature = "rwlock_guard_sync", since = "1.23.0")] +unsafe impl<'a, T: ?Sized + Sync> Sync for RwLockReadGuard<'a, T> {} /// RAII structure used to release the exclusive write access of a lock when /// dropped. @@ -121,7 +123,10 @@ pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T: ?Sized> !marker::Send for RwLockWriteGuard<'a, T> {} +impl<'a, T: ?Sized> !Send for RwLockWriteGuard<'a, T> {} + +#[stable(feature = "rwlock_guard_sync", since = "1.23.0")] +unsafe impl<'a, T: ?Sized + Sync> Sync for RwLockWriteGuard<'a, T> {} impl RwLock { /// Creates a new instance of an `RwLock` which is unlocked. From 568700097950cf66b09dfdf3d608d4f51e0f64ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 2 Nov 2017 11:26:46 +0200 Subject: [PATCH 04/15] Update the std::thread docs and clarify that panics can nowadays be caught --- src/libstd/thread/mod.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 28a33c7ec1465..8c60d9c7bf075 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -25,11 +25,15 @@ //! //! Fatal logic errors in Rust cause *thread panic*, during which //! a thread will unwind the stack, running destructors and freeing -//! owned resources. Thread panic is unrecoverable from within -//! the panicking thread (i.e. there is no 'try/catch' in Rust), but -//! the panic may optionally be detected from a different thread. If -//! the main thread panics, the application will exit with a non-zero -//! exit code. +//! owned resources. While not meant as a 'try/catch' mechanism, panics +//! in Rust can nonetheless be caught with +//! ['catch_unwind'](../../std/panic/fn.catch_unwind.html) and recovered +//! from, or alternatively be resumed with +//! ['resume_unwind'](../../std/panic/fn.resume_unwind.html). If the panic +//! is not caught the thread will exit, but the panic may optionally be +//! detected from a different thread with `join`. If the main thread panics +//! without the panic being caught, the application will exit with a +//! non-zero exit code. //! //! When the main thread of a Rust program terminates, the entire program shuts //! down, even if other threads are still running. However, this module provides From 283b4a1b0bcf94fed0ebc3bfd84e87d17ca1b587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 2 Nov 2017 18:29:52 +0200 Subject: [PATCH 05/15] Use ` instead of ' for function names --- src/libstd/thread/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 8c60d9c7bf075..da5965d801c25 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -27,9 +27,9 @@ //! a thread will unwind the stack, running destructors and freeing //! owned resources. While not meant as a 'try/catch' mechanism, panics //! in Rust can nonetheless be caught with -//! ['catch_unwind'](../../std/panic/fn.catch_unwind.html) and recovered +//! [`catch_unwind`](../../std/panic/fn.catch_unwind.html) and recovered //! from, or alternatively be resumed with -//! ['resume_unwind'](../../std/panic/fn.resume_unwind.html). If the panic +//! [`resume_unwind`](../../std/panic/fn.resume_unwind.html). If the panic //! is not caught the thread will exit, but the panic may optionally be //! detected from a different thread with `join`. If the main thread panics //! without the panic being caught, the application will exit with a From a12f5119101060909de1938d7d4a96854cc02780 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 2 Nov 2017 18:30:02 +0200 Subject: [PATCH 06/15] Mention that panics can't possibly be caught when compiling with panic=abort --- src/libstd/thread/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index da5965d801c25..97220ad993b4a 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -26,7 +26,7 @@ //! Fatal logic errors in Rust cause *thread panic*, during which //! a thread will unwind the stack, running destructors and freeing //! owned resources. While not meant as a 'try/catch' mechanism, panics -//! in Rust can nonetheless be caught with +//! in Rust can nonetheless be caught (unless compiling with `panic=abort`) with //! [`catch_unwind`](../../std/panic/fn.catch_unwind.html) and recovered //! from, or alternatively be resumed with //! [`resume_unwind`](../../std/panic/fn.resume_unwind.html). If the panic From b86bba594023591f4d6c795cf4da115640c3a918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 2 Nov 2017 19:09:31 +0200 Subject: [PATCH 07/15] Make join a link to the function's documentation --- src/libstd/thread/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 97220ad993b4a..ee49bf796b86f 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -31,7 +31,7 @@ //! from, or alternatively be resumed with //! [`resume_unwind`](../../std/panic/fn.resume_unwind.html). If the panic //! is not caught the thread will exit, but the panic may optionally be -//! detected from a different thread with `join`. If the main thread panics +//! detected from a different thread with [`join`]. If the main thread panics //! without the panic being caught, the application will exit with a //! non-zero exit code. //! From 784528b8da35d1f82c696887c293b215f0a1b4b4 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Perennou Date: Sat, 28 Oct 2017 09:54:05 +0200 Subject: [PATCH 08/15] rustbuild: don't try to install rls if ToolState is not Testing The Dist Step is not ran in that case so we would end up trying to install something that we didn't dist. Signed-off-by: Marc-Antoine Perennou --- src/bootstrap/install.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index 608924c9c28d1..1b5f6373c52f4 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -186,8 +186,11 @@ install!((self, builder, _config), install_cargo(builder, self.stage, self.target); }; Rls, "rls", _config.extended, only_hosts: true, { - builder.ensure(dist::Rls { stage: self.stage, target: self.target }); - install_rls(builder, self.stage, self.target); + if builder.ensure(dist::Rls { stage: self.stage, target: self.target }).is_some() { + install_rls(builder, self.stage, self.target); + } else { + println!("skipping Install RLS stage{} ({})", self.stage, self.target); + } }; Analysis, "analysis", _config.extended, only_hosts: false, { builder.ensure(dist::Analysis { From 6363b06ffccf1570e77641db8323d54a72f7db9e Mon Sep 17 00:00:00 2001 From: Ryan Scheel Date: Sat, 4 Nov 2017 20:53:27 -0700 Subject: [PATCH 09/15] Update reference link in doc's 404 It's currently linking to a page that says it's on the page I'm changing the link too. --- src/doc/not_found.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/not_found.md b/src/doc/not_found.md index 5d632ebc68f7a..ebe7c59313fa5 100644 --- a/src/doc/not_found.md +++ b/src/doc/not_found.md @@ -22,7 +22,7 @@ Some things that might be helpful to you though: # Reference * [The Rust official site](https://www.rust-lang.org) -* [The Rust reference](https://doc.rust-lang.org/reference.html) +* [The Rust reference](https://doc.rust-lang.org/reference/index.html) # Docs From 03de2c719af3334afc4764979dc70c99b731b088 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Sat, 4 Nov 2017 17:45:10 +0100 Subject: [PATCH 10/15] [xsave] whitelist xsave target features Whitelists `xsave`, `xsaveopt`, `xsavec`, `xsavec`. --- src/librustc_trans/llvm_util.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs index 448feb5259ddd..35c4d3367ad06 100644 --- a/src/librustc_trans/llvm_util.rs +++ b/src/librustc_trans/llvm_util.rs @@ -76,7 +76,9 @@ const ARM_WHITELIST: &'static [&'static str] = &["neon\0", "vfp2\0", "vfp3\0", " const X86_WHITELIST: &'static [&'static str] = &["avx\0", "avx2\0", "bmi\0", "bmi2\0", "sse\0", "sse2\0", "sse3\0", "sse4.1\0", "sse4.2\0", "ssse3\0", "tbm\0", "lzcnt\0", "popcnt\0", - "sse4a\0", "rdrnd\0", "rdseed\0", "fma\0"]; + "sse4a\0", "rdrnd\0", "rdseed\0", "fma\0", + "xsave\0", "xsaveopt\0", "xsavec\0", + "xsaves\0"]; const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"]; From 5abc5240730c3db243300444f0ee79847f4046fb Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Sat, 4 Nov 2017 14:13:44 -0500 Subject: [PATCH 11/15] rustdoc: add #[allow(unused)] to every doctest also modify the order crate attributes are applied, to have a better order of how things can override lints, either per-crate or per-test --- src/librustdoc/test.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 9316805b9322a..9bbd16355be38 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -337,15 +337,23 @@ pub fn make_test(s: &str, let mut prog = String::new(); - // First push any outer attributes from the example, assuming they - // are intended to be crate attributes. - prog.push_str(&crate_attrs); + if opts.attrs.is_empty() { + // If there aren't any attributes supplied by #![doc(test(attr(...)))], then allow some + // lints that are commonly triggered in doctests. The crate-level test attributes are + // commonly used to make tests fail in case they trigger warnings, so having this there in + // that case may cause some tests to pass when they shouldn't have. + prog.push_str("#![allow(unused)]\n"); + } - // Next, any attributes for other aspects such as lints. + // Next, any attributes that came from the crate root via #![doc(test(attr(...)))]. for attr in &opts.attrs { prog.push_str(&format!("#![{}]\n", attr)); } + // Now push any outer attributes from the example, assuming they + // are intended to be crate attributes. + prog.push_str(&crate_attrs); + // Don't inject `extern crate std` because it's already injected by the // compiler. if !s.contains("extern crate") && !opts.no_crate_inject && cratename != Some("std") { From ce2768ab95cbac4c4b918c9f382cd5316e286a7a Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Sun, 5 Nov 2017 10:24:05 -0600 Subject: [PATCH 12/15] add #![allow(unused)] to the playground link rustdoc tests --- src/test/rustdoc/playground-arg.rs | 2 +- src/test/rustdoc/playground.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/rustdoc/playground-arg.rs b/src/test/rustdoc/playground-arg.rs index f0d55ef6e9fcd..478477dea61ed 100644 --- a/src/test/rustdoc/playground-arg.rs +++ b/src/test/rustdoc/playground-arg.rs @@ -21,4 +21,4 @@ pub fn dummy() {} // ensure that `extern crate foo;` was inserted into code snips automatically: -// @matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=extern%20crate%20foo%3B%0Afn%20main()%20%7B%0Ause%20foo%3A%3Adummy%3B%0Adummy()%3B%0A%7D"]' "Run" +// @matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=%23!%5Ballow(unused)%5D%0Aextern%20crate%20foo%3B%0Afn%20main()%20%7B%0Ause%20foo%3A%3Adummy%3B%0Adummy()%3B%0A%7D"]' "Run" diff --git a/src/test/rustdoc/playground.rs b/src/test/rustdoc/playground.rs index 9eb8dec51a7f2..8e193efaf8504 100644 --- a/src/test/rustdoc/playground.rs +++ b/src/test/rustdoc/playground.rs @@ -34,6 +34,6 @@ //! } //! ``` -// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=fn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D%0A"]' "Run" -// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=fn%20main()%20%7B%0Aprintln!(%22Hello%2C%20world!%22)%3B%0A%7D"]' "Run" -// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Bfeature(something)%5D%0A%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D%0A&version=nightly"]' "Run" +// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D%0A"]' "Run" +// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0Aprintln!(%22Hello%2C%20world!%22)%3B%0A%7D"]' "Run" +// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0A%23!%5Bfeature(something)%5D%0A%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D%0A&version=nightly"]' "Run" From 94d9ff5303701cf9644981695233c55b8703e11f Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Mon, 6 Nov 2017 11:44:00 +0100 Subject: [PATCH 13/15] [intrinsics] add missing div and rem vector intrinsics --- src/librustc_trans/intrinsic.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index e80239175681e..2f1a95038eae5 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -1203,7 +1203,8 @@ fn generic_simd_intrinsic<'a, 'tcx>( simd_add: TyUint, TyInt => add, TyFloat => fadd; simd_sub: TyUint, TyInt => sub, TyFloat => fsub; simd_mul: TyUint, TyInt => mul, TyFloat => fmul; - simd_div: TyFloat => fdiv; + simd_div: TyUint => udiv, TyInt => sdiv, TyFloat => fdiv; + simd_rem: TyUint => urem, TyInt => srem, TyFloat => frem; simd_shl: TyUint, TyInt => shl; simd_shr: TyUint => lshr, TyInt => ashr; simd_and: TyUint, TyInt => and; From 01ced6ecda12add7251b39b6f27bf8d627df7d8a Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Mon, 6 Nov 2017 13:37:26 +0100 Subject: [PATCH 14/15] [intrinsics] add div and rem vector tests --- src/librustc_typeck/check/intrinsic.rs | 2 +- .../simd-intrinsic-generic-arithmetic.rs | 11 ++++++----- .../run-pass/simd-intrinsic-generic-arithmetic.rs | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 3861a358b23e0..6ef0c37a31583 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -348,7 +348,7 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, "simd_eq" | "simd_ne" | "simd_lt" | "simd_le" | "simd_gt" | "simd_ge" => { (2, vec![param(0), param(0)], param(1)) } - "simd_add" | "simd_sub" | "simd_mul" | + "simd_add" | "simd_sub" | "simd_mul" | "simd_rem" | "simd_div" | "simd_shl" | "simd_shr" | "simd_and" | "simd_or" | "simd_xor" => { (1, vec![param(0), param(0)], param(0)) diff --git a/src/test/compile-fail/simd-intrinsic-generic-arithmetic.rs b/src/test/compile-fail/simd-intrinsic-generic-arithmetic.rs index 35c368f4cbedb..ee08ca05e803f 100644 --- a/src/test/compile-fail/simd-intrinsic-generic-arithmetic.rs +++ b/src/test/compile-fail/simd-intrinsic-generic-arithmetic.rs @@ -27,6 +27,7 @@ extern "platform-intrinsic" { fn simd_sub(x: T, y: T) -> T; fn simd_mul(x: T, y: T) -> T; fn simd_div(x: T, y: T) -> T; + fn simd_rem(x: T, y: T) -> T; fn simd_shl(x: T, y: T) -> T; fn simd_shr(x: T, y: T) -> T; fn simd_and(x: T, y: T) -> T; @@ -49,8 +50,12 @@ fn main() { simd_mul(x, x); simd_mul(y, y); simd_mul(z, z); - + simd_div(x, x); + simd_div(y, y); simd_div(z, z); + simd_rem(x, x); + simd_rem(y, y); + simd_rem(z, z); simd_shl(x, x); simd_shl(y, y); @@ -84,10 +89,6 @@ fn main() { //~^ ERROR expected SIMD input type, found non-SIMD `i32` - simd_div(x, x); -//~^ ERROR unsupported operation on `i32x4` with element `i32` - simd_div(y, y); -//~^ ERROR unsupported operation on `u32x4` with element `u32` simd_shl(z, z); //~^ ERROR unsupported operation on `f32x4` with element `f32` simd_shr(z, z); diff --git a/src/test/run-pass/simd-intrinsic-generic-arithmetic.rs b/src/test/run-pass/simd-intrinsic-generic-arithmetic.rs index 5d4ecbb5f8172..1894cd0084bcb 100644 --- a/src/test/run-pass/simd-intrinsic-generic-arithmetic.rs +++ b/src/test/run-pass/simd-intrinsic-generic-arithmetic.rs @@ -35,6 +35,7 @@ extern "platform-intrinsic" { fn simd_sub(x: T, y: T) -> T; fn simd_mul(x: T, y: T) -> T; fn simd_div(x: T, y: T) -> T; + fn simd_rem(x: T, y: T) -> T; fn simd_shl(x: T, y: T) -> T; fn simd_shr(x: T, y: T) -> T; fn simd_and(x: T, y: T) -> T; @@ -72,9 +73,22 @@ fn main() { all_eq!(simd_sub(z2, z1), f32x4(1.0, 1.0, 1.0, 1.0)); all_eq!(simd_sub(z1, z2), f32x4(-1.0, -1.0, -1.0, -1.0)); + all_eq!(simd_div(x1, x1), i32x4(1, 1, 1, 1)); + all_eq!(simd_div(i32x4(2, 4, 6, 8), i32x4(2, 2, 2, 2)), x1); + all_eq!(simd_div(y1, y1), u32x4(1, 1, 1, 1)); + all_eq!(simd_div(u32x4(2, 4, 6, 8), u32x4(2, 2, 2, 2)), y1); + all_eq!(simd_div(z1, z1), f32x4(1.0, 1.0, 1.0, 1.0)); all_eq!(simd_div(z1, z2), f32x4(1.0/2.0, 2.0/3.0, 3.0/4.0, 4.0/5.0)); all_eq!(simd_div(z2, z1), f32x4(2.0/1.0, 3.0/2.0, 4.0/3.0, 5.0/4.0)); + all_eq!(simd_rem(x1, x1), i32x4(0, 0, 0, 0)); + all_eq!(simd_rem(x2, x1), i32x4(0, 1, 1, 1)); + all_eq!(simd_rem(y1, y1), u32x4(0, 0, 0, 0)); + all_eq!(simd_rem(y2, y1), u32x4(0, 1, 1, 1)); + all_eq!(simd_rem(z1, z1), f32x4(0.0, 0.0, 0.0, 0.0)); + all_eq!(simd_rem(z1, z2), z1); + all_eq!(simd_rem(z2, z1), f32x4(0.0, 1.0, 1.0, 1.0)); + all_eq!(simd_shl(x1, x2), i32x4(1 << 2, 2 << 3, 3 << 4, 4 << 5)); all_eq!(simd_shl(x2, x1), i32x4(2 << 1, 3 << 2, 4 << 3, 5 << 4)); all_eq!(simd_shl(y1, y2), u32x4(1 << 2, 2 << 3, 3 << 4, 4 << 5)); From c3ea358121e493ace14308e153b70692439fb154 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sun, 5 Nov 2017 09:20:59 -0500 Subject: [PATCH 15/15] Display all emission types in error msg if user inputs invalid option. before: ``` > rustc --emit foo error: unknown emission type: `foo` ``` after: ``` > rustc --emit foo error: unknown emission type: `foo` - expected one of: `llvm-bc`, `asm`, `llvm-ir`, `mir`, `obj`, `metadata`, `link`, `dep-info` ``` --- src/librustc/session/config.rs | 48 +++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 8401d493b9dbf..a27371926de86 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -138,6 +138,34 @@ impl OutputType { } } + fn from_shorthand(shorthand: &str) -> Option { + Some(match shorthand { + "asm" => OutputType::Assembly, + "llvm-ir" => OutputType::LlvmAssembly, + "mir" => OutputType::Mir, + "llvm-bc" => OutputType::Bitcode, + "obj" => OutputType::Object, + "metadata" => OutputType::Metadata, + "link" => OutputType::Exe, + "dep-info" => OutputType::DepInfo, + _ => return None, + }) + } + + fn shorthands_display() -> String { + format!( + "`{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`", + OutputType::Bitcode.shorthand(), + OutputType::Assembly.shorthand(), + OutputType::LlvmAssembly.shorthand(), + OutputType::Mir.shorthand(), + OutputType::Object.shorthand(), + OutputType::Metadata.shorthand(), + OutputType::Exe.shorthand(), + OutputType::DepInfo.shorthand(), + ) + } + pub fn extension(&self) -> &'static str { match *self { OutputType::Bitcode => "bc", @@ -1479,19 +1507,13 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) for list in matches.opt_strs("emit") { for output_type in list.split(',') { let mut parts = output_type.splitn(2, '='); - let output_type = match parts.next().unwrap() { - "asm" => OutputType::Assembly, - "llvm-ir" => OutputType::LlvmAssembly, - "mir" => OutputType::Mir, - "llvm-bc" => OutputType::Bitcode, - "obj" => OutputType::Object, - "metadata" => OutputType::Metadata, - "link" => OutputType::Exe, - "dep-info" => OutputType::DepInfo, - part => { - early_error(error_format, &format!("unknown emission type: `{}`", - part)) - } + let shorthand = parts.next().unwrap(); + let output_type = match OutputType::from_shorthand(shorthand) { + Some(output_type) => output_type, + None => early_error(error_format, &format!( + "unknown emission type: `{}` - expected one of: {}", + shorthand, OutputType::shorthands_display(), + )), }; let path = parts.next().map(PathBuf::from); output_types.insert(output_type, path);