From db16ca7c839c6dcc5a3103b5e0b37239dd21e450 Mon Sep 17 00:00:00 2001 From: David LeGare Date: Fri, 5 May 2017 20:35:07 -0500 Subject: [PATCH 001/103] Update documention in windows::ffi --- src/libstd/sys/windows/ext/ffi.rs | 42 +++++++++++++++++++++++++++---- src/libstd/sys/windows/ext/mod.rs | 10 +++++--- src/libstd/sys_common/wtf8.rs | 1 + 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/libstd/sys/windows/ext/ffi.rs b/src/libstd/sys/windows/ext/ffi.rs index 253787546c1..cb13595fcd6 100644 --- a/src/libstd/sys/windows/ext/ffi.rs +++ b/src/libstd/sys/windows/ext/ffi.rs @@ -26,8 +26,22 @@ pub trait OsStringExt { /// Creates an `OsString` from a potentially ill-formed UTF-16 slice of /// 16-bit code units. /// - /// This is lossless: calling `.encode_wide()` on the resulting string + /// This is lossless: calling [`encode_wide()`] on the resulting string /// will always return the original code units. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::OsString; + /// use std::os::windows::prelude::*; + /// + /// // UTF-16 encoding for "Unicode". + /// let source = [0x0055, 0x006E, 0x0069, 0x0063, 0x006F, 0x0064, 0x0065]; + /// + /// let string = OsString::from_wide(&source[..]); + /// ``` + /// + /// [`encode_wide()`]: ./trait.OsStrExt.html#tymethod.encode_wide #[stable(feature = "rust1", since = "1.0.0")] fn from_wide(wide: &[u16]) -> Self; } @@ -42,11 +56,29 @@ impl OsStringExt for OsString { /// Windows-specific extensions to `OsStr`. #[stable(feature = "rust1", since = "1.0.0")] pub trait OsStrExt { - /// Re-encodes an `OsStr` as a wide character sequence, - /// i.e. potentially ill-formed UTF-16. + /// Re-encodes an `OsStr` as a wide character sequence, i.e. potentially + /// ill-formed UTF-16. /// - /// This is lossless. Note that the encoding does not include a final - /// null. + /// This is lossless: calling [`OsString::from_wide()`] and then + /// `encode_wide()` on the result will yield the original code units. + /// Note that the encoding does not add a final null terminator. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::OsString; + /// use std::os::windows::prelude::*; + /// + /// // UTF-16 encoding for "Unicode". + /// let source = [0x0055, 0x006E, 0x0069, 0x0063, 0x006F, 0x0064, 0x0065]; + /// + /// let string = OsString::from_wide(&source[..]); + /// + /// let result: Vec = string.encode_wide().collect(); + /// assert_eq!(&source[..], &result[..]); + /// ``` + /// + /// [`OsString::from_wide()`]: ./trait.OsStringExt.html#tymethod.from_wide #[stable(feature = "rust1", since = "1.0.0")] fn encode_wide(&self) -> EncodeWide; } diff --git a/src/libstd/sys/windows/ext/mod.rs b/src/libstd/sys/windows/ext/mod.rs index f12e50cc923..e07acad5e46 100644 --- a/src/libstd/sys/windows/ext/mod.rs +++ b/src/libstd/sys/windows/ext/mod.rs @@ -8,11 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Experimental extensions to `std` for Windows. +//! Platform-specific extensions to `std` for Windows. //! -//! For now, this module is limited to extracting handles, file -//! descriptors, and sockets, but its functionality will grow over -//! time. +//! Provides access to platform-level information for Windows, and exposes +//! Windows-specific idioms that would otherwise be inappropriate as part +//! the core `std` library. These extensions allow developers to use +//! `std` types and idioms with Windows in a way that the noraml +//! platform-agnostic idioms would not normally support. #![stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs index 79aaf34ce2e..df5e4ef1d88 100644 --- a/src/libstd/sys_common/wtf8.rs +++ b/src/libstd/sys_common/wtf8.rs @@ -750,6 +750,7 @@ impl<'a> Iterator for Wtf8CodePoints<'a> { } } +/// Generates a wide character sequence for potentially ill-formed UTF-16. #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct EncodeWide<'a> { From e406cd1ec9abb77236318db30e362e4654411a1a Mon Sep 17 00:00:00 2001 From: David LeGare Date: Fri, 5 May 2017 20:35:35 -0500 Subject: [PATCH 002/103] Update documentation in windows::ffi --- src/libstd/sys/windows/ext/fs.rs | 112 +++++++++++++++++++++++++------ 1 file changed, 91 insertions(+), 21 deletions(-) diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs index c63dd8a47ca..ea322b9822a 100644 --- a/src/libstd/sys/windows/ext/fs.rs +++ b/src/libstd/sys/windows/ext/fs.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Windows-specific extensions for the primitives in `std::fs` +//! Windows-specific extensions for the primitives in the `std::fs` module. #![stable(feature = "rust1", since = "1.0.0")] @@ -35,6 +35,25 @@ pub trait FileExt { /// Note that similar to `File::read`, it is not an error to return with a /// short read. When returning from such a short read, the file pointer is /// still updated. + /// + /// # Examples + /// + /// ``` + /// use std::io; + /// use std::io::prelude::*; + /// use std::fs::File; + /// use std::os::windows::prelude::*; + /// + /// # fn foo() -> io::Result<()> { + /// let mut file = File::open("foo.txt")?; + /// let mut buffer = [0; 10]; + /// + /// // Read 10 bytes, starting 72 bytes from the + /// // start of the file. + /// file.seek_read(&mut buffer[..], 72)?; + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "file_offset", since = "1.15.0")] fn seek_read(&self, buf: &mut [u8], offset: u64) -> io::Result; @@ -52,6 +71,23 @@ pub trait FileExt { /// Note that similar to `File::write`, it is not an error to return a /// short write. When returning from such a short write, the file pointer /// is still updated. + /// + /// # Examples + /// + /// ``` + /// use std::io::prelude::*; + /// use std::fs::File; + /// use std::os::windows::prelude::*; + /// + /// # fn foo() -> std::io::Result<()> { + /// let mut buffer = File::create("foo.txt")?; + /// + /// // Write a byte string starting 72 bytes from + /// // the start of the file. + /// buffer.write(b"some bytes", offset)?; + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "file_offset", since = "1.15.0")] fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result; } @@ -70,13 +106,13 @@ impl FileExt for fs::File { /// Windows-specific extensions to `OpenOptions` #[stable(feature = "open_options_ext", since = "1.10.0")] pub trait OpenOptionsExt { - /// Overrides the `dwDesiredAccess` argument to the call to `CreateFile` + /// Overrides the `dwDesiredAccess` argument to the call to [`CreateFile`] /// with the specified value. /// /// This will override the `read`, `write`, and `append` flags on the /// `OpenOptions` structure. This method provides fine-grained control over /// the permissions to read, write and append data, attributes (like hidden - /// and system) and extended attributes. + /// and system), and extended attributes. /// /// # Examples /// @@ -88,16 +124,20 @@ pub trait OpenOptionsExt { /// // to call `stat()` on the file /// let file = OpenOptions::new().access_mode(0).open("foo.txt"); /// ``` + /// + /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx #[stable(feature = "open_options_ext", since = "1.10.0")] fn access_mode(&mut self, access: u32) -> &mut Self; - /// Overrides the `dwShareMode` argument to the call to `CreateFile` with + /// Overrides the `dwShareMode` argument to the call to [`CreateFile`] with /// the specified value. /// /// By default `share_mode` is set to - /// `FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE`. Specifying - /// less permissions denies others to read from, write to and/or delete the - /// file while it is open. + /// `FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE`. This allows + /// other processes to to read, write, and delete/rename the same file + /// while it is open. Removing any of the flags will prevent other + /// processes from performing the corresponding operation until the file + /// handle is closed. /// /// # Examples /// @@ -106,42 +146,46 @@ pub trait OpenOptionsExt { /// use std::os::windows::fs::OpenOptionsExt; /// /// // Do not allow others to read or modify this file while we have it open - /// // for writing + /// // for writing. /// let file = OpenOptions::new().write(true) /// .share_mode(0) /// .open("foo.txt"); /// ``` + /// + /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx #[stable(feature = "open_options_ext", since = "1.10.0")] fn share_mode(&mut self, val: u32) -> &mut Self; /// Sets extra flags for the `dwFileFlags` argument to the call to - /// `CreateFile2` (or combines it with `attributes` and `security_qos_flags` - /// to set the `dwFlagsAndAttributes` for `CreateFile`). + /// [`CreateFile2`] to the specified value (or combines it with + /// `attributes` and `security_qos_flags` to set the `dwFlagsAndAttributes` + /// for [`CreateFile`]). /// - /// Custom flags can only set flags, not remove flags set by Rusts options. - /// This options overwrites any previously set custom flags. + /// Custom flags can only set flags, not remove flags set by Rust's options. + /// This option overwrites any previously set custom flags. /// /// # Examples /// - /// ```rust,ignore + /// ```ignore /// extern crate winapi; /// use std::fs::OpenOptions; /// use std::os::windows::fs::OpenOptionsExt; /// /// let mut options = OpenOptions::new(); /// options.create(true).write(true); - /// if cfg!(windows) { - /// options.custom_flags(winapi::FILE_FLAG_DELETE_ON_CLOSE); - /// } + /// options.custom_flags(winapi::FILE_FLAG_DELETE_ON_CLOSE); /// let file = options.open("foo.txt"); /// ``` + /// + /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx + /// [`CreateFile2`]: https://msdn.microsoft.com/en-us/library/windows/desktop/hh449422.aspx #[stable(feature = "open_options_ext", since = "1.10.0")] fn custom_flags(&mut self, flags: u32) -> &mut Self; - /// Sets the `dwFileAttributes` argument to the call to `CreateFile2` to + /// Sets the `dwFileAttributes` argument to the call to [`CreateFile2`] to /// the specified value (or combines it with `custom_flags` and /// `security_qos_flags` to set the `dwFlagsAndAttributes` for - /// `CreateFile`). + /// [`CreateFile`]). /// /// If a _new_ file is created because it does not yet exist and ///`.create(true)` or `.create_new(true)` are specified, the new file is @@ -155,7 +199,7 @@ pub trait OpenOptionsExt { /// /// # Examples /// - /// ```rust,ignore + /// ```ignore /// extern crate winapi; /// use std::fs::OpenOptions; /// use std::os::windows::fs::OpenOptionsExt; @@ -164,12 +208,38 @@ pub trait OpenOptionsExt { /// .attributes(winapi::FILE_ATTRIBUTE_HIDDEN) /// .open("foo.txt"); /// ``` + /// + /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx + /// [`CreateFile2`]: https://msdn.microsoft.com/en-us/library/windows/desktop/hh449422.aspx #[stable(feature = "open_options_ext", since = "1.10.0")] fn attributes(&mut self, val: u32) -> &mut Self; - /// Sets the `dwSecurityQosFlags` argument to the call to `CreateFile2` to + /// Sets the `dwSecurityQosFlags` argument to the call to [`CreateFile2`] to /// the specified value (or combines it with `custom_flags` and `attributes` - /// to set the `dwFlagsAndAttributes` for `CreateFile`). + /// to set the `dwFlagsAndAttributes` for [`CreateFile`]). + /// + /// By default, `security_qos_flags` is set to `SECURITY_ANONYMOUS`. For + /// information about possible values, see [Impersonation Levels] on the + /// Windows Dev Center site. + /// + /// # Examples + /// + /// ```ignore + /// use std::fs::OpenOptions; + /// use std::os::windows::fs::OpenOptionsExt; + /// + /// let options = OpenOptions::new(); + /// options.write(true).create(true); + /// + /// // Sets the flag value to `SecurityIdentification`. + /// options.security_qos_flags(1); + /// + /// let file = options.open("foo.txt"); + /// ``` + /// + /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx + /// [`CreateFile2`]: https://msdn.microsoft.com/en-us/library/windows/desktop/hh449422.aspx + /// [Impersonation Levels]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa379572.aspx #[stable(feature = "open_options_ext", since = "1.10.0")] fn security_qos_flags(&mut self, flags: u32) -> &mut OpenOptions; } From 76128b32ccaed5576331ec10e8bdf2c5919978d5 Mon Sep 17 00:00:00 2001 From: David LeGare Date: Sat, 6 May 2017 23:05:47 -0500 Subject: [PATCH 003/103] Update documentation in windows::fs --- src/libstd/sys/windows/ext/fs.rs | 137 ++++++++++++++++++++++++++++--- 1 file changed, 127 insertions(+), 10 deletions(-) diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs index e2e405db276..d49c884cb9f 100644 --- a/src/libstd/sys/windows/ext/fs.rs +++ b/src/libstd/sys/windows/ext/fs.rs @@ -18,7 +18,9 @@ use path::Path; use sys; use sys_common::{AsInnerMut, AsInner}; -/// Windows-specific extensions to `File` +/// Windows-specific extensions to [`File`]. +/// +/// [`File`]: ../../../fs/struct.File.html #[stable(feature = "file_offset", since = "1.15.0")] pub trait FileExt { /// Seeks to a given position and reads a number of bytes. @@ -103,7 +105,9 @@ impl FileExt for fs::File { } } -/// Windows-specific extensions to `OpenOptions` +/// Windows-specific extensions to [`OpenOptions`]. +/// +/// [`OpenOptions`]: ../../../fs/struct.OpenOptions.html #[stable(feature = "open_options_ext", since = "1.10.0")] pub trait OpenOptionsExt { /// Overrides the `dwDesiredAccess` argument to the call to [`CreateFile`] @@ -267,35 +271,134 @@ impl OpenOptionsExt for OpenOptions { } } -/// Extension methods for `fs::Metadata` to access the raw fields contained +/// Extension methods for [`fs::Metadata`] to access the raw fields contained /// within. +/// +/// The data members that this trait exposes correspond to the members +/// of the [`BY_HANDLE_FILE_INFORMATION`] structure. +/// +/// [`fs::Metadata`]: ../../../fs/struct.Metadata.html +/// [`BY_HANDLE_FILE_INFORMATION`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363788.aspx #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Returns the value of the `dwFileAttributes` field of this metadata. /// /// This field contains the file system attribute information for a file - /// or directory. + /// or directory. For possible values and their descriptions, see + /// [File Attribute Constants] in the Windows Dev Center. + /// + /// # Examples + /// + /// ```ignore + /// use std::io; + /// use std::io::prelude::*; + /// use std::fs::File; + /// use std::os::windows::prelude::*; + /// + /// # fn foo() -> io::Result<()> { + /// let mut file = File::open("foo.txt")?; + /// let attributes = file.file_attributes(); + /// # } + /// ``` + /// + /// [File Attribute Constants]: https://msdn.microsoft.com/en-us/library/windows/desktop/gg258117.aspx #[stable(feature = "metadata_ext", since = "1.1.0")] fn file_attributes(&self) -> u32; /// Returns the value of the `ftCreationTime` field of this metadata. /// - /// The returned 64-bit value represents the number of 100-nanosecond - /// intervals since January 1, 1601 (UTC). + /// The returned 64-bit value is equivalent to a [`FILETIME`] struct, + /// which represents the number of 100-nanosecond intervals since + /// January 1, 1601 (UTC). The struct is automatically + /// converted to a `u64` value, as that is the recommended way + /// to use it. + /// + /// If the underlying filesystem does not support creation time, the + /// returned value is 0. + /// + /// # Examples + /// + /// ```ignore + /// use std::io; + /// use std::io::prelude::*; + /// use std::fs::File; + /// use std::os::windows::prelude::*; + /// + /// # fn foo() -> io::Result<()> { + /// let mut file = File::open("foo.txt")?; + /// let creation_time = file.creation_time(); + /// # } + /// ``` + /// + /// [`FILETIME`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx #[stable(feature = "metadata_ext", since = "1.1.0")] fn creation_time(&self) -> u64; /// Returns the value of the `ftLastAccessTime` field of this metadata. /// - /// The returned 64-bit value represents the number of 100-nanosecond - /// intervals since January 1, 1601 (UTC). + /// The returned 64-bit value is equivalent to a [`FILETIME`] struct, + /// which represents the number of 100-nanosecond intervals since + /// January 1, 1601 (UTC). The struct is automatically + /// converted to a `u64` value, as that is the recommended way + /// to use it. + /// + /// For a file, the value specifies the last time that a file was read + /// from or written to. For a directory, the value specifies when + /// the directory was created. For both files and directories, the + /// specified date is correct, but the time of day is always set to + /// midnight. + /// + /// If the underlying filesystem does not support last access time, the + /// returned value is 0. + /// + /// # Examples + /// + /// ```ignore + /// use std::io; + /// use std::io::prelude::*; + /// use std::fs::File; + /// use std::os::windows::prelude::*; + /// + /// # fn foo() -> io::Result<()> { + /// let mut file = File::open("foo.txt")?; + /// let last_access_time = file.last_access_time(); + /// # } + /// ``` + /// + /// [`FILETIME`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx #[stable(feature = "metadata_ext", since = "1.1.0")] fn last_access_time(&self) -> u64; /// Returns the value of the `ftLastWriteTime` field of this metadata. /// - /// The returned 64-bit value represents the number of 100-nanosecond - /// intervals since January 1, 1601 (UTC). + /// The returned 64-bit value is equivalent to a [`FILETIME`] struct, + /// which represents the number of 100-nanosecond intervals since + /// January 1, 1601 (UTC). The struct is automatically + /// converted to a `u64` value, as that is the recommended way + /// to use it. + /// + /// For a file, the value specifies the last time that a file was written + /// to. For a directory, the structure specifies when the directory was + /// created. + /// + /// If the underlying filesystem does not support the last write time + /// time, the returned value is 0. + /// + /// # Examples + /// + /// ```ignore + /// use std::io; + /// use std::io::prelude::*; + /// use std::fs::File; + /// use std::os::windows::prelude::*; + /// + /// # fn foo() -> io::Result<()> { + /// let mut file = File::open("foo.txt")?; + /// let last_write_time = file.last_write_time(); + /// # } + /// ``` + /// + /// [`FILETIME`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx #[stable(feature = "metadata_ext", since = "1.1.0")] fn last_write_time(&self) -> u64; @@ -303,6 +406,20 @@ pub trait MetadataExt { /// metadata. /// /// The returned value does not have meaning for directories. + /// + /// # Examples + /// + /// ```ignore + /// use std::io; + /// use std::io::prelude::*; + /// use std::fs::File; + /// use std::os::windows::prelude::*; + /// + /// # fn foo() -> io::Result<()> { + /// let mut file = File::open("foo.txt")?; + /// let file_size = file.file_size(); + /// # } + /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn file_size(&self) -> u64; } From c350bc17eedc776eacf194472107ec82756b204a Mon Sep 17 00:00:00 2001 From: David LeGare Date: Sun, 7 May 2017 10:35:45 -0500 Subject: [PATCH 004/103] Fix documentation tests in windows::fs --- src/libstd/sys/windows/ext/fs.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs index d49c884cb9f..c4ec75d32e4 100644 --- a/src/libstd/sys/windows/ext/fs.rs +++ b/src/libstd/sys/windows/ext/fs.rs @@ -42,7 +42,6 @@ pub trait FileExt { /// /// ``` /// use std::io; - /// use std::io::prelude::*; /// use std::fs::File; /// use std::os::windows::prelude::*; /// @@ -77,7 +76,6 @@ pub trait FileExt { /// # Examples /// /// ``` - /// use std::io::prelude::*; /// use std::fs::File; /// use std::os::windows::prelude::*; /// @@ -86,7 +84,7 @@ pub trait FileExt { /// /// // Write a byte string starting 72 bytes from /// // the start of the file. - /// buffer.write(b"some bytes", offset)?; + /// buffer.seek_write(b"some bytes", 72)?; /// # Ok(()) /// # } /// ``` From 52c33804af9c85121fe8b65166e11ac2d1feee97 Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Tue, 9 May 2017 12:30:26 +0100 Subject: [PATCH 005/103] loop_break_value: add documentation for book --- .../src/language-features/loop-break-value.md | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/src/doc/unstable-book/src/language-features/loop-break-value.md b/src/doc/unstable-book/src/language-features/loop-break-value.md index 54d6e62ce4c..23527cfe8bd 100644 --- a/src/doc/unstable-book/src/language-features/loop-break-value.md +++ b/src/doc/unstable-book/src/language-features/loop-break-value.md @@ -4,7 +4,89 @@ The tracking issue for this feature is: [#37339] [#37339]: https://github.com/rust-lang/rust/issues/37339 +Documentation to be appended to section 3.6 of the book: Loops (after "Loop Labels", or before if +the "Break" section is moved). If this is deemed too complex a feature this early in the book, it +could also be moved to a new section (please advise). This would allow examples breaking with +non-primitive types, references, and discussion of coercion (probably unnecessary however). + ------------------------ +### Loops as expressions +Like everything else in Rust, loops are expressions; for example, the following is perfectly legal, +if rather useless: +```rust +let result = for n in 1..4 { + println!("Hello, {}", n); +}; +assert_eq!(result, ()); +``` + +Until now, all the loops you have seen evaluate to either `()` or `!`, the latter being special +syntax for "no value", meaning the loop never exits. A `loop` can instead evaluate to +a useful value via *break with value*: + +```rust +// Find the first square number over 1000: +let mut n = 1; +let square = loop { + if n * n > 1000 { + break n * n; + } + n += 1; +}; +``` + +The evaluation type may be specified externally: + +```rust +// Declare that value returned is unsigned 64-bit: +let n: u64 = loop { + break 1; +}; +``` + +It is an error if types do not agree, either between a "break" value and an external requirement, +or between multiple "break" values: + +```rust +loop { + if random_bool() { + break 1u32; + } else { + break 0u8; // error: types do not agree + } +}; + +let n: i32 = loop { + break 0u32; // error: type does not agree with external requirement +}; +``` + +For now, breaking with a value is only possible with `loop`; the same functionality may +some day be added to `for` and `while` (this would require some new syntax like +`while f() { break 1; } default { break 0; }`). + +#### Break: label, value + +Four forms of `break` are available, where EXPR is some expression which evaluates to a value: + +1. `break;` +2. `break 'label;` +3. `break EXPR;` +4. `break 'label EXPR;` + +When no value is given, the value `()` is assumed, thus `break;` is equivalent to `break ();`. + +Using a label allows returning a value from an inner loop: + +```rust +let result = 'outer: loop { + for n in 1..10 { + if n > 4 { + break 'outer n; + } + } +}; +``` From 7d94b4804a51ec7da42ddf3ff4a6bed0518319f7 Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Tue, 9 May 2017 15:48:45 +0100 Subject: [PATCH 006/103] loop_break_value: address review comments on book addition --- .../src/language-features/loop-break-value.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/loop-break-value.md b/src/doc/unstable-book/src/language-features/loop-break-value.md index 23527cfe8bd..dae04d737b7 100644 --- a/src/doc/unstable-book/src/language-features/loop-break-value.md +++ b/src/doc/unstable-book/src/language-features/loop-break-value.md @@ -4,16 +4,13 @@ The tracking issue for this feature is: [#37339] [#37339]: https://github.com/rust-lang/rust/issues/37339 -Documentation to be appended to section 3.6 of the book: Loops (after "Loop Labels", or before if -the "Break" section is moved). If this is deemed too complex a feature this early in the book, it -could also be moved to a new section (please advise). This would allow examples breaking with -non-primitive types, references, and discussion of coercion (probably unnecessary however). +Documentation to be appended to section G of the book. ------------------------ ### Loops as expressions -Like everything else in Rust, loops are expressions; for example, the following is perfectly legal, +Like most things in Rust, loops are expressions; for example, the following is perfectly legal, if rather useless: ```rust From b1858447d36943f96fd4fb940e878b9db7bf3d22 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Tue, 9 May 2017 12:54:43 -0400 Subject: [PATCH 007/103] fix confusion about parts required for float formatting The documentation for flt2dec doesn't match up with the actual implementation, so fix the documentation to align with reality. Presumably due to the mismatch, the formatting code for floats in std::fmt can use correspondingly shorter arrays in some places, so fix those places up as well. Fixes #41304. --- src/libcore/fmt/float.rs | 8 ++++---- src/libcore/num/flt2dec/mod.rs | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index 87def375b20..4825c2aa132 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -21,7 +21,7 @@ fn float_to_decimal_common_exact(fmt: &mut Formatter, num: &T, { unsafe { let mut buf: [u8; 1024] = mem::uninitialized(); // enough for f32 and f64 - let mut parts: [flt2dec::Part; 5] = mem::uninitialized(); + let mut parts: [flt2dec::Part; 4] = mem::uninitialized(); let formatted = flt2dec::to_exact_fixed_str(flt2dec::strategy::grisu::format_exact, *num, sign, precision, false, &mut buf, &mut parts); @@ -39,7 +39,7 @@ fn float_to_decimal_common_shortest(fmt: &mut Formatter, unsafe { // enough for f32 and f64 let mut buf: [u8; flt2dec::MAX_SIG_DIGITS] = mem::uninitialized(); - let mut parts: [flt2dec::Part; 5] = mem::uninitialized(); + let mut parts: [flt2dec::Part; 4] = mem::uninitialized(); let formatted = flt2dec::to_shortest_str(flt2dec::strategy::grisu::format_shortest, *num, sign, 0, false, &mut buf, &mut parts); fmt.pad_formatted_parts(&formatted) @@ -75,7 +75,7 @@ fn float_to_exponential_common_exact(fmt: &mut Formatter, num: &T, { unsafe { let mut buf: [u8; 1024] = mem::uninitialized(); // enough for f32 and f64 - let mut parts: [flt2dec::Part; 7] = mem::uninitialized(); + let mut parts: [flt2dec::Part; 6] = mem::uninitialized(); let formatted = flt2dec::to_exact_exp_str(flt2dec::strategy::grisu::format_exact, *num, sign, precision, upper, &mut buf, &mut parts); @@ -94,7 +94,7 @@ fn float_to_exponential_common_shortest(fmt: &mut Formatter, unsafe { // enough for f32 and f64 let mut buf: [u8; flt2dec::MAX_SIG_DIGITS] = mem::uninitialized(); - let mut parts: [flt2dec::Part; 7] = mem::uninitialized(); + let mut parts: [flt2dec::Part; 6] = mem::uninitialized(); let formatted = flt2dec::to_shortest_exp_str(flt2dec::strategy::grisu::format_shortest, *num, sign, (0, 0), upper, &mut buf, &mut parts); diff --git a/src/libcore/num/flt2dec/mod.rs b/src/libcore/num/flt2dec/mod.rs index 5123e42df61..74b9e7bf37d 100644 --- a/src/libcore/num/flt2dec/mod.rs +++ b/src/libcore/num/flt2dec/mod.rs @@ -410,8 +410,8 @@ fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static /// it will only print given digits and nothing else. /// /// The byte buffer should be at least `MAX_SIG_DIGITS` bytes long. -/// There should be at least 5 parts available, due to the worst case like -/// `[+][0.][0000][45][0000]` with `frac_digits = 10`. +/// There should be at least 4 parts available, due to the worst case like +/// `[+][0.][0000][2][0000]` with `frac_digits = 10`. pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T, sign: Sign, frac_digits: usize, _upper: bool, buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a> @@ -465,8 +465,8 @@ pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T, /// cannot be in this range, avoiding any confusion. /// /// The byte buffer should be at least `MAX_SIG_DIGITS` bytes long. -/// There should be at least 7 parts available, due to the worst case like -/// `[+][1][.][2345][e][-][67]`. +/// There should be at least 6 parts available, due to the worst case like +/// `[+][1][.][2345][e][-][6]`. pub fn to_shortest_exp_str<'a, T, F>(mut format_shortest: F, v: T, sign: Sign, dec_bounds: (i16, i16), upper: bool, buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a> @@ -544,8 +544,8 @@ fn estimate_max_buf_len(exp: i16) -> usize { /// The byte buffer should be at least `ndigits` bytes long unless `ndigits` is /// so large that only the fixed number of digits will be ever written. /// (The tipping point for `f64` is about 800, so 1000 bytes should be enough.) -/// There should be at least 7 parts available, due to the worst case like -/// `[+][1][.][2345][e][-][67]`. +/// There should be at least 6 parts available, due to the worst case like +/// `[+][1][.][2345][e][-][6]`. pub fn to_exact_exp_str<'a, T, F>(mut format_exact: F, v: T, sign: Sign, ndigits: usize, upper: bool, buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a> @@ -600,8 +600,8 @@ pub fn to_exact_exp_str<'a, T, F>(mut format_exact: F, v: T, /// The byte buffer should be enough for the output unless `frac_digits` is /// so large that only the fixed number of digits will be ever written. /// (The tipping point for `f64` is about 800, and 1000 bytes should be enough.) -/// There should be at least 5 parts available, due to the worst case like -/// `[+][0.][0000][45][0000]` with `frac_digits = 10`. +/// There should be at least 4 parts available, due to the worst case like +/// `[+][0.][0000][2][0000]` with `frac_digits = 10`. pub fn to_exact_fixed_str<'a, T, F>(mut format_exact: F, v: T, sign: Sign, frac_digits: usize, _upper: bool, buf: &'a mut [u8], parts: &'a mut [Part<'a>]) -> Formatted<'a> From 7488ff5c44f8e7515aa68e43011784de0893a6a6 Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Tue, 9 May 2017 19:34:00 +0100 Subject: [PATCH 008/103] loop_break_value book doc: remove some curiosities, regarding leodasvacas's comments --- .../src/language-features/loop-break-value.md | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/loop-break-value.md b/src/doc/unstable-book/src/language-features/loop-break-value.md index dae04d737b7..7218cad1c22 100644 --- a/src/doc/unstable-book/src/language-features/loop-break-value.md +++ b/src/doc/unstable-book/src/language-features/loop-break-value.md @@ -10,19 +10,9 @@ Documentation to be appended to section G of the book. ### Loops as expressions -Like most things in Rust, loops are expressions; for example, the following is perfectly legal, -if rather useless: - -```rust -let result = for n in 1..4 { - println!("Hello, {}", n); -}; -assert_eq!(result, ()); -``` - -Until now, all the loops you have seen evaluate to either `()` or `!`, the latter being special -syntax for "no value", meaning the loop never exits. A `loop` can instead evaluate to -a useful value via *break with value*: +Like most things in Rust, loops are expressions, and have a value; normally `()` unless the loop +never exits. +A `loop` can instead evaluate to a useful value via *break with value*: ```rust // Find the first square number over 1000: From 5135cc854156ae149f6ad50a3b5bc36c7519e3e6 Mon Sep 17 00:00:00 2001 From: David LeGare Date: Tue, 9 May 2017 21:20:56 -0500 Subject: [PATCH 009/103] Fix tidy errors --- src/libstd/sys/windows/ext/fs.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs index c4ec75d32e4..8b227573f98 100644 --- a/src/libstd/sys/windows/ext/fs.rs +++ b/src/libstd/sys/windows/ext/fs.rs @@ -241,7 +241,8 @@ pub trait OpenOptionsExt { /// /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx /// [`CreateFile2`]: https://msdn.microsoft.com/en-us/library/windows/desktop/hh449422.aspx - /// [Impersonation Levels]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa379572.aspx + /// [Impersonation Levels]: + /// https://msdn.microsoft.com/en-us/library/windows/desktop/aa379572.aspx #[stable(feature = "open_options_ext", since = "1.10.0")] fn security_qos_flags(&mut self, flags: u32) -> &mut OpenOptions; } @@ -276,7 +277,8 @@ impl OpenOptionsExt for OpenOptions { /// of the [`BY_HANDLE_FILE_INFORMATION`] structure. /// /// [`fs::Metadata`]: ../../../fs/struct.Metadata.html -/// [`BY_HANDLE_FILE_INFORMATION`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363788.aspx +/// [`BY_HANDLE_FILE_INFORMATION`]: +/// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363788.aspx #[stable(feature = "metadata_ext", since = "1.1.0")] pub trait MetadataExt { /// Returns the value of the `dwFileAttributes` field of this metadata. @@ -299,7 +301,8 @@ pub trait MetadataExt { /// # } /// ``` /// - /// [File Attribute Constants]: https://msdn.microsoft.com/en-us/library/windows/desktop/gg258117.aspx + /// [File Attribute Constants]: + /// https://msdn.microsoft.com/en-us/library/windows/desktop/gg258117.aspx #[stable(feature = "metadata_ext", since = "1.1.0")] fn file_attributes(&self) -> u32; From c2c0641444bac053188ff792eaa21c6ce8b2a690 Mon Sep 17 00:00:00 2001 From: Clar Charr Date: Fri, 5 May 2017 14:42:39 -0400 Subject: [PATCH 010/103] Add Vec::resize_default. --- src/doc/unstable-book/src/SUMMARY.md | 1 + .../library-features/vec-resize-default.md | 7 + src/libcollections/vec.rs | 132 +++++++++++++----- 3 files changed, 105 insertions(+), 35 deletions(-) create mode 100644 src/doc/unstable-book/src/library-features/vec-resize-default.md diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md index 3d9e7c7fd86..b978ce6b22b 100644 --- a/src/doc/unstable-book/src/SUMMARY.md +++ b/src/doc/unstable-book/src/SUMMARY.md @@ -217,6 +217,7 @@ - [unique](library-features/unique.md) - [unsize](library-features/unsize.md) - [utf8_error_error_len](library-features/utf8-error-error-len.md) + - [vec_resize_default](library-features/vec-resize-default.md) - [vec_remove_item](library-features/vec-remove-item.md) - [windows_c](library-features/windows-c.md) - [windows_handle](library-features/windows-handle.md) diff --git a/src/doc/unstable-book/src/library-features/vec-resize-default.md b/src/doc/unstable-book/src/library-features/vec-resize-default.md new file mode 100644 index 00000000000..5803d3215a5 --- /dev/null +++ b/src/doc/unstable-book/src/library-features/vec-resize-default.md @@ -0,0 +1,7 @@ +# `vec_resize_default` + +The tracking issue for this feature is: [#41758] + +[#41758]: https://github.com/rust-lang/rust/issues/41758 + +------------------------ diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 7ec5c29de6b..1cf713290d8 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1220,11 +1220,14 @@ impl Vec { } impl Vec { - /// Resizes the `Vec` in-place so that `len()` is equal to `new_len`. + /// Resizes the `Vec` in-place so that `len` is equal to `new_len`. /// - /// If `new_len` is greater than `len()`, the `Vec` is extended by the + /// If `new_len` is greater than `len`, the `Vec` is extended by the /// difference, with each additional slot filled with `value`. - /// If `new_len` is less than `len()`, the `Vec` is simply truncated. + /// If `new_len` is less than `len`, the `Vec` is simply truncated. + /// + /// This method requires `Clone` to clone the passed value. If you'd + /// rather create a value with `Default` instead, see [`resize_default`]. /// /// # Examples /// @@ -1237,46 +1240,19 @@ impl Vec { /// vec.resize(2, 0); /// assert_eq!(vec, [1, 2]); /// ``` + /// + /// [`resize_default`]: #method.resize_default #[stable(feature = "vec_resize", since = "1.5.0")] pub fn resize(&mut self, new_len: usize, value: T) { let len = self.len(); if new_len > len { - self.extend_with_element(new_len - len, value); + self.extend_with(new_len - len, ExtendElement(value)) } else { self.truncate(new_len); } } - /// Extend the vector by `n` additional clones of `value`. - fn extend_with_element(&mut self, n: usize, value: T) { - self.reserve(n); - - unsafe { - let mut ptr = self.as_mut_ptr().offset(self.len() as isize); - // Use SetLenOnDrop to work around bug where compiler - // may not realize the store through `ptr` through self.set_len() - // don't alias. - let mut local_len = SetLenOnDrop::new(&mut self.len); - - // Write all elements except the last one - for _ in 1..n { - ptr::write(ptr, value.clone()); - ptr = ptr.offset(1); - // Increment the length in every step in case clone() panics - local_len.increment_len(1); - } - - if n > 0 { - // We can write the last element directly without cloning needlessly - ptr::write(ptr, value); - local_len.increment_len(1); - } - - // len set by scope guard - } - } - /// Clones and appends all elements in a slice to the `Vec`. /// /// Iterates over the slice `other`, clones each element, and then appends @@ -1300,6 +1276,92 @@ impl Vec { } } +impl Vec { + /// Resizes the `Vec` in-place so that `len` is equal to `new_len`. + /// + /// If `new_len` is greater than `len`, the `Vec` is extended by the + /// difference, with each additional slot filled with `Default::default()`. + /// If `new_len` is less than `len`, the `Vec` is simply truncated. + /// + /// This method uses `Default` to create new values on every push. If + /// you'd rather `Clone` a given value, use [`resize`]. + /// + /// + /// # Examples + /// + /// ``` + /// #![feature(vec_resize_default)] + /// + /// let mut vec = vec![1, 2, 3]; + /// vec.resize_default(5); + /// assert_eq!(vec, [1, 2, 3, 0, 0]); + /// + /// let mut vec = vec![1, 2, 3, 4]; + /// vec.resize_default(2); + /// assert_eq!(vec, [1, 2]); + /// ``` + /// + /// [`resize`]: #method.resize + #[unstable(feature = "vec_resize_default", issue = "41758")] + pub fn resize_default(&mut self, new_len: usize) { + let len = self.len(); + + if new_len > len { + self.extend_with(new_len - len, ExtendDefault); + } else { + self.truncate(new_len); + } + } +} + +// This code generalises `extend_with_{element,default}`. +trait ExtendWith { + fn next(&self) -> T; + fn last(self) -> T; +} + +struct ExtendElement(T); +impl ExtendWith for ExtendElement { + fn next(&self) -> T { self.0.clone() } + fn last(self) -> T { self.0 } +} + +struct ExtendDefault; +impl ExtendWith for ExtendDefault { + fn next(&self) -> T { Default::default() } + fn last(self) -> T { Default::default() } +} +impl Vec { + /// Extend the vector by `n` values, using the given generator. + fn extend_with>(&mut self, n: usize, value: E) { + self.reserve(n); + + unsafe { + let mut ptr = self.as_mut_ptr().offset(self.len() as isize); + // Use SetLenOnDrop to work around bug where compiler + // may not realize the store through `ptr` through self.set_len() + // don't alias. + let mut local_len = SetLenOnDrop::new(&mut self.len); + + // Write all elements except the last one + for _ in 1..n { + ptr::write(ptr, value.next()); + ptr = ptr.offset(1); + // Increment the length in every step in case next() panics + local_len.increment_len(1); + } + + if n > 0 { + // We can write the last element directly without cloning needlessly + ptr::write(ptr, value.last()); + local_len.increment_len(1); + } + + // len set by scope guard + } + } +} + // Set the length of the vec when the `SetLenOnDrop` value goes out of scope. // // The idea is: The length field in SetLenOnDrop is a local variable @@ -1389,7 +1451,7 @@ trait SpecFromElem: Sized { impl SpecFromElem for T { default fn from_elem(elem: Self, n: usize) -> Vec { let mut v = Vec::with_capacity(n); - v.extend_with_element(n, elem); + v.extend_with(n, ExtendElement(elem)); v } } @@ -1424,7 +1486,7 @@ macro_rules! impl_spec_from_elem { } } let mut v = Vec::with_capacity(n); - v.extend_with_element(n, elem); + v.extend_with(n, ExtendElement(elem)); v } } From e6cde9f2a4f5e4d9e20686f29344461eacae3eba Mon Sep 17 00:00:00 2001 From: Mike Lubinets Date: Thu, 11 May 2017 16:48:25 +0300 Subject: [PATCH 011/103] Number of filtered out tests in tests summary Closes #31905 --- src/libtest/lib.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 0d615db3deb..ef048ac8ca3 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -542,6 +542,7 @@ struct ConsoleTestState { passed: usize, failed: usize, ignored: usize, + filtered_out: usize, measured: usize, metrics: MetricMap, failures: Vec<(TestDesc, Vec)>, @@ -570,6 +571,7 @@ impl ConsoleTestState { passed: 0, failed: 0, ignored: 0, + filtered_out: 0, measured: 0, metrics: MetricMap::new(), failures: Vec::new(), @@ -775,11 +777,12 @@ impl ConsoleTestState { } else { self.write_pretty("FAILED", term::color::RED)?; } - let s = format!(". {} passed; {} failed; {} ignored; {} measured\n\n", + let s = format!(". {} passed; {} failed; {} ignored; {} measured; {} filtered out\n\n", self.passed, self.failed, self.ignored, - self.measured); + self.measured, + self.filtered_out); self.write_plain(&s)?; return Ok(success); } @@ -875,6 +878,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec) -> io::Resu fn callback(event: &TestEvent, st: &mut ConsoleTestState) -> io::Result<()> { match (*event).clone() { TeFiltered(ref filtered_tests) => st.write_run_start(filtered_tests.len()), + TeFilteredOut(filtered_out) => Ok(st.filtered_out = filtered_out), TeWait(ref test, padding) => st.write_test_start(test, padding), TeTimeout(ref test) => st.write_timeout(test), TeResult(test, result, stdout) => { @@ -957,6 +961,7 @@ fn should_sort_failures_before_printing_them() { passed: 0, failed: 0, ignored: 0, + filtered_out: 0, measured: 0, max_name_len: 10, metrics: MetricMap::new(), @@ -1017,6 +1022,7 @@ pub enum TestEvent { TeWait(TestDesc, NamePadding), TeResult(TestDesc, TestResult, Vec), TeTimeout(TestDesc), + TeFilteredOut(usize), } pub type MonitorMsg = (TestDesc, TestResult, Vec); @@ -1028,11 +1034,16 @@ pub fn run_tests(opts: &TestOpts, tests: Vec, mut callback: F) use std::collections::HashMap; use std::sync::mpsc::RecvTimeoutError; + let tests_len = tests.len(); + let mut filtered_tests = filter_tests(opts, tests); if !opts.bench_benchmarks { filtered_tests = convert_benchmarks_to_tests(filtered_tests); } + let filtered_out = tests_len - filtered_tests.len(); + callback(TeFilteredOut(filtered_out))?; + let filtered_descs = filtered_tests.iter() .map(|t| t.desc.clone()) .collect(); From a9c163ebe9deeaf74699fc8642d919cdb2b5e617 Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Fri, 12 May 2017 20:05:39 +0200 Subject: [PATCH 012/103] Fix some clippy warnings in libsyntax This is mostly removing stray ampersands, needless returns and lifetimes. --- src/libsyntax/ast.rs | 18 +- src/libsyntax/attr.rs | 17 +- src/libsyntax/codemap.rs | 4 +- src/libsyntax/config.rs | 8 +- src/libsyntax/diagnostics/plugin.rs | 6 +- src/libsyntax/ext/base.rs | 10 +- src/libsyntax/ext/expand.rs | 26 +-- src/libsyntax/ext/quote.rs | 4 +- src/libsyntax/ext/source_util.rs | 4 +- src/libsyntax/ext/tt/macro_parser.rs | 49 ++--- src/libsyntax/ext/tt/macro_rules.rs | 45 ++-- src/libsyntax/ext/tt/quoted.rs | 19 +- src/libsyntax/ext/tt/transcribe.rs | 6 +- src/libsyntax/feature_gate.rs | 47 ++-- src/libsyntax/json.rs | 2 +- src/libsyntax/parse/attr.rs | 4 +- src/libsyntax/parse/classify.rs | 4 +- src/libsyntax/parse/common.rs | 2 +- src/libsyntax/parse/lexer/comments.rs | 2 +- src/libsyntax/parse/lexer/mod.rs | 122 +++++------ src/libsyntax/parse/mod.rs | 146 ++++++------- src/libsyntax/parse/obsolete.rs | 2 +- src/libsyntax/parse/parser.rs | 73 +++---- src/libsyntax/parse/token.rs | 46 ++-- src/libsyntax/print/pp.rs | 12 +- src/libsyntax/print/pprust.rs | 297 ++++++++++++-------------- src/libsyntax/std_inject.rs | 4 +- src/libsyntax/test.rs | 19 +- src/libsyntax/tokenstream.rs | 14 +- src/libsyntax/util/lev_distance.rs | 7 +- src/libsyntax/util/move_map.rs | 8 +- src/libsyntax/visit.rs | 8 +- 32 files changed, 498 insertions(+), 537 deletions(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index e5bb02fe082..24ce99208ed 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -715,7 +715,7 @@ impl Stmt { StmtKind::Mac(mac) => StmtKind::Mac(mac.map(|(mac, _style, attrs)| { (mac, MacStmtStyle::Semicolon, attrs) })), - node @ _ => node, + node => node, }; self } @@ -1076,16 +1076,16 @@ impl LitKind { pub fn is_unsuffixed(&self) -> bool { match *self { // unsuffixed variants - LitKind::Str(..) => true, - LitKind::ByteStr(..) => true, - LitKind::Byte(..) => true, - LitKind::Char(..) => true, - LitKind::Int(_, LitIntType::Unsuffixed) => true, - LitKind::FloatUnsuffixed(..) => true, + LitKind::Str(..) | + LitKind::ByteStr(..) | + LitKind::Byte(..) | + LitKind::Char(..) | + LitKind::Int(_, LitIntType::Unsuffixed) | + LitKind::FloatUnsuffixed(..) | LitKind::Bool(..) => true, // suffixed variants - LitKind::Int(_, LitIntType::Signed(..)) => false, - LitKind::Int(_, LitIntType::Unsigned(..)) => false, + LitKind::Int(_, LitIntType::Signed(..)) | + LitKind::Int(_, LitIntType::Unsigned(..)) | LitKind::Float(..) => false, } } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 0980b73e80c..45f891d8dc5 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -112,7 +112,7 @@ impl NestedMetaItem { /// Returns the MetaItem if self is a NestedMetaItemKind::MetaItem. pub fn meta_item(&self) -> Option<&MetaItem> { match self.node { - NestedMetaItemKind::MetaItem(ref item) => Some(&item), + NestedMetaItemKind::MetaItem(ref item) => Some(item), _ => None } } @@ -120,7 +120,7 @@ impl NestedMetaItem { /// Returns the Lit if self is a NestedMetaItemKind::Literal. pub fn literal(&self) -> Option<&Lit> { match self.node { - NestedMetaItemKind::Literal(ref lit) => Some(&lit), + NestedMetaItemKind::Literal(ref lit) => Some(lit), _ => None } } @@ -259,7 +259,7 @@ impl MetaItem { match self.node { MetaItemKind::NameValue(ref v) => { match v.node { - LitKind::Str(ref s, _) => Some((*s).clone()), + LitKind::Str(ref s, _) => Some(*s), _ => None, } }, @@ -1217,9 +1217,10 @@ impl LitKind { Token::Literal(token::Lit::Float(symbol), Some(Symbol::intern(ty.ty_to_string()))) } LitKind::FloatUnsuffixed(symbol) => Token::Literal(token::Lit::Float(symbol), None), - LitKind::Bool(value) => Token::Ident(Ident::with_empty_ctxt(Symbol::intern(match value { - true => "true", - false => "false", + LitKind::Bool(value) => Token::Ident(Ident::with_empty_ctxt(Symbol::intern(if value { + "true" + } else { + "false" }))), } } @@ -1261,7 +1262,7 @@ impl HasAttrs for Spanned { impl HasAttrs for Vec { fn attrs(&self) -> &[Attribute] { - &self + self } fn map_attrs) -> Vec>(self, f: F) -> Self { f(self) @@ -1270,7 +1271,7 @@ impl HasAttrs for Vec { impl HasAttrs for ThinVec { fn attrs(&self) -> &[Attribute] { - &self + self } fn map_attrs) -> Vec>(self, f: F) -> Self { f(self.into()).into() diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 0c8be1d4f24..d32c3ec5f46 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -485,7 +485,7 @@ impl CodeMap { match self.span_to_snippet(sp) { Ok(snippet) => { let snippet = snippet.split(c).nth(0).unwrap_or("").trim_right(); - if snippet.len() > 0 && !snippet.contains('\n') { + if !snippet.is_empty() && !snippet.contains('\n') { Span { hi: BytePos(sp.lo.0 + snippet.len() as u32), ..sp } } else { sp @@ -502,7 +502,7 @@ impl CodeMap { pub fn get_filemap(&self, filename: &str) -> Option> { for fm in self.files.borrow().iter() { if filename == fm.name { - (self.dep_tracking_callback.borrow())(&fm); + (self.dep_tracking_callback.borrow())(fm); return Some(fm.clone()); } } diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index ede8a33df65..2e98c7d9626 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -123,7 +123,7 @@ impl<'a> StripUnconfigured<'a> { return false; } - let mis = if !is_cfg(&attr) { + let mis = if !is_cfg(attr) { return true; } else if let Some(mis) = attr.meta_item_list() { mis @@ -150,7 +150,7 @@ impl<'a> StripUnconfigured<'a> { // flag the offending attributes for attr in attrs.iter() { if !self.features.map(|features| features.stmt_expr_attributes).unwrap_or(true) { - let mut err = feature_err(&self.sess, + let mut err = feature_err(self.sess, "stmt_expr_attributes", attr.span, GateIssue::Language, @@ -258,7 +258,7 @@ impl<'a> StripUnconfigured<'a> { pub fn configure_struct_expr_field(&mut self, field: ast::Field) -> Option { if !self.features.map(|features| features.struct_field_attributes).unwrap_or(true) { if !field.attrs.is_empty() { - let mut err = feature_err(&self.sess, + let mut err = feature_err(self.sess, "struct_field_attributes", field.span, GateIssue::Language, @@ -290,7 +290,7 @@ impl<'a> StripUnconfigured<'a> { for attr in attrs.iter() { if !self.features.map(|features| features.struct_field_attributes).unwrap_or(true) { let mut err = feature_err( - &self.sess, + self.sess, "struct_field_attributes", attr.span, GateIssue::Language, diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index fe5cb87ad59..ca89a80fdee 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -111,7 +111,7 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt, // overflow the maximum line width. description.map(|raw_msg| { let msg = raw_msg.as_str(); - if !msg.starts_with("\n") || !msg.ends_with("\n") { + if !msg.starts_with('\n') || !msg.ends_with('\n') { ecx.span_err(span, &format!( "description for error code {} doesn't start and end with a newline", code @@ -177,7 +177,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, if let Err(e) = output_metadata(ecx, &target_triple, &crate_name.name.as_str(), - &diagnostics) { + diagnostics) { ecx.span_bug(span, &format!( "error writing metadata for triple `{}` and crate `{}`, error: {}, \ cause: {:?}", @@ -227,7 +227,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, MacEager::items(SmallVector::many(vec![ P(ast::Item { - ident: name.clone(), + ident: *name, attrs: Vec::new(), id: ast::DUMMY_NODE_ID, node: ast::ItemKind::Const( diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index f731c5abdd6..f78089aaa75 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -636,7 +636,7 @@ pub struct ExpansionData { /// One of these is made during expansion and incrementally updated as we go; /// when a macro expansion occurs, the resulting nodes have the backtrace() -/// -> expn_info of their expansion context stored into their span. +/// -> `expn_info` of their expansion context stored into their span. pub struct ExtCtxt<'a> { pub parse_sess: &'a parse::ParseSess, pub ecfg: expand::ExpansionConfig<'a>, @@ -709,7 +709,7 @@ impl<'a> ExtCtxt<'a> { } ctxt = info.call_site.ctxt; last_macro = Some(info.call_site); - return Some(()); + Some(()) }).is_none() { break } @@ -770,9 +770,9 @@ impl<'a> ExtCtxt<'a> { } pub fn trace_macros_diag(&self) { for (sp, notes) in self.expansions.iter() { - let mut db = self.parse_sess.span_diagnostic.span_note_diag(*sp, &"trace_macro"); + let mut db = self.parse_sess.span_diagnostic.span_note_diag(*sp, "trace_macro"); for note in notes { - db.note(¬e); + db.note(note); } db.emit(); } @@ -795,7 +795,7 @@ impl<'a> ExtCtxt<'a> { v.push(self.ident_of(s)); } v.extend(components.iter().map(|s| self.ident_of(s))); - return v + v } pub fn name_of(&self, st: &str) -> ast::Name { Symbol::intern(st) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index a8aa103f80a..a5633679539 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -415,19 +415,19 @@ impl<'a, 'b> MacroExpander<'a, 'b> { match *ext { MultiModifier(ref mac) => { - let meta = panictry!(attr.parse_meta(&self.cx.parse_sess)); + let meta = panictry!(attr.parse_meta(self.cx.parse_sess)); let item = mac.expand(self.cx, attr.span, &meta, item); kind.expect_from_annotatables(item) } MultiDecorator(ref mac) => { let mut items = Vec::new(); - let meta = panictry!(attr.parse_meta(&self.cx.parse_sess)); + let meta = panictry!(attr.parse_meta(self.cx.parse_sess)); mac.expand(self.cx, attr.span, &meta, &item, &mut |item| items.push(item)); items.push(item); kind.expect_from_annotatables(items) } SyntaxExtension::AttrProcMacro(ref mac) => { - let item_toks = stream_for_item(&item, &self.cx.parse_sess); + let item_toks = stream_for_item(&item, self.cx.parse_sess); let span = Span { ctxt: self.cx.backtrace(), ..attr.span }; let tok_result = mac.expand(self.cx, attr.span, attr.tokens, item_toks); @@ -439,7 +439,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } _ => { let msg = &format!("macro `{}` may not be used in attributes", attr.path); - self.cx.span_err(attr.span, &msg); + self.cx.span_err(attr.span, msg); kind.dummy(attr.span) } } @@ -454,7 +454,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }; let path = &mac.node.path; - let ident = ident.unwrap_or(keywords::Invalid.ident()); + let ident = ident.unwrap_or_else(|| keywords::Invalid.ident()); let marked_tts = noop_fold_tts(mac.node.stream(), &mut Marker(mark)); let opt_expanded = match *ext { NormalTT(ref expandfun, exp_span, allow_internal_unstable) => { @@ -591,7 +591,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } _ => { let msg = &format!("macro `{}` may not be used for derive attributes", attr.path); - self.cx.span_err(span, &msg); + self.cx.span_err(span, msg); kind.dummy(span) } } @@ -749,19 +749,15 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { fn check_attributes(&mut self, attrs: &[ast::Attribute]) { let features = self.cx.ecfg.features.unwrap(); for attr in attrs.iter() { - feature_gate::check_attribute(&attr, &self.cx.parse_sess, features); + feature_gate::check_attribute(attr, self.cx.parse_sess, features); } } } pub fn find_attr_invoc(attrs: &mut Vec) -> Option { - for i in 0 .. attrs.len() { - if !attr::is_known(&attrs[i]) && !is_builtin_attr(&attrs[i]) { - return Some(attrs.remove(i)); - } - } - - None + attrs.iter() + .position(|a| !attr::is_known(a) && !is_builtin_attr(a)) + .map(|i| attrs.remove(i)) } // These are pretty nasty. Ideally, we would keep the tokens around, linked from @@ -923,7 +919,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> { let result = noop_fold_item(item, self); self.cx.current_expansion.module = orig_module; self.cx.current_expansion.directory_ownership = orig_directory_ownership; - return result; + result } // Ensure that test functions are accessible from the test harness. ast::ItemKind::Fn(..) if self.cx.ecfg.should_test => { diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index d7a85baa3ff..85ae65e6b79 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -23,7 +23,7 @@ use tokenstream::{TokenStream, TokenTree}; /// /// This is registered as a set of expression syntax extension called quote! /// that lifts its argument token-tree to an AST representing the -/// construction of the same token tree, with token::SubstNt interpreted +/// construction of the same token tree, with `token::SubstNt` interpreted /// as antiquotes (splices). pub mod rt { @@ -389,7 +389,7 @@ pub fn unflatten(tts: Vec) -> Vec { result = results.pop().unwrap(); result.push(tree); } - tree @ _ => result.push(tree), + tree => result.push(tree), } } result diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 22a5776315a..4183583d66f 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -150,7 +150,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenT cx.span_err(sp, &format!("{} wasn't a utf-8 file", file.display())); - return DummyResult::expr(sp); + DummyResult::expr(sp) } } } @@ -167,7 +167,7 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::Toke Err(e) => { cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e)); - return DummyResult::expr(sp); + DummyResult::expr(sp) } Ok(..) => { // Add this input file to the code map to make it available as diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index eb0b7c29f8d..8e28135b11d 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -39,40 +39,40 @@ //! Example: Start parsing `a a a a b` against [· a $( a )* a b]. //! //! Remaining input: `a a a a b` -//! next_eis: [· a $( a )* a b] +//! `next_eis`: `[· a $( a )* a b]` //! //! - - - Advance over an `a`. - - - //! //! Remaining input: `a a a b` -//! cur: [a · $( a )* a b] +//! cur: `[a · $( a )* a b]` //! Descend/Skip (first item). -//! next: [a $( · a )* a b] [a $( a )* · a b]. +//! next: `[a $( · a )* a b] [a $( a )* · a b]`. //! //! - - - Advance over an `a`. - - - //! //! Remaining input: `a a b` -//! cur: [a $( a · )* a b] next: [a $( a )* a · b] +//! cur: `[a $( a · )* a b]` next: `[a $( a )* a · b]` //! Finish/Repeat (first item) -//! next: [a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b] +//! next: `[a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b]` //! //! - - - Advance over an `a`. - - - (this looks exactly like the last step) //! //! Remaining input: `a b` -//! cur: [a $( a · )* a b] next: [a $( a )* a · b] +//! cur: `[a $( a · )* a b]` next: `[a $( a )* a · b]` //! Finish/Repeat (first item) -//! next: [a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b] +//! next: `[a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b]` //! //! - - - Advance over an `a`. - - - (this looks exactly like the last step) //! //! Remaining input: `b` -//! cur: [a $( a · )* a b] next: [a $( a )* a · b] +//! cur: `[a $( a · )* a b]` next: `[a $( a )* a · b]` //! Finish/Repeat (first item) -//! next: [a $( a )* · a b] [a $( · a )* a b] +//! next: `[a $( a )* · a b] [a $( · a )* a b]` //! //! - - - Advance over a `b`. - - - //! //! Remaining input: `` -//! eof: [a $( a )* a b ·] +//! eof: `[a $( a )* a b ·]` pub use self::NamedMatch::*; pub use self::ParseResult::*; @@ -178,20 +178,20 @@ fn initial_matcher_pos(ms: Vec, lo: BytePos) -> Box { }) } -/// NamedMatch is a pattern-match result for a single token::MATCH_NONTERMINAL: +/// `NamedMatch` is a pattern-match result for a single `token::MATCH_NONTERMINAL`: /// so it is associated with a single ident in a parse, and all -/// `MatchedNonterminal`s in the NamedMatch have the same nonterminal type -/// (expr, item, etc). Each leaf in a single NamedMatch corresponds to a -/// single token::MATCH_NONTERMINAL in the TokenTree that produced it. +/// `MatchedNonterminal`s in the `NamedMatch` have the same nonterminal type +/// (expr, item, etc). Each leaf in a single `NamedMatch` corresponds to a +/// single `token::MATCH_NONTERMINAL` in the `TokenTree` that produced it. /// -/// The in-memory structure of a particular NamedMatch represents the match +/// The in-memory structure of a particular `NamedMatch` represents the match /// that occurred when a particular subset of a matcher was applied to a /// particular token tree. /// -/// The width of each MatchedSeq in the NamedMatch, and the identity of the -/// `MatchedNonterminal`s, will depend on the token tree it was applied to: -/// each MatchedSeq corresponds to a single TTSeq in the originating -/// token tree. The depth of the NamedMatch structure will therefore depend +/// The width of each `MatchedSeq` in the `NamedMatch`, and the identity of +/// the `MatchedNonterminal`s, will depend on the token tree it was applied +/// to: each `MatchedSeq` corresponds to a single `TTSeq` in the originating +/// token tree. The depth of the `NamedMatch` structure will therefore depend /// only on the nesting depth of `ast::TTSeq`s in the originating /// token tree it was derived from. @@ -334,7 +334,7 @@ fn inner_parse_loop(sess: &ParseSess, // Check if we need a separator if idx == len && ei.sep.is_some() { // We have a separator, and it is the current token. - if ei.sep.as_ref().map(|ref sep| token_name_eq(&token, sep)).unwrap_or(false) { + if ei.sep.as_ref().map(|sep| token_name_eq(token, sep)).unwrap_or(false) { ei.idx += 1; next_eis.push(ei); } @@ -401,7 +401,7 @@ fn inner_parse_loop(sess: &ParseSess, cur_eis.push(ei); } TokenTree::Token(_, ref t) => { - if token_name_eq(t, &token) { + if token_name_eq(t, token) { ei.idx += 1; next_eis.push(ei); } @@ -485,11 +485,8 @@ pub fn parse(sess: &ParseSess, tts: TokenStream, ms: &[TokenTree], directory: Op } fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal { - match name { - "tt" => { - return token::NtTT(p.parse_token_tree()); - } - _ => {} + if let "tt" = name { + return token::NtTT(p.parse_token_tree()); } // check at the beginning and the parser checks after each bump p.process_potential_macro_variable(); diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index f959ccc989e..9e3fe30e7bf 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -94,7 +94,7 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt, -> Box { if cx.trace_macros() { let sp = sp.macro_backtrace().last().map(|trace| trace.call_site).unwrap_or(sp); - let mut values: &mut Vec = cx.expansions.entry(sp).or_insert(vec![]); + let mut values: &mut Vec = cx.expansions.entry(sp).or_insert_with(Vec::new); values.push(format!("expands to `{}! {{ {} }}`", name, arg)); } @@ -206,7 +206,7 @@ pub fn compile(sess: &ParseSess, features: &RefCell, def: &ast::Item) let mut valid = true; // Extract the arguments: - let lhses = match **argument_map.get(&lhs_nm).unwrap() { + let lhses = match *argument_map[&lhs_nm] { MatchedSeq(ref s, _) => { s.iter().map(|m| { if let MatchedNonterminal(ref nt) = **m { @@ -222,7 +222,7 @@ pub fn compile(sess: &ParseSess, features: &RefCell, def: &ast::Item) _ => sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs") }; - let rhses = match **argument_map.get(&rhs_nm).unwrap() { + let rhses = match *argument_map[&rhs_nm] { MatchedSeq(ref s, _) => { s.iter().map(|m| { if let MatchedNonterminal(ref nt) = **m { @@ -260,13 +260,12 @@ fn check_lhs_nt_follows(sess: &ParseSess, lhs: "ed::TokenTree) -> bool { // lhs is going to be like TokenTree::Delimited(...), where the // entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens. - match lhs { - "ed::TokenTree::Delimited(_, ref tts) => check_matcher(sess, features, &tts.tts), - _ => { - let msg = "invalid macro matcher; matchers must be contained in balanced delimiters"; - sess.span_diagnostic.span_err(lhs.span(), msg); - false - } + if let quoted::TokenTree::Delimited(_, ref tts) = *lhs { + check_matcher(sess, features, &tts.tts) + } else { + let msg = "invalid macro matcher; matchers must be contained in balanced delimiters"; + sess.span_diagnostic.span_err(lhs.span(), msg); + false } // we don't abort on errors on rejection, the driver will do that for us // after parsing/expansion. we can report every error in every macro this way. @@ -283,17 +282,15 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[quoted::TokenTree]) -> bool { return false; }, TokenTree::Sequence(span, ref seq) => { - if seq.separator.is_none() { - if seq.tts.iter().all(|seq_tt| { - match *seq_tt { - TokenTree::Sequence(_, ref sub_seq) => - sub_seq.op == quoted::KleeneOp::ZeroOrMore, - _ => false, - } - }) { - sess.span_diagnostic.span_err(span, "repetition matches empty token tree"); - return false; + if seq.separator.is_none() && seq.tts.iter().all(|seq_tt| { + match *seq_tt { + TokenTree::Sequence(_, ref sub_seq) => + sub_seq.op == quoted::KleeneOp::ZeroOrMore, + _ => false, } + }) { + sess.span_diagnostic.span_err(span, "repetition matches empty token tree"); + return false; } if !check_lhs_no_empty_seq(sess, &seq.tts) { return false; @@ -407,7 +404,7 @@ impl FirstSets { } } - return first; + first } } @@ -469,7 +466,7 @@ impl FirstSets { // we only exit the loop if `tts` was empty or if every // element of `tts` matches the empty sequence. assert!(first.maybe_empty); - return first; + first } } @@ -579,7 +576,7 @@ fn check_matcher_core(sess: &ParseSess, let build_suffix_first = || { let mut s = first_sets.first(suffix); if s.maybe_empty { s.add_all(follow); } - return s; + s }; // (we build `suffix_first` on demand below; you can tell @@ -861,6 +858,6 @@ fn quoted_tt_to_string(tt: "ed::TokenTree) -> String { match *tt { quoted::TokenTree::Token(_, ref tok) => ::print::pprust::token_to_string(tok), quoted::TokenTree::MetaVarDecl(_, name, kind) => format!("${}:{}", name, kind), - _ => panic!("unexpected quoted::TokenTree::{Sequence or Delimited} in follow set checker"), + _ => panic!("unexpected quoted::TokenTree::{{Sequence or Delimited}} in follow set checker"), } } diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs index d216effbd45..fa65e9501c2 100644 --- a/src/libsyntax/ext/tt/quoted.rs +++ b/src/libsyntax/ext/tt/quoted.rs @@ -96,6 +96,17 @@ impl TokenTree { } } + pub fn is_empty(&self) -> bool { + match *self { + TokenTree::Delimited(_, ref delimed) => match delimed.delim { + token::NoDelim => delimed.tts.is_empty(), + _ => false, + }, + TokenTree::Sequence(_, ref seq) => seq.tts.is_empty(), + _ => true, + } + } + pub fn get_tt(&self, index: usize) -> TokenTree { match (self, index) { (&TokenTree::Delimited(_, ref delimed), _) if delimed.delim == token::NoDelim => { @@ -144,9 +155,9 @@ pub fn parse(input: tokenstream::TokenStream, expect_matchers: bool, sess: &Pars } _ => end_sp, }, - tree @ _ => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(span), + tree => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(span), }, - tree @ _ => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(start_sp), + tree => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(start_sp), }; sess.missing_fragment_specifiers.borrow_mut().insert(span); result.push(TokenTree::MetaVarDecl(span, ident, keywords::Invalid.ident())); @@ -228,10 +239,10 @@ fn parse_sep_and_kleene_op(input: &mut I, span: Span, sess: &ParseSess) Some(op) => return (Some(tok), op), None => span, }, - tree @ _ => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(span), + tree => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(span), } }, - tree @ _ => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(span), + tree => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(span), }; sess.span_diagnostic.span_err(span, "expected `*` or `+`"); diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 947089b0b9a..2a435bdea10 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -121,20 +121,20 @@ pub fn transcribe(sp_diag: &Handler, &repeats) { LockstepIterSize::Unconstrained => { panic!(sp_diag.span_fatal( - sp.clone(), /* blame macro writer */ + sp, /* blame macro writer */ "attempted to repeat an expression \ containing no syntax \ variables matched as repeating at this depth")); } LockstepIterSize::Contradiction(ref msg) => { // FIXME #2887 blame macro invoker instead - panic!(sp_diag.span_fatal(sp.clone(), &msg[..])); + panic!(sp_diag.span_fatal(sp, &msg[..])); } LockstepIterSize::Constraint(len, _) => { if len == 0 { if seq.op == quoted::KleeneOp::OneOrMore { // FIXME #2887 blame invoker - panic!(sp_diag.span_fatal(sp.clone(), + panic!(sp_diag.span_fatal(sp, "this must repeat at least once")); } } else { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index b6a2c983fd4..f95693f6820 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -472,7 +472,7 @@ pub enum Stability { impl ::std::fmt::Debug for AttributeGate { fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { match *self { - Gated(ref stab, ref name, ref expl, _) => + Gated(ref stab, name, expl, _) => write!(fmt, "Gated({:?}, {}, {})", stab, name, expl), Ungated => write!(fmt, "Ungated") } @@ -816,7 +816,7 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG ]; // cfg(...)'s that are feature gated -const GATED_CFGS: &'static [(&'static str, &'static str, fn(&Features) -> bool)] = &[ +const GATED_CFGS: &[(&str, &str, fn(&Features) -> bool)] = &[ // (name in cfg, feature, function to check if the feature is enabled) ("target_feature", "cfg_target_feature", cfg_fn!(cfg_target_feature)), ("target_vendor", "cfg_target_vendor", cfg_fn!(cfg_target_vendor)), @@ -881,7 +881,7 @@ impl<'a> Context<'a> { let name = unwrap_or!(attr.name(), return).as_str(); for &(n, ty, ref gateage) in BUILTIN_ATTRIBUTES { if name == n { - if let &Gated(_, ref name, ref desc, ref has_feature) = gateage { + if let Gated(_, name, desc, ref has_feature) = *gateage { gate_feature_fn!(self, has_feature, attr.span, name, desc); } debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage); @@ -1098,7 +1098,7 @@ fn contains_novel_literal(item: &ast::MetaItem) -> bool { NameValue(ref lit) => !lit.node.is_str(), List(ref list) => list.iter().any(|li| { match li.node { - MetaItem(ref mi) => contains_novel_literal(&mi), + MetaItem(ref mi) => contains_novel_literal(mi), Literal(_) => true, } }), @@ -1120,7 +1120,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { return } - let meta = panictry!(attr.parse_meta(&self.context.parse_sess)); + let meta = panictry!(attr.parse_meta(self.context.parse_sess)); if contains_novel_literal(&meta) { gate_feature_post!(&self, attr_literals, attr.span, "non-string literals in attributes, or string \ @@ -1216,14 +1216,11 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, _) => { - match polarity { - ast::ImplPolarity::Negative => { - gate_feature_post!(&self, optin_builtin_traits, - i.span, - "negative trait bounds are not yet fully implemented; \ - use marker types for now"); - }, - _ => {} + if let ast::ImplPolarity::Negative = polarity { + gate_feature_post!(&self, optin_builtin_traits, + i.span, + "negative trait bounds are not yet fully implemented; \ + use marker types for now"); } if let ast::Defaultness::Default = defaultness { @@ -1272,10 +1269,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FunctionRetTy) { if let ast::FunctionRetTy::Ty(ref output_ty) = *ret_ty { - match output_ty.node { - ast::TyKind::Never => return, - _ => (), - }; + if let ast::TyKind::Never = output_ty.node { + return + } self.visit_ty(output_ty) } } @@ -1373,17 +1369,14 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { span: Span, _node_id: NodeId) { // check for const fn declarations - match fn_kind { - FnKind::ItemFn(_, _, _, Spanned { node: ast::Constness::Const, .. }, _, _, _) => { - gate_feature_post!(&self, const_fn, span, "const fn is unstable"); - } - _ => { - // stability of const fn methods are covered in - // visit_trait_item and visit_impl_item below; this is - // because default methods don't pass through this - // point. - } + if let FnKind::ItemFn(_, _, _, Spanned { node: ast::Constness::Const, .. }, _, _, _) = + fn_kind { + gate_feature_post!(&self, const_fn, span, "const fn is unstable"); } + // stability of const fn methods are covered in + // visit_trait_item and visit_impl_item below; this is + // because default methods don't pass through this + // point. match fn_kind { FnKind::ItemFn(_, _, _, _, abi, _, _) | diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs index 0271ddbccbf..ccc2a2aef31 100644 --- a/src/libsyntax/json.rs +++ b/src/libsyntax/json.rs @@ -330,7 +330,7 @@ impl DiagnosticSpanLine { }) .collect() }) - .unwrap_or(vec![]) + .unwrap_or_else(|_| vec![]) } } diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index 92cec462ffb..082930777e5 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -62,7 +62,7 @@ impl<'a> Parser<'a> { _ => break, } } - return Ok(attrs); + Ok(attrs) } /// Matches `attribute = # ! [ meta_item ]` @@ -182,7 +182,7 @@ impl<'a> Parser<'a> { } let attr = self.parse_attribute(true)?; - assert!(attr.style == ast::AttrStyle::Inner); + assert_eq!(attr.style, ast::AttrStyle::Inner); attrs.push(attr); } token::DocComment(s) => { diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs index 4fe4ec7e4c0..c2755cf0591 100644 --- a/src/libsyntax/parse/classify.rs +++ b/src/libsyntax/parse/classify.rs @@ -43,14 +43,14 @@ pub fn expr_is_simple_block(e: &ast::Expr) -> bool { } /// this statement requires a semicolon after it. -/// note that in one case (stmt_semi), we've already +/// note that in one case (`stmt_semi`), we've already /// seen the semicolon, and thus don't need another. pub fn stmt_ends_with_semi(stmt: &ast::StmtKind) -> bool { match *stmt { ast::StmtKind::Local(_) => true, ast::StmtKind::Item(_) => false, ast::StmtKind::Expr(ref e) => expr_requires_semi_to_be_stmt(e), - ast::StmtKind::Semi(..) => false, + ast::StmtKind::Semi(..) | ast::StmtKind::Mac(..) => false, } } diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs index b57708f9193..fe931f7cf6a 100644 --- a/src/libsyntax/parse/common.rs +++ b/src/libsyntax/parse/common.rs @@ -12,7 +12,7 @@ use parse::token; -/// SeqSep : a sequence separator (token) +/// `SeqSep` : a sequence separator (token) /// and whether a trailing separator is allowed. pub struct SeqSep { pub sep: Option, diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs index 7ac322b144c..8b545d3b909 100644 --- a/src/libsyntax/parse/lexer/comments.rs +++ b/src/libsyntax/parse/lexer/comments.rs @@ -77,7 +77,7 @@ pub fn strip_doc_comment_decoration(comment: &str) -> String { while j > i && lines[j - 1].trim().is_empty() { j -= 1; } - lines[i..j].iter().cloned().collect() + lines[i..j].to_vec() } /// remove a "[ \t]*\*" block from each line, if possible diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index ded1f0b599a..454167695e1 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -144,7 +144,7 @@ impl<'a> StringReader<'a> { impl<'a> StringReader<'a> { /// For comments.rs, which hackily pokes into next_pos and ch - pub fn new_raw<'b>(sess: &'a ParseSess, filemap: Rc) -> Self { + pub fn new_raw(sess: &'a ParseSess, filemap: Rc) -> Self { let mut sr = StringReader::new_raw_internal(sess, filemap); sr.bump(); sr @@ -180,7 +180,7 @@ impl<'a> StringReader<'a> { pub fn new(sess: &'a ParseSess, filemap: Rc) -> Self { let mut sr = StringReader::new_raw(sess, filemap); - if let Err(_) = sr.advance_token() { + if sr.advance_token().is_err() { sr.emit_fatal_errors(); panic!(FatalError); } @@ -205,7 +205,7 @@ impl<'a> StringReader<'a> { sr.bump(); - if let Err(_) = sr.advance_token() { + if sr.advance_token().is_err() { sr.emit_fatal_errors(); panic!(FatalError); } @@ -525,7 +525,7 @@ impl<'a> StringReader<'a> { self.bump(); } - return if doc_comment { + if doc_comment { self.with_str_from(start_bpos, |string| { // comments with only more "/"s are not doc comments let tok = if is_doc_comment(string) { @@ -544,7 +544,7 @@ impl<'a> StringReader<'a> { tok: token::Comment, sp: mk_sp(start_bpos, self.pos), }) - }; + } } Some('*') => { self.bump(); @@ -766,7 +766,7 @@ impl<'a> StringReader<'a> { } let pos = self.pos; self.check_float_base(start_bpos, pos, base); - return token::Float(self.name_from(start_bpos)); + token::Float(self.name_from(start_bpos)) } else { // it might be a float if it has an exponent if self.ch_is('e') || self.ch_is('E') { @@ -776,7 +776,7 @@ impl<'a> StringReader<'a> { return token::Float(self.name_from(start_bpos)); } // but we certainly have an integer! - return token::Integer(self.name_from(start_bpos)); + token::Integer(self.name_from(start_bpos)) } } @@ -1053,9 +1053,9 @@ impl<'a> StringReader<'a> { self.bump(); if self.ch_is('=') { self.bump(); - return token::BinOpEq(op); + token::BinOpEq(op) } else { - return token::BinOp(op); + token::BinOp(op) } } @@ -1102,15 +1102,15 @@ impl<'a> StringReader<'a> { // One-byte tokens. ';' => { self.bump(); - return Ok(token::Semi); + Ok(token::Semi) } ',' => { self.bump(); - return Ok(token::Comma); + Ok(token::Comma) } '.' => { self.bump(); - return if self.ch_is('.') { + if self.ch_is('.') { self.bump(); if self.ch_is('.') { self.bump(); @@ -1120,61 +1120,61 @@ impl<'a> StringReader<'a> { } } else { Ok(token::Dot) - }; + } } '(' => { self.bump(); - return Ok(token::OpenDelim(token::Paren)); + Ok(token::OpenDelim(token::Paren)) } ')' => { self.bump(); - return Ok(token::CloseDelim(token::Paren)); + Ok(token::CloseDelim(token::Paren)) } '{' => { self.bump(); - return Ok(token::OpenDelim(token::Brace)); + Ok(token::OpenDelim(token::Brace)) } '}' => { self.bump(); - return Ok(token::CloseDelim(token::Brace)); + Ok(token::CloseDelim(token::Brace)) } '[' => { self.bump(); - return Ok(token::OpenDelim(token::Bracket)); + Ok(token::OpenDelim(token::Bracket)) } ']' => { self.bump(); - return Ok(token::CloseDelim(token::Bracket)); + Ok(token::CloseDelim(token::Bracket)) } '@' => { self.bump(); - return Ok(token::At); + Ok(token::At) } '#' => { self.bump(); - return Ok(token::Pound); + Ok(token::Pound) } '~' => { self.bump(); - return Ok(token::Tilde); + Ok(token::Tilde) } '?' => { self.bump(); - return Ok(token::Question); + Ok(token::Question) } ':' => { self.bump(); if self.ch_is(':') { self.bump(); - return Ok(token::ModSep); + Ok(token::ModSep) } else { - return Ok(token::Colon); + Ok(token::Colon) } } '$' => { self.bump(); - return Ok(token::Dollar); + Ok(token::Dollar) } // Multi-byte tokens. @@ -1182,21 +1182,21 @@ impl<'a> StringReader<'a> { self.bump(); if self.ch_is('=') { self.bump(); - return Ok(token::EqEq); + Ok(token::EqEq) } else if self.ch_is('>') { self.bump(); - return Ok(token::FatArrow); + Ok(token::FatArrow) } else { - return Ok(token::Eq); + Ok(token::Eq) } } '!' => { self.bump(); if self.ch_is('=') { self.bump(); - return Ok(token::Ne); + Ok(token::Ne) } else { - return Ok(token::Not); + Ok(token::Not) } } '<' => { @@ -1204,21 +1204,21 @@ impl<'a> StringReader<'a> { match self.ch.unwrap_or('\x00') { '=' => { self.bump(); - return Ok(token::Le); + Ok(token::Le) } '<' => { - return Ok(self.binop(token::Shl)); + Ok(self.binop(token::Shl)) } '-' => { self.bump(); match self.ch.unwrap_or('\x00') { _ => { - return Ok(token::LArrow); + Ok(token::LArrow) } } } _ => { - return Ok(token::Lt); + Ok(token::Lt) } } } @@ -1227,13 +1227,13 @@ impl<'a> StringReader<'a> { match self.ch.unwrap_or('\x00') { '=' => { self.bump(); - return Ok(token::Ge); + Ok(token::Ge) } '>' => { - return Ok(self.binop(token::Shr)); + Ok(self.binop(token::Shr)) } _ => { - return Ok(token::Gt); + Ok(token::Gt) } } } @@ -1303,7 +1303,7 @@ impl<'a> StringReader<'a> { }; self.bump(); // advance ch past token let suffix = self.scan_optional_raw_name(); - return Ok(token::Literal(token::Char(id), suffix)); + Ok(token::Literal(token::Char(id), suffix)) } 'b' => { self.bump(); @@ -1314,7 +1314,7 @@ impl<'a> StringReader<'a> { _ => unreachable!(), // Should have been a token::Ident above. }; let suffix = self.scan_optional_raw_name(); - return Ok(token::Literal(lit, suffix)); + Ok(token::Literal(lit, suffix)) } '"' => { let start_bpos = self.pos; @@ -1345,7 +1345,7 @@ impl<'a> StringReader<'a> { }; self.bump(); let suffix = self.scan_optional_raw_name(); - return Ok(token::Literal(token::Str_(id), suffix)); + Ok(token::Literal(token::Str_(id), suffix)) } 'r' => { let start_bpos = self.pos; @@ -1416,24 +1416,24 @@ impl<'a> StringReader<'a> { Symbol::intern("??") }; let suffix = self.scan_optional_raw_name(); - return Ok(token::Literal(token::StrRaw(id, hash_count), suffix)); + Ok(token::Literal(token::StrRaw(id, hash_count), suffix)) } '-' => { if self.nextch_is('>') { self.bump(); self.bump(); - return Ok(token::RArrow); + Ok(token::RArrow) } else { - return Ok(self.binop(token::Minus)); + Ok(self.binop(token::Minus)) } } '&' => { if self.nextch_is('&') { self.bump(); self.bump(); - return Ok(token::AndAnd); + Ok(token::AndAnd) } else { - return Ok(self.binop(token::And)); + Ok(self.binop(token::And)) } } '|' => { @@ -1441,27 +1441,27 @@ impl<'a> StringReader<'a> { Some('|') => { self.bump(); self.bump(); - return Ok(token::OrOr); + Ok(token::OrOr) } _ => { - return Ok(self.binop(token::Or)); + Ok(self.binop(token::Or)) } } } '+' => { - return Ok(self.binop(token::Plus)); + Ok(self.binop(token::Plus)) } '*' => { - return Ok(self.binop(token::Star)); + Ok(self.binop(token::Star)) } '/' => { - return Ok(self.binop(token::Slash)); + Ok(self.binop(token::Slash)) } '^' => { - return Ok(self.binop(token::Caret)); + Ok(self.binop(token::Caret)) } '%' => { - return Ok(self.binop(token::Percent)); + Ok(self.binop(token::Percent)) } c => { let last_bpos = self.pos; @@ -1470,7 +1470,7 @@ impl<'a> StringReader<'a> { bpos, "unknown start of token", c); - unicode_chars::check_for_substitution(&self, c, &mut err); + unicode_chars::check_for_substitution(self, c, &mut err); self.fatal_errs.push(err); Err(()) } @@ -1492,14 +1492,14 @@ impl<'a> StringReader<'a> { if self.ch_is('\n') { self.bump(); } - return val; + val } fn read_one_line_comment(&mut self) -> String { let val = self.read_to_eol(); assert!((val.as_bytes()[0] == b'/' && val.as_bytes()[1] == b'/') || (val.as_bytes()[0] == b'#' && val.as_bytes()[1] == b'!')); - return val; + val } fn consume_non_eol_whitespace(&mut self) { @@ -1543,7 +1543,7 @@ impl<'a> StringReader<'a> { Symbol::intern("?") }; self.bump(); // advance ch past token - return token::Byte(id); + token::Byte(id) } fn scan_byte_escape(&mut self, delim: char, below_0x7f_only: bool) -> bool { @@ -1576,7 +1576,7 @@ impl<'a> StringReader<'a> { Symbol::intern("??") }; self.bump(); - return token::ByteStr(id); + token::ByteStr(id) } fn scan_raw_byte_string(&mut self) -> token::Lit { @@ -1629,8 +1629,8 @@ impl<'a> StringReader<'a> { self.bump(); } self.bump(); - return token::ByteStrRaw(self.name_from_to(content_start_bpos, content_end_bpos), - hash_count); + token::ByteStrRaw(self.name_from_to(content_start_bpos, content_end_bpos), + hash_count) } } @@ -1648,7 +1648,7 @@ fn in_range(c: Option, lo: char, hi: char) -> bool { } fn is_dec_digit(c: Option) -> bool { - return in_range(c, '0', '9'); + in_range(c, '0', '9') } pub fn is_doc_comment(s: &str) -> bool { diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index fe3ca1cf230..4fcf7614622 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -107,18 +107,18 @@ pub fn parse_crate_attrs_from_file<'a>(input: &Path, sess: &'a ParseSess) parser.parse_inner_attributes() } -pub fn parse_crate_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) - -> PResult<'a, ast::Crate> { +pub fn parse_crate_from_source_str(name: String, source: String, sess: &ParseSess) + -> PResult { new_parser_from_source_str(sess, name, source).parse_crate_mod() } -pub fn parse_crate_attrs_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) - -> PResult<'a, Vec> { +pub fn parse_crate_attrs_from_source_str(name: String, source: String, sess: &ParseSess) + -> PResult> { new_parser_from_source_str(sess, name, source).parse_inner_attributes() } -pub fn parse_expr_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) - -> PResult<'a, P> { +pub fn parse_expr_from_source_str(name: String, source: String, sess: &ParseSess) + -> PResult> { new_parser_from_source_str(sess, name, source).parse_expr() } @@ -126,29 +126,29 @@ pub fn parse_expr_from_source_str<'a>(name: String, source: String, sess: &'a Pa /// /// Returns `Ok(Some(item))` when successful, `Ok(None)` when no item was found, and`Err` /// when a syntax error occurred. -pub fn parse_item_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) - -> PResult<'a, Option>> { +pub fn parse_item_from_source_str(name: String, source: String, sess: &ParseSess) + -> PResult>> { new_parser_from_source_str(sess, name, source).parse_item() } -pub fn parse_meta_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) - -> PResult<'a, ast::MetaItem> { +pub fn parse_meta_from_source_str(name: String, source: String, sess: &ParseSess) + -> PResult { new_parser_from_source_str(sess, name, source).parse_meta_item() } -pub fn parse_stmt_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) - -> PResult<'a, Option> { +pub fn parse_stmt_from_source_str(name: String, source: String, sess: &ParseSess) + -> PResult> { new_parser_from_source_str(sess, name, source).parse_stmt() } -pub fn parse_stream_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess) +pub fn parse_stream_from_source_str(name: String, source: String, sess: &ParseSess) -> TokenStream { filemap_to_stream(sess, sess.codemap().new_filemap(name, source)) } // Create a new parser from a source string -pub fn new_parser_from_source_str<'a>(sess: &'a ParseSess, name: String, source: String) - -> Parser<'a> { +pub fn new_parser_from_source_str(sess: &ParseSess, name: String, source: String) + -> Parser { filemap_to_parser(sess, sess.codemap().new_filemap(name, source)) } @@ -173,7 +173,7 @@ pub fn new_sub_parser_from_file<'a>(sess: &'a ParseSess, } /// Given a filemap and config, return a parser -pub fn filemap_to_parser<'a>(sess: &'a ParseSess, filemap: Rc, ) -> Parser<'a> { +pub fn filemap_to_parser(sess: & ParseSess, filemap: Rc, ) -> Parser { let end_pos = filemap.end_pos; let mut parser = stream_to_parser(sess, filemap_to_stream(sess, filemap)); @@ -186,7 +186,7 @@ pub fn filemap_to_parser<'a>(sess: &'a ParseSess, filemap: Rc, ) -> Par // must preserve old name for now, because quote! from the *existing* // compiler expands into it -pub fn new_parser_from_tts<'a>(sess: &'a ParseSess, tts: Vec) -> Parser<'a> { +pub fn new_parser_from_tts(sess: &ParseSess, tts: Vec) -> Parser { stream_to_parser(sess, tts.into_iter().collect()) } @@ -216,8 +216,8 @@ pub fn filemap_to_stream(sess: &ParseSess, filemap: Rc) -> TokenStream panictry!(srdr.parse_all_token_trees()) } -/// Given stream and the ParseSess, produce a parser -pub fn stream_to_parser<'a>(sess: &'a ParseSess, stream: TokenStream) -> Parser<'a> { +/// Given stream and the `ParseSess`, produce a parser +pub fn stream_to_parser(sess: &ParseSess, stream: TokenStream) -> Parser { Parser::new(sess, stream, None, false) } @@ -251,7 +251,7 @@ pub fn char_lit(lit: &str) -> (char, isize) { (c, 4) } 'u' => { - assert!(lit.as_bytes()[2] == b'{'); + assert_eq!(lit.as_bytes()[2], b'{'); let idx = lit.find('}').unwrap(); let v = u32::from_str_radix(&lit[3..idx], 16).unwrap(); let c = char::from_u32(v).unwrap(); @@ -287,51 +287,46 @@ pub fn str_lit(lit: &str) -> String { } let mut chars = lit.char_indices().peekable(); - loop { - match chars.next() { - Some((i, c)) => { - match c { - '\\' => { - let ch = chars.peek().unwrap_or_else(|| { - panic!("{}", error(i)) - }).1; + while let Some((i, c)) = chars.next() { + match c { + '\\' => { + let ch = chars.peek().unwrap_or_else(|| { + panic!("{}", error(i)) + }).1; - if ch == '\n' { - eat(&mut chars); - } else if ch == '\r' { - chars.next(); - let ch = chars.peek().unwrap_or_else(|| { - panic!("{}", error(i)) - }).1; + if ch == '\n' { + eat(&mut chars); + } else if ch == '\r' { + chars.next(); + let ch = chars.peek().unwrap_or_else(|| { + panic!("{}", error(i)) + }).1; - if ch != '\n' { - panic!("lexer accepted bare CR"); - } - eat(&mut chars); - } else { - // otherwise, a normal escape - let (c, n) = char_lit(&lit[i..]); - for _ in 0..n - 1 { // we don't need to move past the first \ - chars.next(); - } - res.push(c); - } - }, - '\r' => { - let ch = chars.peek().unwrap_or_else(|| { - panic!("{}", error(i)) - }).1; - - if ch != '\n' { - panic!("lexer accepted bare CR"); - } - chars.next(); - res.push('\n'); + if ch != '\n' { + panic!("lexer accepted bare CR"); } - c => res.push(c), + eat(&mut chars); + } else { + // otherwise, a normal escape + let (c, n) = char_lit(&lit[i..]); + for _ in 0..n - 1 { // we don't need to move past the first \ + chars.next(); + } + res.push(c); } }, - None => break + '\r' => { + let ch = chars.peek().unwrap_or_else(|| { + panic!("{}", error(i)) + }).1; + + if ch != '\n' { + panic!("lexer accepted bare CR"); + } + chars.next(); + res.push('\n'); + } + c => res.push(c), } } @@ -348,20 +343,15 @@ pub fn raw_str_lit(lit: &str) -> String { // FIXME #8372: This could be a for-loop if it didn't borrow the iterator let mut chars = lit.chars().peekable(); - loop { - match chars.next() { - Some(c) => { - if c == '\r' { - if *chars.peek().unwrap() != '\n' { - panic!("lexer accepted bare CR"); - } - chars.next(); - res.push('\n'); - } else { - res.push(c); - } - }, - None => break + while let Some(c) = chars.next() { + if c == '\r' { + if *chars.peek().unwrap() != '\n' { + panic!("lexer accepted bare CR"); + } + chars.next(); + res.push('\n'); + } else { + res.push(c); } } @@ -459,7 +449,7 @@ pub fn byte_lit(lit: &str) -> (u8, usize) { if lit.len() == 1 { (lit.as_bytes()[0], 1) } else { - assert!(lit.as_bytes()[0] == b'\\', err(0)); + assert_eq!(lit.as_bytes()[0], b'\\', "{}", err(0)); let b = match lit.as_bytes()[1] { b'"' => b'"', b'n' => b'\n', @@ -480,7 +470,7 @@ pub fn byte_lit(lit: &str) -> (u8, usize) { } } }; - return (b, 2); + (b, 2) } } @@ -491,7 +481,7 @@ pub fn byte_str_lit(lit: &str) -> Rc> { let error = |i| format!("lexer should have rejected {} at {}", lit, i); /// Eat everything up to a non-whitespace - fn eat<'a, I: Iterator>(it: &mut iter::Peekable) { + fn eat>(it: &mut iter::Peekable) { loop { match it.peek().map(|x| x.1) { Some(b' ') | Some(b'\n') | Some(b'\r') | Some(b'\t') => { @@ -578,7 +568,7 @@ pub fn integer_lit(s: &str, suffix: Option, diag: Option<(Span, &Handler if let Some(err) = err { err!(diag, |span, diag| diag.span_err(span, err)); } - return filtered_float_lit(Symbol::intern(&s), Some(suf), diag) + return filtered_float_lit(Symbol::intern(s), Some(suf), diag) } } diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index d5baec675e4..078e86aa294 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -59,7 +59,7 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> { if !self.obsolete_set.contains(&kind) && (error || self.sess.span_diagnostic.can_emit_warnings) { - err.note(&format!("{}", desc)); + err.note(desc); self.obsolete_set.insert(kind); } err.emit(); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ca1351e3b41..28c57e0855f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -248,7 +248,7 @@ impl TokenCursor { fn next_desugared(&mut self) -> TokenAndSpan { let (sp, name) = match self.next() { TokenAndSpan { sp, tok: token::DocComment(name) } => (sp, name), - tok @ _ => return tok, + tok => return tok, }; let stripped = strip_doc_comment_decoration(&name.as_str()); @@ -354,7 +354,7 @@ pub enum Error { } impl Error { - pub fn span_err<'a>(self, sp: Span, handler: &'a errors::Handler) -> DiagnosticBuilder<'a> { + pub fn span_err(self, sp: Span, handler: &errors::Handler) -> DiagnosticBuilder { match self { Error::FileNotFoundForModule { ref mod_name, ref default_path, @@ -478,9 +478,10 @@ impl<'a> Parser<'a> { } fn next_tok(&mut self) -> TokenAndSpan { - let mut next = match self.desugar_doc_comments { - true => self.token_cursor.next_desugared(), - false => self.token_cursor.next(), + let mut next = if self.desugar_doc_comments { + self.token_cursor.next_desugared() + } else { + self.token_cursor.next() }; if next.sp == syntax_pos::DUMMY_SP { next.sp = self.prev_span; @@ -551,7 +552,7 @@ impl<'a> Parser<'a> { // This might be a sign we need a connect method on Iterator. let b = i.next() .map_or("".to_string(), |t| t.to_string()); - i.enumerate().fold(b, |mut b, (i, ref a)| { + i.enumerate().fold(b, |mut b, (i, a)| { if tokens.len() > 2 && i == tokens.len() - 2 { b.push_str(", or "); } else if tokens.len() == 2 && i == tokens.len() - 2 { @@ -985,18 +986,15 @@ impl<'a> Parser<'a> { token::CloseDelim(..) | token::Eof => break, _ => {} }; - match sep.sep { - Some(ref t) => { - if first { - first = false; - } else { - if let Err(e) = self.expect(t) { - fe(e); - break; - } + if let Some(ref t) = sep.sep { + if first { + first = false; + } else { + if let Err(e) = self.expect(t) { + fe(e); + break; } } - _ => () } if sep.trailing_sep_allowed && kets.iter().any(|k| self.check(k)) { break; @@ -1493,7 +1491,7 @@ impl<'a> Parser<'a> { let sum_span = ty.span.to(self.prev_span); let mut err = struct_span_err!(self.sess.span_diagnostic, sum_span, E0178, - "expected a path on the left-hand side of `+`, not `{}`", pprust::ty_to_string(&ty)); + "expected a path on the left-hand side of `+`, not `{}`", pprust::ty_to_string(ty)); match ty.node { TyKind::Rptr(ref lifetime, ref mut_ty) => { @@ -1547,8 +1545,8 @@ impl<'a> Parser<'a> { pub fn is_named_argument(&mut self) -> bool { let offset = match self.token { - token::BinOp(token::And) => 1, - token::AndAnd => 1, + token::BinOp(token::And) | + token::AndAnd | _ if self.token.is_keyword(keywords::Mut) => 1, _ => 0 }; @@ -2571,7 +2569,7 @@ impl<'a> Parser<'a> { s.print_usize(float.trunc() as usize)?; s.pclose()?; word(&mut s.s, ".")?; - word(&mut s.s, fstr.splitn(2, ".").last().unwrap()) + word(&mut s.s, fstr.splitn(2, '.').last().unwrap()) }); err.span_suggestion( lo.to(self.prev_span), @@ -3154,10 +3152,11 @@ impl<'a> Parser<'a> { let attrs = self.parse_outer_attributes()?; let pats = self.parse_pats()?; - let mut guard = None; - if self.eat_keyword(keywords::If) { - guard = Some(self.parse_expr()?); - } + let guard = if self.eat_keyword(keywords::If) { + Some(self.parse_expr()?) + } else { + None + }; self.expect(&token::FatArrow)?; let expr = self.parse_expr_res(RESTRICTION_STMT_EXPR, None)?; @@ -3600,10 +3599,11 @@ impl<'a> Parser<'a> { let lo = self.span; let pat = self.parse_pat()?; - let mut ty = None; - if self.eat(&token::Colon) { - ty = Some(self.parse_ty()?); - } + let ty = if self.eat(&token::Colon) { + Some(self.parse_ty()?) + } else { + None + }; let init = self.parse_initializer()?; Ok(P(ast::Local { ty: ty, @@ -3929,7 +3929,7 @@ impl<'a> Parser<'a> { }, None => { let unused_attrs = |attrs: &[_], s: &mut Self| { - if attrs.len() > 0 { + if !attrs.is_empty() { if s.prev_token_kind == PrevTokenKind::DocComment { s.span_fatal_err(s.prev_span, Error::UselessDocComment).emit(); } else { @@ -4815,7 +4815,7 @@ impl<'a> Parser<'a> { self.expect(&token::Not)?; } - self.complain_if_pub_macro(&vis, prev_span); + self.complain_if_pub_macro(vis, prev_span); // eat a matched-delimiter token tree: *at_end = true; @@ -4917,13 +4917,10 @@ impl<'a> Parser<'a> { } } } else { - match polarity { - ast::ImplPolarity::Negative => { - // This is a negated type implementation - // `impl !MyType {}`, which is not allowed. - self.span_err(neg_span, "inherent implementation can't be negated"); - }, - _ => {} + if let ast::ImplPolarity::Negative = polarity { + // This is a negated type implementation + // `impl !MyType {}`, which is not allowed. + self.span_err(neg_span, "inherent implementation can't be negated"); } None }; @@ -5185,7 +5182,7 @@ impl<'a> Parser<'a> { let path_span = self.prev_span; let help_msg = format!("make this visible only to module `{}` with `in`:", path); self.expect(&token::CloseDelim(token::Paren))?; // `)` - let mut err = self.span_fatal_help(path_span, &msg, &suggestion); + let mut err = self.span_fatal_help(path_span, msg, suggestion); err.span_suggestion(path_span, &help_msg, format!("in {}", path)); err.emit(); // emit diagnostic, but continue with public visibility } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 25cabef70c1..77db604c56e 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -53,6 +53,10 @@ impl DelimToken { pub fn len(self) -> usize { if self == NoDelim { 0 } else { 1 } } + + pub fn is_empty(self) -> bool { + self == NoDelim + } } #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)] @@ -198,17 +202,17 @@ impl Token { pub fn can_begin_expr(&self) -> bool { match *self { Ident(ident) => ident_can_begin_expr(ident), // value name or keyword - OpenDelim(..) => true, // tuple, array or block - Literal(..) => true, // literal - Not => true, // operator not - BinOp(Minus) => true, // unary minus - BinOp(Star) => true, // dereference - BinOp(Or) | OrOr => true, // closure - BinOp(And) => true, // reference - AndAnd => true, // double reference - DotDot | DotDotDot => true, // range notation - Lt | BinOp(Shl) => true, // associated path - ModSep => true, // global path + OpenDelim(..) | // tuple, array or block + Literal(..) | // literal + Not | // operator not + BinOp(Minus) | // unary minus + BinOp(Star) | // dereference + BinOp(Or) | OrOr | // closure + BinOp(And) | // reference + AndAnd | // double reference + DotDot | DotDotDot | // range notation + Lt | BinOp(Shl) | // associated path + ModSep | // global path Pound => true, // expression attributes Interpolated(ref nt) => match **nt { NtIdent(..) | NtExpr(..) | NtBlock(..) | NtPath(..) => true, @@ -222,16 +226,16 @@ impl Token { pub fn can_begin_type(&self) -> bool { match *self { Ident(ident) => ident_can_begin_type(ident), // type name or keyword - OpenDelim(Paren) => true, // tuple - OpenDelim(Bracket) => true, // array - Underscore => true, // placeholder - Not => true, // never - BinOp(Star) => true, // raw pointer - BinOp(And) => true, // reference - AndAnd => true, // double reference - Question => true, // maybe bound in trait object - Lifetime(..) => true, // lifetime bound in trait object - Lt | BinOp(Shl) => true, // associated path + OpenDelim(Paren) | // tuple + OpenDelim(Bracket) | // array + Underscore | // placeholder + Not | // never + BinOp(Star) | // raw pointer + BinOp(And) | // reference + AndAnd | // double reference + Question | // maybe bound in trait object + Lifetime(..) | // lifetime bound in trait object + Lt | BinOp(Shl) | // associated path ModSep => true, // global path Interpolated(ref nt) => match **nt { NtIdent(..) | NtTy(..) | NtPath(..) => true, diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 1d67c2a2c2b..e893c859247 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -113,22 +113,22 @@ //! between using 'left' and 'right' terms to denote the wrapped-to-ring-buffer //! and point-in-infinite-stream senses freely. //! -//! There is a parallel ring buffer, 'size', that holds the calculated size of +//! There is a parallel ring buffer, `size`, that holds the calculated size of //! each token. Why calculated? Because for Begin/End pairs, the "size" //! includes everything between the pair. That is, the "size" of Begin is //! actually the sum of the sizes of everything between Begin and the paired -//! End that follows. Since that is arbitrarily far in the future, 'size' is +//! End that follows. Since that is arbitrarily far in the future, `size` is //! being rewritten regularly while the printer runs; in fact most of the -//! machinery is here to work out 'size' entries on the fly (and give up when +//! machinery is here to work out `size` entries on the fly (and give up when //! they're so obviously over-long that "infinity" is a good enough //! approximation for purposes of line breaking). //! //! The "input side" of the printer is managed as an abstract process called -//! SCAN, which uses 'scan_stack', to manage calculating 'size'. SCAN is, in +//! SCAN, which uses `scan_stack`, to manage calculating `size`. SCAN is, in //! other words, the process of calculating 'size' entries. //! //! The "output side" of the printer is managed by an abstract process called -//! PRINT, which uses 'print_stack', 'margin' and 'space' to figure out what to +//! PRINT, which uses `print_stack`, `margin` and `space` to figure out what to //! do with each token/size pair it consumes as it goes. It's trying to consume //! the entire buffered window, but can't output anything until the size is >= //! 0 (sizes are set to negative while they're pending calculation). @@ -409,7 +409,7 @@ impl<'a> Printer<'a> { pub fn advance_right(&mut self) { self.right += 1; self.right %= self.buf_len; - assert!(self.right != self.left); + assert_ne!(self.right, self.left); } pub fn advance_left(&mut self) -> io::Result<()> { debug!("advance_left Vec<{},{}>, sizeof({})={}", self.left, self.right, diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 0c7e8fda837..6114db25fe8 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -233,7 +233,7 @@ pub fn token_to_string(tok: &Token) -> String { token::CloseDelim(token::Bracket) => "]".to_string(), token::OpenDelim(token::Brace) => "{".to_string(), token::CloseDelim(token::Brace) => "}".to_string(), - token::OpenDelim(token::NoDelim) => " ".to_string(), + token::OpenDelim(token::NoDelim) | token::CloseDelim(token::NoDelim) => " ".to_string(), token::Pound => "#".to_string(), token::Dollar => "$".to_string(), @@ -244,7 +244,7 @@ pub fn token_to_string(tok: &Token) -> String { let mut out = match lit { token::Byte(b) => format!("b'{}'", b), token::Char(c) => format!("'{}'", c), - token::Float(c) => c.to_string(), + token::Float(c) | token::Integer(c) => c.to_string(), token::Str_(s) => format!("\"{}\"", s), token::StrRaw(s, n) => format!("r{delim}\"{string}\"{delim}", @@ -277,23 +277,23 @@ pub fn token_to_string(tok: &Token) -> String { token::Shebang(s) => format!("/* shebang: {}*/", s), token::Interpolated(ref nt) => match **nt { - token::NtExpr(ref e) => expr_to_string(&e), - token::NtMeta(ref e) => meta_item_to_string(&e), - token::NtTy(ref e) => ty_to_string(&e), - token::NtPath(ref e) => path_to_string(&e), - token::NtItem(ref e) => item_to_string(&e), - token::NtBlock(ref e) => block_to_string(&e), - token::NtStmt(ref e) => stmt_to_string(&e), - token::NtPat(ref e) => pat_to_string(&e), + token::NtExpr(ref e) => expr_to_string(e), + token::NtMeta(ref e) => meta_item_to_string(e), + token::NtTy(ref e) => ty_to_string(e), + token::NtPath(ref e) => path_to_string(e), + token::NtItem(ref e) => item_to_string(e), + token::NtBlock(ref e) => block_to_string(e), + token::NtStmt(ref e) => stmt_to_string(e), + token::NtPat(ref e) => pat_to_string(e), token::NtIdent(ref e) => ident_to_string(e.node), token::NtTT(ref tree) => tt_to_string(tree.clone()), - token::NtArm(ref e) => arm_to_string(&e), - token::NtImplItem(ref e) => impl_item_to_string(&e), - token::NtTraitItem(ref e) => trait_item_to_string(&e), - token::NtGenerics(ref e) => generics_to_string(&e), - token::NtWhereClause(ref e) => where_clause_to_string(&e), - token::NtArg(ref e) => arg_to_string(&e), - token::NtVis(ref e) => vis_to_string(&e), + token::NtArm(ref e) => arm_to_string(e), + token::NtImplItem(ref e) => impl_item_to_string(e), + token::NtTraitItem(ref e) => trait_item_to_string(e), + token::NtGenerics(ref e) => generics_to_string(e), + token::NtWhereClause(ref e) => where_clause_to_string(e), + token::NtArg(ref e) => arg_to_string(e), + token::NtVis(ref e) => vis_to_string(e), } } } @@ -520,8 +520,7 @@ pub trait PrintState<'a> { let mut result = None; - if let &Some(ref lits) = self.literals() - { + if let Some(ref lits) = *self.literals() { while cur_lit < lits.len() { let ltrl = (*lits)[cur_lit].clone(); if ltrl.pos > pos { break; } @@ -618,11 +617,8 @@ pub trait PrintState<'a> { fn print_literal(&mut self, lit: &ast::Lit) -> io::Result<()> { self.maybe_print_comment(lit.span.lo)?; - match self.next_lit(lit.span.lo) { - Some(ref ltrl) => { - return word(self.writer(), &(*ltrl).lit); - } - _ => () + if let Some(ref ltrl) = self.next_lit(lit.span.lo) { + return word(self.writer(), &(*ltrl).lit); } match lit.node { ast::LitKind::Str(st, style) => self.print_string(&st.as_str(), style), @@ -799,7 +795,7 @@ pub trait PrintState<'a> { self.popen()?; self.commasep(Consistent, &items[..], - |s, i| s.print_meta_list_item(&i))?; + |s, i| s.print_meta_list_item(i))?; self.pclose()?; } } @@ -965,11 +961,9 @@ impl<'a> State<'a> { { self.rbox(0, b)?; let len = elts.len(); - let mut i = 0; - for elt in elts { + for (i, elt) in elts.iter().enumerate() { self.maybe_print_comment(get_span(elt).hi)?; op(self, elt)?; - i += 1; if i < len { word(&mut self.s, ",")?; self.maybe_print_trailing_comment(get_span(elt), @@ -982,14 +976,14 @@ impl<'a> State<'a> { pub fn commasep_exprs(&mut self, b: Breaks, exprs: &[P]) -> io::Result<()> { - self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&e), |e| e.span) + self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e), |e| e.span) } pub fn print_mod(&mut self, _mod: &ast::Mod, attrs: &[ast::Attribute]) -> io::Result<()> { self.print_inner_attributes(attrs)?; for item in &_mod.items { - self.print_item(&item)?; + self.print_item(item)?; } Ok(()) } @@ -1018,7 +1012,7 @@ impl<'a> State<'a> { match ty.node { ast::TyKind::Slice(ref ty) => { word(&mut self.s, "[")?; - self.print_type(&ty)?; + self.print_type(ty)?; word(&mut self.s, "]")?; } ast::TyKind::Ptr(ref mt) => { @@ -1040,7 +1034,7 @@ impl<'a> State<'a> { ast::TyKind::Tup(ref elts) => { self.popen()?; self.commasep(Inconsistent, &elts[..], - |s, ty| s.print_type(&ty))?; + |s, ty| s.print_type(ty))?; if elts.len() == 1 { word(&mut self.s, ",")?; } @@ -1048,7 +1042,7 @@ impl<'a> State<'a> { } ast::TyKind::Paren(ref typ) => { self.popen()?; - self.print_type(&typ)?; + self.print_type(typ)?; self.pclose()?; } ast::TyKind::BareFn(ref f) => { @@ -1081,14 +1075,14 @@ impl<'a> State<'a> { } ast::TyKind::Array(ref ty, ref v) => { word(&mut self.s, "[")?; - self.print_type(&ty)?; + self.print_type(ty)?; word(&mut self.s, "; ")?; - self.print_expr(&v)?; + self.print_expr(v)?; word(&mut self.s, "]")?; } ast::TyKind::Typeof(ref e) => { word(&mut self.s, "typeof(")?; - self.print_expr(&e)?; + self.print_expr(e)?; word(&mut self.s, ")")?; } ast::TyKind::Infer => { @@ -1130,7 +1124,7 @@ impl<'a> State<'a> { } self.print_ident(item.ident)?; self.word_space(":")?; - self.print_type(&t)?; + self.print_type(t)?; word(&mut self.s, ";")?; self.end()?; // end the head-ibox self.end() // end the outer cbox @@ -1187,7 +1181,7 @@ impl<'a> State<'a> { self.head(&visibility_qualified(&item.vis, "extern crate"))?; if let Some(p) = *optional_path { let val = p.as_str(); - if val.contains("-") { + if val.contains('-') { self.print_string(&val, ast::StrStyle::Cooked)?; } else { self.print_name(p)?; @@ -1203,7 +1197,7 @@ impl<'a> State<'a> { } ast::ItemKind::Use(ref vp) => { self.head(&visibility_qualified(&item.vis, "use"))?; - self.print_view_path(&vp)?; + self.print_view_path(vp)?; word(&mut self.s, ";")?; self.end()?; // end inner head-block self.end()?; // end outer head-block @@ -1215,12 +1209,12 @@ impl<'a> State<'a> { } self.print_ident(item.ident)?; self.word_space(":")?; - self.print_type(&ty)?; + self.print_type(ty)?; space(&mut self.s)?; self.end()?; // end the head-ibox self.word_space("=")?; - self.print_expr(&expr)?; + self.print_expr(expr)?; word(&mut self.s, ";")?; self.end()?; // end the outer cbox } @@ -1228,12 +1222,12 @@ impl<'a> State<'a> { self.head(&visibility_qualified(&item.vis, "const"))?; self.print_ident(item.ident)?; self.word_space(":")?; - self.print_type(&ty)?; + self.print_type(ty)?; space(&mut self.s)?; self.end()?; // end the head-ibox self.word_space("=")?; - self.print_expr(&expr)?; + self.print_expr(expr)?; word(&mut self.s, ";")?; self.end()?; // end the outer cbox } @@ -1249,7 +1243,7 @@ impl<'a> State<'a> { &item.vis )?; word(&mut self.s, " ")?; - self.print_block_with_attrs(&body, &item.attrs)?; + self.print_block_with_attrs(body, &item.attrs)?; } ast::ItemKind::Mod(ref _mod) => { self.head(&visibility_qualified(&item.vis, "mod"))?; @@ -1282,7 +1276,7 @@ impl<'a> State<'a> { self.print_where_clause(¶ms.where_clause)?; space(&mut self.s)?; self.word_space("=")?; - self.print_type(&ty)?; + self.print_type(ty)?; word(&mut self.s, ";")?; self.end()?; // end the outer ibox } @@ -1297,11 +1291,11 @@ impl<'a> State<'a> { } ast::ItemKind::Struct(ref struct_def, ref generics) => { self.head(&visibility_qualified(&item.vis, "struct"))?; - self.print_struct(&struct_def, generics, item.ident, item.span, true)?; + self.print_struct(struct_def, generics, item.ident, item.span, true)?; } ast::ItemKind::Union(ref struct_def, ref generics) => { self.head(&visibility_qualified(&item.vis, "union"))?; - self.print_struct(&struct_def, generics, item.ident, item.span, true)?; + self.print_struct(struct_def, generics, item.ident, item.span, true)?; } ast::ItemKind::DefaultImpl(unsafety, ref trait_ref) => { self.head("")?; @@ -1333,11 +1327,8 @@ impl<'a> State<'a> { space(&mut self.s)?; } - match polarity { - ast::ImplPolarity::Negative => { - word(&mut self.s, "!")?; - }, - _ => {} + if let ast::ImplPolarity::Negative = polarity { + word(&mut self.s, "!")?; } if let Some(ref t) = *opt_trait { @@ -1346,7 +1337,7 @@ impl<'a> State<'a> { self.word_space("for")?; } - self.print_type(&ty)?; + self.print_type(ty)?; self.print_where_clause(&generics.where_clause)?; space(&mut self.s)?; @@ -1543,7 +1534,7 @@ impl<'a> State<'a> { Some(ref d) => { space(&mut self.s)?; self.word_space("=")?; - self.print_expr(&d) + self.print_expr(d) } _ => Ok(()) } @@ -1571,7 +1562,7 @@ impl<'a> State<'a> { self.print_outer_attributes(&ti.attrs)?; match ti.node { ast::TraitItemKind::Const(ref ty, ref default) => { - self.print_associated_const(ti.ident, &ty, + self.print_associated_const(ti.ident, ty, default.as_ref().map(|expr| &**expr), &ast::Visibility::Inherited)?; } @@ -1614,7 +1605,7 @@ impl<'a> State<'a> { self.print_defaultness(ii.defaultness)?; match ii.node { ast::ImplItemKind::Const(ref ty, ref expr) => { - self.print_associated_const(ii.ident, &ty, Some(&expr), &ii.vis)?; + self.print_associated_const(ii.ident, ty, Some(expr), &ii.vis)?; } ast::ImplItemKind::Method(ref sig, ref body) => { self.head("")?; @@ -1650,38 +1641,38 @@ impl<'a> State<'a> { self.word_nbsp("let")?; self.ibox(INDENT_UNIT)?; - self.print_local_decl(&loc)?; + self.print_local_decl(loc)?; self.end()?; if let Some(ref init) = loc.init { self.nbsp()?; self.word_space("=")?; - self.print_expr(&init)?; + self.print_expr(init)?; } word(&mut self.s, ";")?; self.end()?; } - ast::StmtKind::Item(ref item) => self.print_item(&item)?, + ast::StmtKind::Item(ref item) => self.print_item(item)?, ast::StmtKind::Expr(ref expr) => { self.space_if_not_bol()?; - self.print_expr_outer_attr_style(&expr, false)?; + self.print_expr_outer_attr_style(expr, false)?; if parse::classify::expr_requires_semi_to_be_stmt(expr) { word(&mut self.s, ";")?; } } ast::StmtKind::Semi(ref expr) => { self.space_if_not_bol()?; - self.print_expr_outer_attr_style(&expr, false)?; + self.print_expr_outer_attr_style(expr, false)?; word(&mut self.s, ";")?; } ast::StmtKind::Mac(ref mac) => { let (ref mac, style, ref attrs) = **mac; self.space_if_not_bol()?; - self.print_outer_attributes(&attrs)?; + self.print_outer_attributes(attrs)?; let delim = match style { ast::MacStmtStyle::Braces => token::Brace, _ => token::Paren }; - self.print_mac(&mac, delim)?; + self.print_mac(mac, delim)?; if style == ast::MacStmtStyle::Semicolon { word(&mut self.s, ";")?; } @@ -1735,7 +1726,7 @@ impl<'a> State<'a> { ast::StmtKind::Expr(ref expr) if i == blk.stmts.len() - 1 => { self.maybe_print_comment(st.span.lo)?; self.space_if_not_bol()?; - self.print_expr_outer_attr_style(&expr, false)?; + self.print_expr_outer_attr_style(expr, false)?; self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi))?; } _ => self.print_stmt(st)?, @@ -1755,9 +1746,9 @@ impl<'a> State<'a> { self.cbox(INDENT_UNIT - 1)?; self.ibox(0)?; word(&mut self.s, " else if ")?; - self.print_expr(&i)?; + self.print_expr(i)?; space(&mut self.s)?; - self.print_block(&then)?; + self.print_block(then)?; self.print_else(e.as_ref().map(|e| &**e)) } // "another else-if-let" @@ -1765,12 +1756,12 @@ impl<'a> State<'a> { self.cbox(INDENT_UNIT - 1)?; self.ibox(0)?; word(&mut self.s, " else if let ")?; - self.print_pat(&pat)?; + self.print_pat(pat)?; space(&mut self.s)?; self.word_space("=")?; - self.print_expr(&expr)?; + self.print_expr(expr)?; space(&mut self.s)?; - self.print_block(&then)?; + self.print_block(then)?; self.print_else(e.as_ref().map(|e| &**e)) } // "final else" @@ -1778,7 +1769,7 @@ impl<'a> State<'a> { self.cbox(INDENT_UNIT - 1)?; self.ibox(0)?; word(&mut self.s, " else ")?; - self.print_block(&b) + self.print_block(b) } // BLEAH, constraints would be great here _ => { @@ -1844,12 +1835,8 @@ impl<'a> State<'a> { binop: ast::BinOp) -> bool { match sub_expr.node { ast::ExprKind::Binary(ref sub_op, _, _) => { - if AssocOp::from_ast_binop(sub_op.node).precedence() < - AssocOp::from_ast_binop(binop.node).precedence() { - true - } else { - false - } + AssocOp::from_ast_binop(sub_op.node).precedence() < + AssocOp::from_ast_binop(binop.node).precedence() } _ => true } @@ -1929,7 +1916,7 @@ impl<'a> State<'a> { space(&mut self.s)?; } word(&mut self.s, "..")?; - self.print_expr(&expr)?; + self.print_expr(expr)?; self.end()?; } _ => if !fields.is_empty() { @@ -1969,7 +1956,7 @@ impl<'a> State<'a> { if !tys.is_empty() { word(&mut self.s, "::<")?; self.commasep(Inconsistent, tys, - |s, ty| s.print_type(&ty))?; + |s, ty| s.print_type(ty))?; word(&mut self.s, ">")?; } self.print_call_post(base_args) @@ -2038,7 +2025,7 @@ impl<'a> State<'a> { self.print_expr_vec(&exprs[..], attrs)?; } ast::ExprKind::Repeat(ref element, ref count) => { - self.print_expr_repeat(&element, &count, attrs)?; + self.print_expr_repeat(element, count, attrs)?; } ast::ExprKind::Struct(ref path, ref fields, ref wth) => { self.print_expr_struct(path, &fields[..], wth, attrs)?; @@ -2047,43 +2034,43 @@ impl<'a> State<'a> { self.print_expr_tup(&exprs[..], attrs)?; } ast::ExprKind::Call(ref func, ref args) => { - self.print_expr_call(&func, &args[..])?; + self.print_expr_call(func, &args[..])?; } ast::ExprKind::MethodCall(ident, ref tys, ref args) => { self.print_expr_method_call(ident, &tys[..], &args[..])?; } ast::ExprKind::Binary(op, ref lhs, ref rhs) => { - self.print_expr_binary(op, &lhs, &rhs)?; + self.print_expr_binary(op, lhs, rhs)?; } ast::ExprKind::Unary(op, ref expr) => { - self.print_expr_unary(op, &expr)?; + self.print_expr_unary(op, expr)?; } ast::ExprKind::AddrOf(m, ref expr) => { - self.print_expr_addr_of(m, &expr)?; + self.print_expr_addr_of(m, expr)?; } ast::ExprKind::Lit(ref lit) => { - self.print_literal(&lit)?; + self.print_literal(lit)?; } ast::ExprKind::Cast(ref expr, ref ty) => { if let ast::ExprKind::Cast(..) = expr.node { - self.print_expr(&expr)?; + self.print_expr(expr)?; } else { - self.print_expr_maybe_paren(&expr)?; + self.print_expr_maybe_paren(expr)?; } space(&mut self.s)?; self.word_space("as")?; - self.print_type(&ty)?; + self.print_type(ty)?; } ast::ExprKind::Type(ref expr, ref ty) => { - self.print_expr(&expr)?; + self.print_expr(expr)?; self.word_space(":")?; - self.print_type(&ty)?; + self.print_type(ty)?; } ast::ExprKind::If(ref test, ref blk, ref elseopt) => { - self.print_if(&test, &blk, elseopt.as_ref().map(|e| &**e))?; + self.print_if(test, blk, elseopt.as_ref().map(|e| &**e))?; } ast::ExprKind::IfLet(ref pat, ref expr, ref blk, ref elseopt) => { - self.print_if_let(&pat, &expr, &blk, elseopt.as_ref().map(|e| &**e))?; + self.print_if_let(pat, expr, blk, elseopt.as_ref().map(|e| &**e))?; } ast::ExprKind::While(ref test, ref blk, opt_ident) => { if let Some(ident) = opt_ident { @@ -2091,9 +2078,9 @@ impl<'a> State<'a> { self.word_space(":")?; } self.head("while")?; - self.print_expr(&test)?; + self.print_expr(test)?; space(&mut self.s)?; - self.print_block_with_attrs(&blk, attrs)?; + self.print_block_with_attrs(blk, attrs)?; } ast::ExprKind::WhileLet(ref pat, ref expr, ref blk, opt_ident) => { if let Some(ident) = opt_ident { @@ -2101,12 +2088,12 @@ impl<'a> State<'a> { self.word_space(":")?; } self.head("while let")?; - self.print_pat(&pat)?; + self.print_pat(pat)?; space(&mut self.s)?; self.word_space("=")?; - self.print_expr(&expr)?; + self.print_expr(expr)?; space(&mut self.s)?; - self.print_block_with_attrs(&blk, attrs)?; + self.print_block_with_attrs(blk, attrs)?; } ast::ExprKind::ForLoop(ref pat, ref iter, ref blk, opt_ident) => { if let Some(ident) = opt_ident { @@ -2114,12 +2101,12 @@ impl<'a> State<'a> { self.word_space(":")?; } self.head("for")?; - self.print_pat(&pat)?; + self.print_pat(pat)?; space(&mut self.s)?; self.word_space("in")?; - self.print_expr(&iter)?; + self.print_expr(iter)?; space(&mut self.s)?; - self.print_block_with_attrs(&blk, attrs)?; + self.print_block_with_attrs(blk, attrs)?; } ast::ExprKind::Loop(ref blk, opt_ident) => { if let Some(ident) = opt_ident { @@ -2128,13 +2115,13 @@ impl<'a> State<'a> { } self.head("loop")?; space(&mut self.s)?; - self.print_block_with_attrs(&blk, attrs)?; + self.print_block_with_attrs(blk, attrs)?; } ast::ExprKind::Match(ref expr, ref arms) => { self.cbox(INDENT_UNIT)?; self.ibox(4)?; self.word_nbsp("match")?; - self.print_expr(&expr)?; + self.print_expr(expr)?; space(&mut self.s)?; self.bopen()?; self.print_inner_attributes_no_trailing_hardbreak(attrs)?; @@ -2146,7 +2133,7 @@ impl<'a> State<'a> { ast::ExprKind::Closure(capture_clause, ref decl, ref body, _) => { self.print_capture_clause(capture_clause)?; - self.print_fn_block_args(&decl)?; + self.print_fn_block_args(decl)?; space(&mut self.s)?; self.print_expr(body)?; self.end()?; // need to close a box @@ -2161,48 +2148,48 @@ impl<'a> State<'a> { self.cbox(INDENT_UNIT)?; // head-box, will be closed by print-block after { self.ibox(0)?; - self.print_block_with_attrs(&blk, attrs)?; + self.print_block_with_attrs(blk, attrs)?; } ast::ExprKind::Assign(ref lhs, ref rhs) => { - self.print_expr(&lhs)?; + self.print_expr(lhs)?; space(&mut self.s)?; self.word_space("=")?; - self.print_expr(&rhs)?; + self.print_expr(rhs)?; } ast::ExprKind::AssignOp(op, ref lhs, ref rhs) => { - self.print_expr(&lhs)?; + self.print_expr(lhs)?; space(&mut self.s)?; word(&mut self.s, op.node.to_string())?; self.word_space("=")?; - self.print_expr(&rhs)?; + self.print_expr(rhs)?; } ast::ExprKind::Field(ref expr, id) => { - self.print_expr(&expr)?; + self.print_expr(expr)?; word(&mut self.s, ".")?; self.print_ident(id.node)?; } ast::ExprKind::TupField(ref expr, id) => { - self.print_expr(&expr)?; + self.print_expr(expr)?; word(&mut self.s, ".")?; self.print_usize(id.node)?; } ast::ExprKind::Index(ref expr, ref index) => { - self.print_expr(&expr)?; + self.print_expr(expr)?; word(&mut self.s, "[")?; - self.print_expr(&index)?; + self.print_expr(index)?; word(&mut self.s, "]")?; } ast::ExprKind::Range(ref start, ref end, limits) => { - if let &Some(ref e) = start { - self.print_expr(&e)?; + if let Some(ref e) = *start { + self.print_expr(e)?; } if limits == ast::RangeLimits::HalfOpen { word(&mut self.s, "..")?; } else { word(&mut self.s, "...")?; } - if let &Some(ref e) = end { - self.print_expr(&e)?; + if let Some(ref e) = *end { + self.print_expr(e)?; } } ast::ExprKind::Path(None, ref path) => { @@ -2233,12 +2220,9 @@ impl<'a> State<'a> { } ast::ExprKind::Ret(ref result) => { word(&mut self.s, "return")?; - match *result { - Some(ref expr) => { - word(&mut self.s, " ")?; - self.print_expr(&expr)?; - } - _ => () + if let Some(ref expr) = *result { + word(&mut self.s, " ")?; + self.print_expr(expr)?; } } ast::ExprKind::InlineAsm(ref a) => { @@ -2268,7 +2252,7 @@ impl<'a> State<'a> { self.commasep(Inconsistent, &a.inputs, |s, &(co, ref o)| { s.print_string(&co.as_str(), ast::StrStyle::Cooked)?; s.popen()?; - s.print_expr(&o)?; + s.print_expr(o)?; s.pclose()?; Ok(()) })?; @@ -2308,7 +2292,7 @@ impl<'a> State<'a> { ast::ExprKind::Paren(ref e) => { self.popen()?; self.print_inner_attributes_inline(attrs)?; - self.print_expr(&e)?; + self.print_expr(e)?; self.pclose()?; }, ast::ExprKind::Try(ref e) => { @@ -2318,7 +2302,7 @@ impl<'a> State<'a> { ast::ExprKind::Catch(ref blk) => { self.head("do catch")?; space(&mut self.s)?; - self.print_block_with_attrs(&blk, attrs)? + self.print_block_with_attrs(blk, attrs)? } } self.ann.post(self, NodeExpr(expr))?; @@ -2329,7 +2313,7 @@ impl<'a> State<'a> { self.print_pat(&loc.pat)?; if let Some(ref ty) = loc.ty { self.word_space(":")?; - self.print_type(&ty)?; + self.print_type(ty)?; } Ok(()) } @@ -2397,7 +2381,7 @@ impl<'a> State<'a> { space(&mut self.s)?; self.word_space("as")?; let depth = path.segments.len() - qself.position; - self.print_path(&path, false, depth, false)?; + self.print_path(path, false, depth, false)?; } word(&mut self.s, ">")?; word(&mut self.s, "::")?; @@ -2438,7 +2422,7 @@ impl<'a> State<'a> { self.commasep( Inconsistent, &data.types, - |s, ty| s.print_type(&ty))?; + |s, ty| s.print_type(ty))?; comma = true; } @@ -2461,13 +2445,13 @@ impl<'a> State<'a> { self.commasep( Inconsistent, &data.inputs, - |s, ty| s.print_type(&ty))?; + |s, ty| s.print_type(ty))?; word(&mut self.s, ")")?; if let Some(ref ty) = data.output { self.space_if_not_bol()?; self.word_space("->")?; - self.print_type(&ty)?; + self.print_type(ty)?; } } } @@ -2496,24 +2480,24 @@ impl<'a> State<'a> { self.print_ident(path1.node)?; if let Some(ref p) = *sub { word(&mut self.s, "@")?; - self.print_pat(&p)?; + self.print_pat(p)?; } } PatKind::TupleStruct(ref path, ref elts, ddpos) => { self.print_path(path, true, 0, false)?; self.popen()?; if let Some(ddpos) = ddpos { - self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p))?; + self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p))?; if ddpos != 0 { self.word_space(",")?; } word(&mut self.s, "..")?; if ddpos != elts.len() { word(&mut self.s, ",")?; - self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p))?; + self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(p))?; } } else { - self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p))?; + self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p))?; } self.pclose()?; } @@ -2549,17 +2533,17 @@ impl<'a> State<'a> { PatKind::Tuple(ref elts, ddpos) => { self.popen()?; if let Some(ddpos) = ddpos { - self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p))?; + self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p))?; if ddpos != 0 { self.word_space(",")?; } word(&mut self.s, "..")?; if ddpos != elts.len() { word(&mut self.s, ",")?; - self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p))?; + self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(p))?; } } else { - self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p))?; + self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p))?; if elts.len() == 1 { word(&mut self.s, ",")?; } @@ -2568,41 +2552,41 @@ impl<'a> State<'a> { } PatKind::Box(ref inner) => { word(&mut self.s, "box ")?; - self.print_pat(&inner)?; + self.print_pat(inner)?; } PatKind::Ref(ref inner, mutbl) => { word(&mut self.s, "&")?; if mutbl == ast::Mutability::Mutable { word(&mut self.s, "mut ")?; } - self.print_pat(&inner)?; + self.print_pat(inner)?; } PatKind::Lit(ref e) => self.print_expr(&**e)?, PatKind::Range(ref begin, ref end, ref end_kind) => { - self.print_expr(&begin)?; + self.print_expr(begin)?; space(&mut self.s)?; match *end_kind { RangeEnd::Included => word(&mut self.s, "...")?, RangeEnd::Excluded => word(&mut self.s, "..")?, } - self.print_expr(&end)?; + self.print_expr(end)?; } PatKind::Slice(ref before, ref slice, ref after) => { word(&mut self.s, "[")?; self.commasep(Inconsistent, &before[..], - |s, p| s.print_pat(&p))?; + |s, p| s.print_pat(p))?; if let Some(ref p) = *slice { if !before.is_empty() { self.word_space(",")?; } if p.node != PatKind::Wild { - self.print_pat(&p)?; + self.print_pat(p)?; } word(&mut self.s, "..")?; if !after.is_empty() { self.word_space(",")?; } } self.commasep(Inconsistent, &after[..], - |s, p| s.print_pat(&p))?; + |s, p| s.print_pat(p))?; word(&mut self.s, "]")?; } PatKind::Mac(ref m) => self.print_mac(m, token::Paren)?, @@ -2628,12 +2612,12 @@ impl<'a> State<'a> { space(&mut self.s)?; self.word_space("|")?; } - self.print_pat(&p)?; + self.print_pat(p)?; } space(&mut self.s)?; if let Some(ref e) = arm.guard { self.word_space("if")?; - self.print_expr(&e)?; + self.print_expr(e)?; space(&mut self.s)?; } self.word_space("=>")?; @@ -2641,7 +2625,7 @@ impl<'a> State<'a> { match arm.body.node { ast::ExprKind::Block(ref blk) => { // the block will close the pattern's ibox - self.print_block_unclosed_indent(&blk, INDENT_UNIT)?; + self.print_block_unclosed_indent(blk, INDENT_UNIT)?; // If it is a user-provided unsafe block, print a comma after it if let BlockCheckMode::Unsafe(ast::UserProvided) = blk.rules { @@ -2673,7 +2657,7 @@ impl<'a> State<'a> { self.print_mutability(m)?; word(&mut self.s, "self")?; self.word_space(":")?; - self.print_type(&typ) + self.print_type(typ) } } } @@ -2725,7 +2709,7 @@ impl<'a> State<'a> { self.word_space("->")?; match decl.output { ast::FunctionRetTy::Ty(ref ty) => { - self.print_type(&ty)?; + self.print_type(ty)?; self.maybe_print_comment(ty.span.lo) } ast::FunctionRetTy::Default(..) => unreachable!(), @@ -2839,7 +2823,7 @@ impl<'a> State<'a> { Some(ref default) => { space(&mut self.s)?; self.word_space("=")?; - self.print_type(&default) + self.print_type(default) } _ => Ok(()) } @@ -2865,7 +2849,7 @@ impl<'a> State<'a> { ref bounds, ..}) => { self.print_formal_lifetime_list(bound_lifetimes)?; - self.print_type(&bounded_ty)?; + self.print_type(bounded_ty)?; self.print_bounds(":", bounds)?; } ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime, @@ -2977,7 +2961,7 @@ impl<'a> State<'a> { match decl.output { ast::FunctionRetTy::Default(..) => unreachable!(), ast::FunctionRetTy::Ty(ref ty) => - self.print_type(&ty)? + self.print_type(ty)? } self.end()?; @@ -3044,14 +3028,9 @@ impl<'a> State<'a> { if self.next_comment().is_none() { hardbreak(&mut self.s)?; } - loop { - match self.next_comment() { - Some(ref cmnt) => { - self.print_comment(cmnt)?; - self.cur_cmnt_and_lit.cur_cmnt += 1; - } - _ => break - } + while let Some(ref cmnt) = self.next_comment() { + self.print_comment(cmnt)?; + self.cur_cmnt_and_lit.cur_cmnt += 1; } Ok(()) } diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index c7820a15fb3..8e257102e1c 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -18,7 +18,7 @@ use ptr::P; use tokenstream::TokenStream; /// Craft a span that will be ignored by the stability lint's -/// call to codemap's is_internal check. +/// call to codemap's `is_internal` check. /// The expanded code uses the unstable `#[prelude_import]` attribute. fn ignored_span(sp: Span) -> Span { let mark = Mark::fresh(); @@ -49,7 +49,7 @@ pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option return krate, }; - let crate_name = Symbol::intern(&alt_std_name.unwrap_or(name.to_string())); + let crate_name = Symbol::intern(&alt_std_name.unwrap_or_else(|| name.to_string())); krate.module.items.insert(0, P(ast::Item { attrs: vec![attr::mk_attr_outer(DUMMY_SP, diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 91746a2edd9..bb1a6ff65a5 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -106,9 +106,8 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { // Add a special __test module to the crate that will contain code // generated for the test harness let (mod_, reexport) = mk_test_module(&mut self.cx); - match reexport { - Some(re) => folded.module.items.push(re), - None => {} + if let Some(re) = reexport { + folded.module.items.push(re) } folded.module.items.push(mod_); folded @@ -257,7 +256,7 @@ fn mk_reexport_mod(cx: &mut TestCtxt, let parent = if parent == ast::DUMMY_NODE_ID { ast::CRATE_NODE_ID } else { parent }; cx.ext_cx.current_expansion.mark = cx.ext_cx.resolver.get_module_scope(parent); let it = cx.ext_cx.monotonic_expander().fold_item(P(ast::Item { - ident: sym.clone(), + ident: sym, attrs: Vec::new(), id: ast::DUMMY_NODE_ID, node: ast::ItemKind::Mod(reexport_mod), @@ -308,7 +307,7 @@ fn generate_test_harness(sess: &ParseSess, } /// Craft a span that will be ignored by the stability lint's -/// call to codemap's is_internal check. +/// call to codemap's `is_internal` check. /// The expanded code calls some unstable functions in the test crate. fn ignored_span(cx: &TestCtxt, sp: Span) -> Span { Span { ctxt: cx.ctxt, ..sp } @@ -354,7 +353,7 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { } } - return has_test_attr && has_test_signature(i) == Yes; + has_test_attr && has_test_signature(i) == Yes } fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool { @@ -385,7 +384,7 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool { `fn(&mut Bencher) -> ()`"); } - return has_bench_attr && has_test_signature(i); + has_bench_attr && has_test_signature(i) } fn is_ignored(i: &ast::Item) -> bool { @@ -504,16 +503,14 @@ fn mk_main(cx: &mut TestCtxt) -> P { ast::Unsafety::Normal, dummy_spanned(ast::Constness::NotConst), ::abi::Abi::Rust, ast::Generics::default(), main_body); - let main = P(ast::Item { + P(ast::Item { ident: Ident::from_str("main"), attrs: vec![main_attr], id: ast::DUMMY_NODE_ID, node: main, vis: ast::Visibility::Public, span: sp - }); - - return main; + }) } fn mk_test_module(cx: &mut TestCtxt) -> (P, Option>) { diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 86bfdebe42b..9c1371a31fe 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -10,16 +10,16 @@ //! # Token Streams //! -//! TokenStreams represent syntactic objects before they are converted into ASTs. +//! `TokenStream`s represent syntactic objects before they are converted into ASTs. //! A `TokenStream` is, roughly speaking, a sequence (eg stream) of `TokenTree`s, //! which are themselves a single `Token` or a `Delimited` subsequence of tokens. //! //! ## Ownership -//! TokenStreams are persistent data structures constructed as ropes with reference -//! counted-children. In general, this means that calling an operation on a TokenStream -//! (such as `slice`) produces an entirely new TokenStream from the borrowed reference to -//! the original. This essentially coerces TokenStreams into 'views' of their subparts, -//! and a borrowed TokenStream is sufficient to build an owned TokenStream without taking +//! `TokenStreams` are persistent data structures constructed as ropes with reference +//! counted-children. In general, this means that calling an operation on a `TokenStream` +//! (such as `slice`) produces an entirely new `TokenStream` from the borrowed reference to +//! the original. This essentially coerces `TokenStream`s into 'views' of their subparts, +//! and a borrowed `TokenStream` is sufficient to build an owned `TokenStream` without taking //! ownership of the original. use syntax_pos::{BytePos, Span, DUMMY_SP}; @@ -88,7 +88,7 @@ impl Delimited { /// If the syntax extension is an MBE macro, it will attempt to match its /// LHS token tree against the provided token tree, and if it finds a /// match, will transcribe the RHS token tree, splicing in any captured -/// macro_parser::matched_nonterminals into the `SubstNt`s it finds. +/// `macro_parser::matched_nonterminals` into the `SubstNt`s it finds. /// /// The RHS of an MBE macro is the only place `SubstNt`s are substituted. /// Nothing special happens to misnamed or misplaced `SubstNt`s. diff --git a/src/libsyntax/util/lev_distance.rs b/src/libsyntax/util/lev_distance.rs index a6fff2d7074..9307f3c58d4 100644 --- a/src/libsyntax/util/lev_distance.rs +++ b/src/libsyntax/util/lev_distance.rs @@ -53,9 +53,10 @@ pub fn find_best_match_for_name<'a, T>(iter_names: T, iter_names .filter_map(|&name| { let dist = lev_distance(lookup, &name.as_str()); - match dist <= max_dist { // filter the unwanted cases - true => Some((name, dist)), - false => None, + if dist <= max_dist { // filter the unwanted cases + Some((name, dist)) + } else { + None } }) .min_by_key(|&(_, val)| val) // extract the tuple containing the minimum edit distance diff --git a/src/libsyntax/util/move_map.rs b/src/libsyntax/util/move_map.rs index fe05e2958b3..8cc37afa354 100644 --- a/src/libsyntax/util/move_map.rs +++ b/src/libsyntax/util/move_map.rs @@ -37,10 +37,10 @@ impl MoveMap for Vec { // move the read_i'th item out of the vector and map it // to an iterator let e = ptr::read(self.get_unchecked(read_i)); - let mut iter = f(e).into_iter(); + let iter = f(e).into_iter(); read_i += 1; - while let Some(e) = iter.next() { + for e in iter { if write_i < read_i { ptr::write(self.get_unchecked_mut(write_i), e); write_i += 1; @@ -93,10 +93,10 @@ impl MoveMap for SmallVector { // move the read_i'th item out of the vector and map it // to an iterator let e = ptr::read(self.get_unchecked(read_i)); - let mut iter = f(e).into_iter(); + let iter = f(e).into_iter(); read_i += 1; - while let Some(e) = iter.next() { + for e in iter { if write_i < read_i { ptr::write(self.get_unchecked_mut(write_i), e); write_i += 1; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 2e42c6986e6..6e613d1eee7 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -343,9 +343,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) { visitor.visit_ty(ty); visitor.visit_expr(expression) } - TyKind::TraitObject(ref bounds) => { - walk_list!(visitor, visit_ty_param_bound, bounds); - } + TyKind::TraitObject(ref bounds) | TyKind::ImplTrait(ref bounds) => { walk_list!(visitor, visit_ty_param_bound, bounds); } @@ -540,7 +538,7 @@ pub fn walk_fn<'a, V>(visitor: &mut V, kind: FnKind<'a>, declaration: &'a FnDecl walk_fn_decl(visitor, declaration); visitor.visit_block(body); } - FnKind::Method(_, ref sig, _, body) => { + FnKind::Method(_, sig, _, body) => { visitor.visit_generics(&sig.generics); walk_fn_decl(visitor, declaration); visitor.visit_block(body); @@ -776,7 +774,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { } ExprKind::InlineAsm(ref ia) => { for &(_, ref input) in &ia.inputs { - visitor.visit_expr(&input) + visitor.visit_expr(input) } for output in &ia.outputs { visitor.visit_expr(&output.expr) From fa013725556fcf017aabef2e9c19837f45257b28 Mon Sep 17 00:00:00 2001 From: Ivan Dardi Date: Fri, 12 May 2017 15:11:15 -0300 Subject: [PATCH 013/103] Fix commit derp and update implementations and documentation --- src/libcore/iter/iterator.rs | 36 ++++++++++++++++++++++++++++++++++- src/libcore/iter/mod.rs | 37 +++++++++++++++++++++++++++++++++++- src/libcore/tests/iter.rs | 29 +++++++++++++++++++++++++++- src/libcore/tests/lib.rs | 1 + 4 files changed, 100 insertions(+), 3 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index b3f4d75c4da..1277acfb8bb 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -11,7 +11,7 @@ use cmp::Ordering; use super::{Chain, Cycle, Cloned, Enumerate, Filter, FilterMap, FlatMap, Fuse}; -use super::{Inspect, Map, Peekable, Scan, Skip, SkipWhile, Take, TakeWhile, Rev}; +use super::{Inspect, Map, Peekable, Scan, Skip, SkipWhile, StepBy, Take, TakeWhile, Rev}; use super::{Zip, Sum, Product}; use super::{ChainState, FromIterator, ZipImpl}; @@ -258,6 +258,40 @@ pub trait Iterator { None } + /// Creates an iterator starting at the same point, but stepping by + /// the given amount at each iteration. + /// + /// Note that it will always return the first element of the range, + /// regardless of the step given. + /// + /// # Panics + /// + /// If the given step is `0`, the method will panic if debug assertions are + /// enabled. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(iterator_step_by)] + /// let a = [0, 1, 2, 3, 4, 5]; + /// let mut iter = a.into_iter().step_by(2); + /// + /// assert_eq!(iter.next(), Some(&0)); + /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), Some(&4)); + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[unstable(feature = "iterator_step_by", + reason = "unstable replacement of Range::step_by", + issue = "27741")] + fn step_by(self, step: usize) -> StepBy where Self: Sized { + assert!(step != 0); + StepBy{iter: self, step: step - 1, first_take: true} + } + /// Takes two iterators and creates a new iterator over both in sequence. /// /// `chain()` will return a new iterator which will first iterate over diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 273f9d0e6f6..420ff0f7119 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -313,7 +313,7 @@ pub use self::iterator::Iterator; pub use self::range::Step; #[unstable(feature = "step_by", reason = "recent addition", issue = "27741")] -pub use self::range::StepBy; +pub use self::range::StepBy as DeprecatedStepBy; #[stable(feature = "rust1", since = "1.0.0")] pub use self::sources::{Repeat, repeat}; @@ -520,6 +520,41 @@ impl Iterator for Cycle where I: Clone + Iterator { #[unstable(feature = "fused", issue = "35602")] impl FusedIterator for Cycle where I: Clone + Iterator {} +/// An iterator that steps by n elements every iteration. +/// +/// This `struct` is created by the [`step_by`] method on [`Iterator`]. See +/// its documentation for more. +/// +/// [`step_by`]: trait.Iterator.html#method.step_by +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[unstable(feature = "iterator_step_by", + reason = "unstable replacement of Range::step_by", + issue = "27741")] +#[derive(Clone, Debug)] +pub struct StepBy { + iter: I, + step: usize, + first_take: bool, +} + +#[unstable(feature = "iterator_step_by", + reason = "unstable replacement of Range::step_by", + issue = "27741")] +impl Iterator for StepBy where I: Iterator { + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option { + if self.first_take { + self.first_take = false; + self.iter.next() + } else { + self.iter.nth(self.step) + } + } +} + /// An iterator that strings two iterators together. /// /// This `struct` is created by the [`chain`] method on [`Iterator`]. See its diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 001fa304cd0..ad91ba9be58 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -144,6 +144,33 @@ fn test_iterator_chain_find() { assert_eq!(iter.next(), None); } +#[test] +fn test_iterator_step_by() { + // Identity + // Replace with (0..).step_by(1) after Range::step_by gets removed + let mut it = Iterator::step_by((0..), 1).take(3); + assert_eq!(it.next(), Some(0)); + assert_eq!(it.next(), Some(1)); + assert_eq!(it.next(), Some(2)); + assert_eq!(it.next(), None); + + // Replace with (0..).step_by(3) after Range::step_by gets removed + let mut it = Iterator::step_by((0..), 3).take(4); + assert_eq!(it.next(), Some(0)); + assert_eq!(it.next(), Some(3)); + assert_eq!(it.next(), Some(6)); + assert_eq!(it.next(), Some(9)); + assert_eq!(it.next(), None); +} + +#[test] +#[should_panic] +fn test_iterator_step_by_zero() { + // Replace with (0..).step_by(0) after Range::step_by gets removed + let mut it = Iterator::step_by((0..), 0); + it.next(); +} + #[test] fn test_filter_map() { let it = (0..).step_by(1).take(10) @@ -1119,4 +1146,4 @@ fn test_step_replace_no_between() { let y = x.replace_one(); assert_eq!(x, 1); assert_eq!(y, 5); -} \ No newline at end of file +} diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index f0c46a6f194..c52155ead4f 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -20,6 +20,7 @@ #![feature(fixed_size_array)] #![feature(flt2dec)] #![feature(fmt_internals)] +#![feature(iterator_step_by)] #![feature(i128_type)] #![feature(iter_rfind)] #![feature(libc)] From 115854e19c3ab0c9896a388cfff38a8e2cc81113 Mon Sep 17 00:00:00 2001 From: kennytm Date: Fri, 12 May 2017 22:48:46 +0800 Subject: [PATCH 014/103] =?UTF-8?q?Fix=20#35829=20(syntax=20extension's=20?= =?UTF-8?q?`quote=5Fexpr!()`=20does=20not=20handle=20b"=E2=80=A6")?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Handles `b"…"`, `br#"…"#` and `...` for `quote_expr!()`. * Refactored the match statement to allow it to complain loudly on any unhandled token. * Similarly, proc_macro's `quote!()` did not handle `br#"…"#` or `r#"…"#`, so this commit fixes it too. --- src/libproc_macro_plugin/quote.rs | 16 ++++-- src/libsyntax/ext/quote.rs | 56 ++++++++------------- src/test/run-pass-fulldeps/issue-35829.rs | 55 ++++++++++++++++++++ src/test/run-pass-fulldeps/macro-quote-1.rs | 17 ++++++- 4 files changed, 103 insertions(+), 41 deletions(-) create mode 100644 src/test/run-pass-fulldeps/issue-35829.rs diff --git a/src/libproc_macro_plugin/quote.rs b/src/libproc_macro_plugin/quote.rs index ad71584b61a..09675564291 100644 --- a/src/libproc_macro_plugin/quote.rs +++ b/src/libproc_macro_plugin/quote.rs @@ -133,6 +133,14 @@ impl<'a> Quote for &'a str { } } +impl Quote for usize { + fn quote(&self) -> TokenStream { + let integer_symbol = Symbol::intern(&self.to_string()); + TokenTree::Token(DUMMY_SP, Token::Literal(token::Lit::Integer(integer_symbol), None)) + .into() + } +} + impl Quote for Ident { fn quote(&self) -> TokenStream { // FIXME(jseyfried) quote hygiene @@ -193,15 +201,17 @@ impl Quote for token::BinOpToken { impl Quote for Lit { fn quote(&self) -> TokenStream { macro_rules! gen_match { - ($($i:ident),*) => { + ($($i:ident),*; $($raw:ident),*) => { match *self { $( Lit::$i(lit) => quote!(::syntax::parse::token::Lit::$i((quote lit))), )* - _ => panic!("Unsupported literal"), + $( Lit::$raw(lit, n) => { + quote!(::syntax::parse::token::Lit::$raw((quote lit), (quote n))) + })* } } } - gen_match!(Byte, Char, Float, Str_, Integer, ByteStr) + gen_match!(Byte, Char, Float, Str_, Integer, ByteStr; StrRaw, ByteStrRaw) } } diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index d7a85baa3ff..9bc9f66445c 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -612,8 +612,11 @@ fn mk_delim(cx: &ExtCtxt, sp: Span, delim: token::DelimToken) -> P { #[allow(non_upper_case_globals)] fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P { macro_rules! mk_lit { - ($name: expr, $suffix: expr, $($args: expr),*) => {{ - let inner = cx.expr_call(sp, mk_token_path(cx, sp, $name), vec![$($args),*]); + ($name: expr, $suffix: expr, $content: expr $(, $count: expr)*) => {{ + let name = mk_name(cx, sp, ast::Ident::with_empty_ctxt($content)); + let inner = cx.expr_call(sp, mk_token_path(cx, sp, $name), vec![ + name $(, cx.expr_usize(sp, $count))* + ]); let suffix = match $suffix { Some(name) => cx.expr_some(sp, mk_name(cx, sp, ast::Ident::with_empty_ctxt(name))), None => cx.expr_none(sp) @@ -621,7 +624,8 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P { cx.expr_call(sp, mk_token_path(cx, sp, "Literal"), vec![inner, suffix]) }} } - match *tok { + + let name = match *tok { token::BinOp(binop) => { return cx.expr_call(sp, mk_token_path(cx, sp, "BinOp"), vec![mk_binop(cx, sp, binop)]); } @@ -639,34 +643,14 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P { vec![mk_delim(cx, sp, delim)]); } - token::Literal(token::Byte(i), suf) => { - let e_byte = mk_name(cx, sp, ast::Ident::with_empty_ctxt(i)); - return mk_lit!("Byte", suf, e_byte); - } - - token::Literal(token::Char(i), suf) => { - let e_char = mk_name(cx, sp, ast::Ident::with_empty_ctxt(i)); - return mk_lit!("Char", suf, e_char); - } - - token::Literal(token::Integer(i), suf) => { - let e_int = mk_name(cx, sp, ast::Ident::with_empty_ctxt(i)); - return mk_lit!("Integer", suf, e_int); - } - - token::Literal(token::Float(fident), suf) => { - let e_fident = mk_name(cx, sp, ast::Ident::with_empty_ctxt(fident)); - return mk_lit!("Float", suf, e_fident); - } - - token::Literal(token::Str_(ident), suf) => { - return mk_lit!("Str_", suf, mk_name(cx, sp, ast::Ident::with_empty_ctxt(ident))) - } - - token::Literal(token::StrRaw(ident, n), suf) => { - return mk_lit!("StrRaw", suf, mk_name(cx, sp, ast::Ident::with_empty_ctxt(ident)), - cx.expr_usize(sp, n)) - } + token::Literal(token::Byte(i), suf) => return mk_lit!("Byte", suf, i), + token::Literal(token::Char(i), suf) => return mk_lit!("Char", suf, i), + token::Literal(token::Integer(i), suf) => return mk_lit!("Integer", suf, i), + token::Literal(token::Float(i), suf) => return mk_lit!("Float", suf, i), + token::Literal(token::Str_(i), suf) => return mk_lit!("Str_", suf, i), + token::Literal(token::StrRaw(i, n), suf) => return mk_lit!("StrRaw", suf, i, n), + token::Literal(token::ByteStr(i), suf) => return mk_lit!("ByteStr", suf, i), + token::Literal(token::ByteStrRaw(i, n), suf) => return mk_lit!("ByteStrRaw", suf, i, n), token::Ident(ident) => { return cx.expr_call(sp, @@ -688,10 +672,6 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P { token::Interpolated(_) => panic!("quote! with interpolated token"), - _ => () - } - - let name = match *tok { token::Eq => "Eq", token::Lt => "Lt", token::Le => "Le", @@ -706,6 +686,7 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P { token::At => "At", token::Dot => "Dot", token::DotDot => "DotDot", + token::DotDotDot => "DotDotDot", token::Comma => "Comma", token::Semi => "Semi", token::Colon => "Colon", @@ -718,7 +699,10 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P { token::Question => "Question", token::Underscore => "Underscore", token::Eof => "Eof", - _ => panic!("unhandled token in quote!"), + + token::Whitespace | token::SubstNt(_) | token::Comment | token::Shebang(_) => { + panic!("unhandled token in quote!"); + } }; mk_token_path(cx, sp, name) } diff --git a/src/test/run-pass-fulldeps/issue-35829.rs b/src/test/run-pass-fulldeps/issue-35829.rs new file mode 100644 index 00000000000..0a4c15a9236 --- /dev/null +++ b/src/test/run-pass-fulldeps/issue-35829.rs @@ -0,0 +1,55 @@ +// 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. + +// ignore-stage1 +// ignore-cross-compile +#![feature(quote, rustc_private)] + +extern crate syntax; + +use syntax::ext::base::{ExtCtxt, DummyResolver}; +use syntax::ext::expand::ExpansionConfig; +use syntax::parse::ParseSess; +use syntax::codemap::{FilePathMapping, dummy_spanned}; +use syntax::print::pprust::expr_to_string; +use syntax::ast::{Expr, ExprKind, LitKind, StrStyle, RangeLimits}; +use syntax::symbol::Symbol; +use syntax::ptr::P; + +use std::rc::Rc; + +fn main() { + let parse_sess = ParseSess::new(FilePathMapping::empty()); + let exp_cfg = ExpansionConfig::default("issue_35829".to_owned()); + let mut resolver = DummyResolver; + let cx = ExtCtxt::new(&parse_sess, exp_cfg, &mut resolver); + + // check byte string + let byte_string = quote_expr!(&cx, b"one"); + let byte_string_lit_kind = LitKind::ByteStr(Rc::new(b"one".to_vec())); + assert_eq!(byte_string.node, ExprKind::Lit(P(dummy_spanned(byte_string_lit_kind)))); + + // check raw byte string + let raw_byte_string = quote_expr!(&cx, br###"#"two"#"###); + let raw_byte_string_lit_kind = LitKind::ByteStr(Rc::new(b"#\"two\"#".to_vec())); + assert_eq!(raw_byte_string.node, ExprKind::Lit(P(dummy_spanned(raw_byte_string_lit_kind)))); + + // check dotdotdot + let closed_range = quote_expr!(&cx, 0 ... 1); + assert_eq!(closed_range.node, ExprKind::Range( + Some(quote_expr!(&cx, 0)), + Some(quote_expr!(&cx, 1)), + RangeLimits::Closed + )); + + // test case from 35829 + let expr_35829 = quote_expr!(&cx, std::io::stdout().write(b"one")); + assert_eq!(expr_to_string(&expr_35829), r#"std::io::stdout().write(b"one")"#); +} diff --git a/src/test/run-pass-fulldeps/macro-quote-1.rs b/src/test/run-pass-fulldeps/macro-quote-1.rs index 01b0ed80235..e7d0a83017b 100644 --- a/src/test/run-pass-fulldeps/macro-quote-1.rs +++ b/src/test/run-pass-fulldeps/macro-quote-1.rs @@ -17,11 +17,24 @@ extern crate syntax; extern crate syntax_pos; -use syntax::ast::Ident; -use syntax::parse::token; +use syntax::ast::{Ident, Name}; +use syntax::parse::token::{self, Token, Lit}; use syntax::tokenstream::TokenTree; fn main() { let true_tok = token::Ident(Ident::from_str("true")); assert!(quote!(true).eq_unspanned(&true_tok.into())); + + // issue #35829, extended check to proc_macro. + let triple_dot_tok = Token::DotDotDot; + assert!(quote!(...).eq_unspanned(&triple_dot_tok.into())); + + let byte_str_tok = Token::Literal(Lit::ByteStr(Name::intern("one")), None); + assert!(quote!(b"one").eq_unspanned(&byte_str_tok.into())); + + let byte_str_raw_tok = Token::Literal(Lit::ByteStrRaw(Name::intern("#\"two\"#"), 3), None); + assert!(quote!(br###"#"two"#"###).eq_unspanned(&byte_str_raw_tok.into())); + + let str_raw_tok = Token::Literal(Lit::StrRaw(Name::intern("#\"three\"#"), 2), None); + assert!(quote!(r##"#"three"#"##).eq_unspanned(&str_raw_tok.into())); } From df188b8f976a49c226068e42a6c3ae2e15956daf Mon Sep 17 00:00:00 2001 From: est31 Date: Thu, 11 May 2017 10:26:07 +0200 Subject: [PATCH 015/103] Add lint for unused macros --- src/librustc/lint/builtin.rs | 7 +++++++ src/librustc_driver/driver.rs | 2 ++ src/librustc_lint/lib.rs | 3 ++- src/librustc_resolve/lib.rs | 7 +++++++ src/librustc_resolve/macros.rs | 29 +++++++++++++++++++++++++++-- src/libsyntax/ext/base.rs | 6 ++++++ 6 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index e681d55cf94..07140f71aeb 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -76,6 +76,12 @@ declare_lint! { "detects unreachable patterns" } +declare_lint! { + pub UNUSED_MACROS, + Warn, + "detects macros that were not used" +} + declare_lint! { pub WARNINGS, Warn, @@ -259,6 +265,7 @@ impl LintPass for HardwiredLints { DEAD_CODE, UNREACHABLE_CODE, UNREACHABLE_PATTERNS, + UNUSED_MACROS, WARNINGS, UNUSED_FEATURES, STABLE_FEATURES, diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 8fddbe110b0..eff5d2b2f37 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -699,6 +699,8 @@ pub fn phase_2_configure_and_expand(sess: &Session, let krate = ecx.monotonic_expander().expand_crate(krate); + ecx.check_unused_macros(); + let mut missing_fragment_specifiers: Vec<_> = ecx.parse_sess.missing_fragment_specifiers.borrow().iter().cloned().collect(); missing_fragment_specifiers.sort(); diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 2d0b5a6a51c..479c7206cb4 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -171,7 +171,8 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { UNUSED_MUST_USE, UNUSED_UNSAFE, PATH_STATEMENTS, - UNUSED_ATTRIBUTES); + UNUSED_ATTRIBUTES, + UNUSED_MACROS); // Guidelines for creating a future incompatibility lint: // diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index c4512cb38c4..f78dd4890e2 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1195,6 +1195,12 @@ pub struct Resolver<'a> { pub whitelisted_legacy_custom_derives: Vec, pub found_unresolved_macro: bool, + // List of macros that we need to warn about as being unused. + // The bool is true if the macro is unused, and false if its used. + // Setting a bool to false should be much faster than removing a single + // element from a FxHashSet. + unused_macros: FxHashMap, + // Maps the `Mark` of an expansion to its containing module or block. invocations: FxHashMap>, @@ -1400,6 +1406,7 @@ impl<'a> Resolver<'a> { potentially_unused_imports: Vec::new(), struct_constructors: DefIdMap(), found_unresolved_macro: false, + unused_macros: FxHashMap(), } } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index c08421cb937..29ca163b0b4 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -16,7 +16,7 @@ use resolve_imports::ImportResolver; use rustc::hir::def_id::{DefId, BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, DefIndex}; use rustc::hir::def::{Def, Export}; use rustc::hir::map::{self, DefCollector}; -use rustc::ty; +use rustc::{ty, lint}; use syntax::ast::{self, Name, Ident}; use syntax::attr::{self, HasAttrs}; use syntax::errors::DiagnosticBuilder; @@ -291,12 +291,35 @@ impl<'a> base::Resolver for Resolver<'a> { }, }; self.macro_defs.insert(invoc.expansion_data.mark, def.def_id()); + self.unused_macros.get_mut(&def.def_id()).map(|m| *m = false); Ok(Some(self.get_macro(def))) } fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool) -> Result, Determinacy> { - self.resolve_macro_to_def(scope, path, kind, force).map(|def| self.get_macro(def)) + self.resolve_macro_to_def(scope, path, kind, force).map(|def| { + self.unused_macros.get_mut(&def.def_id()).map(|m| *m = false); + self.get_macro(def) + }) + } + + fn check_unused_macros(&self) { + for (did, _) in self.unused_macros.iter().filter(|&(_, b)| *b) { + let span = match *self.macro_map[did] { + SyntaxExtension::NormalTT(_, sp, _) => sp, + SyntaxExtension::IdentTT(_, sp, _) => sp, + _ => None + }; + if let Some(span) = span { + let lint = lint::builtin::UNUSED_MACROS; + let msg = "unused macro".to_string(); + // We are using CRATE_NODE_ID here even though its inaccurate, as we + // sadly don't have the NodeId of the macro definition. + self.session.add_lint(lint, ast::CRATE_NODE_ID, span, msg); + } else { + bug!("attempted to create unused macro error, but span not available"); + } + } } } @@ -687,6 +710,8 @@ impl<'a> Resolver<'a> { if attr::contains_name(&item.attrs, "macro_export") { let def = Def::Macro(def_id, MacroKind::Bang); self.macro_exports.push(Export { name: ident.name, def: def, span: item.span }); + } else { + self.unused_macros.insert(def_id, true); } } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index f731c5abdd6..b0253ec3905 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -589,6 +589,7 @@ pub trait Resolver { -> Result>, Determinacy>; fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool) -> Result, Determinacy>; + fn check_unused_macros(&self); } #[derive(Copy, Clone, Debug)] @@ -618,6 +619,7 @@ impl Resolver for DummyResolver { _force: bool) -> Result, Determinacy> { Err(Determinacy::Determined) } + fn check_unused_macros(&self) {} } #[derive(Clone)] @@ -800,6 +802,10 @@ impl<'a> ExtCtxt<'a> { pub fn name_of(&self, st: &str) -> ast::Name { Symbol::intern(st) } + + pub fn check_unused_macros(&self) { + self.resolver.check_unused_macros(); + } } /// Extract a string literal from the macro expanded version of `expr`, From db82c57cb7ff7f4f629ceeaefdbc693d2886fda7 Mon Sep 17 00:00:00 2001 From: est31 Date: Fri, 12 May 2017 08:05:52 +0200 Subject: [PATCH 016/103] Extend the libsyntax visitor to work over macro defs --- src/libsyntax/visit.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 2e42c6986e6..1855681221b 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -27,6 +27,7 @@ use abi::Abi; use ast::*; use syntax_pos::Span; use codemap::Spanned; +use tokenstream::ThinTokenStream; #[derive(Copy, Clone, PartialEq, Eq)] pub enum FnKind<'a> { @@ -110,6 +111,9 @@ pub trait Visitor<'ast>: Sized { // definition in your trait impl: // visit::walk_mac(self, _mac) } + fn visit_mac_def(&mut self, _mac: &'ast ThinTokenStream, _id: NodeId) { + // Nothing to do + } fn visit_path(&mut self, path: &'ast Path, _id: NodeId) { walk_path(self, path) } @@ -288,7 +292,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { walk_list!(visitor, visit_trait_item, methods); } ItemKind::Mac(ref mac) => visitor.visit_mac(mac), - ItemKind::MacroDef(..) => {}, + ItemKind::MacroDef(ref ts) => visitor.visit_mac_def(ts, item.id), } walk_list!(visitor, visit_attribute, &item.attrs); } From d14d194f61bfd775411c2450e1d939bbb06542b9 Mon Sep 17 00:00:00 2001 From: est31 Date: Fri, 12 May 2017 08:10:52 +0200 Subject: [PATCH 017/103] Support #[allow] etc logic on a per macro level This commit extends the current unused macro linter to support directives like #[allow(unused_macros)] or #[deny(unused_macros)] directly next to the macro definition, or in one of the modules the macro is inside. Before, we only supported such directives at a per crate level, due to the crate's NodeId being passed to session.add_lint. We also had to implement handling of the macro's NodeId in the lint visitor. --- src/librustc/lint/context.rs | 8 ++++++++ src/librustc_plugin/registry.rs | 3 ++- src/librustc_resolve/macros.rs | 13 +++++-------- src/libsyntax/ext/base.rs | 2 +- src/libsyntax/ext/expand.rs | 2 +- src/libsyntax/ext/tt/macro_rules.rs | 6 +++++- 6 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 6f3e84247f7..172b74d5393 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -49,6 +49,7 @@ use hir; use hir::def_id::LOCAL_CRATE; use hir::intravisit as hir_visit; use syntax::visit as ast_visit; +use syntax::tokenstream::ThinTokenStream; /// Information about the registered lints. /// @@ -1125,6 +1126,13 @@ impl<'a> ast_visit::Visitor<'a> for EarlyContext<'a> { fn visit_attribute(&mut self, attr: &'a ast::Attribute) { run_lints!(self, check_attribute, early_passes, attr); } + + fn visit_mac_def(&mut self, _mac: &'a ThinTokenStream, id: ast::NodeId) { + let lints = self.sess.lints.borrow_mut().take(id); + for early_lint in lints { + self.early_lint(&early_lint); + } + } } enum CheckLintNameResult { diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index cdde56f5f63..3027489d65b 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -103,7 +103,8 @@ impl<'a> Registry<'a> { } self.syntax_exts.push((name, match extension { NormalTT(ext, _, allow_internal_unstable) => { - NormalTT(ext, Some(self.krate_span), allow_internal_unstable) + let nid = ast::CRATE_NODE_ID; + NormalTT(ext, Some((nid, self.krate_span)), allow_internal_unstable) } IdentTT(ext, _, allow_internal_unstable) => { IdentTT(ext, Some(self.krate_span), allow_internal_unstable) diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 29ca163b0b4..f6155c6cafd 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -305,17 +305,14 @@ impl<'a> base::Resolver for Resolver<'a> { fn check_unused_macros(&self) { for (did, _) in self.unused_macros.iter().filter(|&(_, b)| *b) { - let span = match *self.macro_map[did] { - SyntaxExtension::NormalTT(_, sp, _) => sp, - SyntaxExtension::IdentTT(_, sp, _) => sp, + let id_span = match *self.macro_map[did] { + SyntaxExtension::NormalTT(_, isp, _) => isp, _ => None }; - if let Some(span) = span { + if let Some((id, span)) = id_span { let lint = lint::builtin::UNUSED_MACROS; - let msg = "unused macro".to_string(); - // We are using CRATE_NODE_ID here even though its inaccurate, as we - // sadly don't have the NodeId of the macro definition. - self.session.add_lint(lint, ast::CRATE_NODE_ID, span, msg); + let msg = "unused macro definition".to_string(); + self.session.add_lint(lint, id, span, msg); } else { bug!("attempted to create unused macro error, but span not available"); } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index b0253ec3905..86202f77dbf 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -535,7 +535,7 @@ pub enum SyntaxExtension { /// /// The `bool` dictates whether the contents of the macro can /// directly use `#[unstable]` things (true == yes). - NormalTT(Box, Option, bool), + NormalTT(Box, Option<(ast::NodeId, Span)>, bool), /// A function-like syntax extension that has an extra ident before /// the block. diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index a8aa103f80a..75dd09f2311 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -469,7 +469,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { call_site: span, callee: NameAndSpan { format: MacroBang(Symbol::intern(&format!("{}", path))), - span: exp_span, + span: exp_span.map(|(_, s)| s), allow_internal_unstable: allow_internal_unstable, }, }); diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index f959ccc989e..0c787dcbecb 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -252,7 +252,11 @@ pub fn compile(sess: &ParseSess, features: &RefCell, def: &ast::Item) valid: valid, }); - NormalTT(exp, Some(def.span), attr::contains_name(&def.attrs, "allow_internal_unstable")) + NormalTT( + exp, + Some((def.id, def.span)), + attr::contains_name(&def.attrs, "allow_internal_unstable") + ) } fn check_lhs_nt_follows(sess: &ParseSess, From ba0601d4b6b3a84cb7e8c2781b71491c17abb910 Mon Sep 17 00:00:00 2001 From: est31 Date: Fri, 12 May 2017 08:21:13 +0200 Subject: [PATCH 018/103] libcore: #[allow] some unused macros --- src/libcore/num/wrapping.rs | 1 + src/libcore/ops.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs index 013f02685ba..6cc374b13b7 100644 --- a/src/libcore/num/wrapping.rs +++ b/src/libcore/num/wrapping.rs @@ -12,6 +12,7 @@ use super::Wrapping; use ops::*; +#[allow(unused_macros)] macro_rules! sh_impl_signed { ($t:ident, $f:ident) => ( #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 391b606f613..ca6438c0fa7 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -763,6 +763,7 @@ macro_rules! neg_impl_numeric { ($($t:ty)*) => { neg_impl_core!{ x => -x, $($t)*} } } +#[allow(unused_macros)] macro_rules! neg_impl_unsigned { ($($t:ty)*) => { neg_impl_core!{ x => { From b36d23c8afeab39df09fa447b37ccb8797861382 Mon Sep 17 00:00:00 2001 From: est31 Date: Fri, 12 May 2017 09:53:58 +0200 Subject: [PATCH 019/103] Add test, and fix the other tests --- .../proc-macro/resolve-error.rs | 1 + ...te-allow-internal-unstable-nested-macro.rs | 2 + .../feature-gate-allow-internal-unstable.rs | 2 + .../compile-fail/invalid-macro-matcher.rs | 2 + src/test/compile-fail/issue-21356.rs | 2 + src/test/compile-fail/issue-39388.rs | 2 + src/test/compile-fail/issue-39404.rs | 1 + src/test/compile-fail/issue-5067.rs | 2 + .../compile-fail/macro-expansion-tests.rs | 2 + src/test/compile-fail/macro-follow.rs | 2 + .../compile-fail/macro-followed-by-seq-bad.rs | 2 + .../macro-input-future-proofing.rs | 2 + src/test/compile-fail/macro-shadowing.rs | 2 + .../unused-macro-with-bad-frag-spec.rs | 2 + .../unused-macro-with-follow-violation.rs | 2 + src/test/compile-fail/unused-macro.rs | 39 +++++++++++++++++++ .../compile-fail/user-defined-macro-rules.rs | 2 + 17 files changed, 69 insertions(+) create mode 100644 src/test/compile-fail/unused-macro.rs diff --git a/src/test/compile-fail-fulldeps/proc-macro/resolve-error.rs b/src/test/compile-fail-fulldeps/proc-macro/resolve-error.rs index e0066dd43be..ddd8631f02e 100644 --- a/src/test/compile-fail-fulldeps/proc-macro/resolve-error.rs +++ b/src/test/compile-fail-fulldeps/proc-macro/resolve-error.rs @@ -14,6 +14,7 @@ // aux-build:bang_proc_macro.rs #![feature(proc_macro)] +#![allow(unused_macros)] #[macro_use] extern crate derive_foo; diff --git a/src/test/compile-fail/feature-gate-allow-internal-unstable-nested-macro.rs b/src/test/compile-fail/feature-gate-allow-internal-unstable-nested-macro.rs index 1aabe6b87df..9af501b1419 100644 --- a/src/test/compile-fail/feature-gate-allow-internal-unstable-nested-macro.rs +++ b/src/test/compile-fail/feature-gate-allow-internal-unstable-nested-macro.rs @@ -10,6 +10,8 @@ // gate-test-allow_internal_unstable +#![allow(unused_macros)] + macro_rules! bar { () => { // more layers don't help: diff --git a/src/test/compile-fail/feature-gate-allow-internal-unstable.rs b/src/test/compile-fail/feature-gate-allow-internal-unstable.rs index 8a2d8dddac0..61a362cb37f 100644 --- a/src/test/compile-fail/feature-gate-allow-internal-unstable.rs +++ b/src/test/compile-fail/feature-gate-allow-internal-unstable.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(unused_macros)] + #[allow_internal_unstable] //~ ERROR allow_internal_unstable side-steps macro_rules! foo { () => {} diff --git a/src/test/compile-fail/invalid-macro-matcher.rs b/src/test/compile-fail/invalid-macro-matcher.rs index a0ac5d4c720..d710f5647dd 100644 --- a/src/test/compile-fail/invalid-macro-matcher.rs +++ b/src/test/compile-fail/invalid-macro-matcher.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(unused_macros)] + macro_rules! invalid { _ => (); //~ ERROR invalid macro matcher } diff --git a/src/test/compile-fail/issue-21356.rs b/src/test/compile-fail/issue-21356.rs index fefd432e229..f66c09291cc 100644 --- a/src/test/compile-fail/issue-21356.rs +++ b/src/test/compile-fail/issue-21356.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(unused_macros)] + macro_rules! test { ($wrong:t_ty ..) => () } //~^ ERROR: invalid fragment specifier `t_ty` diff --git a/src/test/compile-fail/issue-39388.rs b/src/test/compile-fail/issue-39388.rs index 6994d2199d2..15eef429eab 100644 --- a/src/test/compile-fail/issue-39388.rs +++ b/src/test/compile-fail/issue-39388.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(unused_macros)] + macro_rules! assign { (($($a:tt)*) = ($($b:tt))*) => { //~ ERROR expected `*` or `+` $($a)* = $($b)* diff --git a/src/test/compile-fail/issue-39404.rs b/src/test/compile-fail/issue-39404.rs index 0168ae7d910..8b49772494a 100644 --- a/src/test/compile-fail/issue-39404.rs +++ b/src/test/compile-fail/issue-39404.rs @@ -9,6 +9,7 @@ // except according to those terms. #![deny(missing_fragment_specifier)] //~ NOTE lint level defined here +#![allow(unused_macros)] macro_rules! m { ($i) => {} } //~^ ERROR missing fragment specifier diff --git a/src/test/compile-fail/issue-5067.rs b/src/test/compile-fail/issue-5067.rs index 1c543a5fdac..267362f902d 100644 --- a/src/test/compile-fail/issue-5067.rs +++ b/src/test/compile-fail/issue-5067.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(unused_macros)] + macro_rules! foo { ( $()* ) => {}; //~^ ERROR repetition matches empty token tree diff --git a/src/test/compile-fail/macro-expansion-tests.rs b/src/test/compile-fail/macro-expansion-tests.rs index ada06b0b3f4..06f2d86e5d9 100644 --- a/src/test/compile-fail/macro-expansion-tests.rs +++ b/src/test/compile-fail/macro-expansion-tests.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(unused_macros)] + mod macros_cant_escape_fns { fn f() { macro_rules! m { () => { 3 + 4 } } diff --git a/src/test/compile-fail/macro-follow.rs b/src/test/compile-fail/macro-follow.rs index 001bc42274b..6e80e9b574b 100644 --- a/src/test/compile-fail/macro-follow.rs +++ b/src/test/compile-fail/macro-follow.rs @@ -10,6 +10,8 @@ // // Check the macro follow sets (see corresponding rpass test). +#![allow(unused_macros)] + // FOLLOW(pat) = {FatArrow, Comma, Eq, Or, Ident(if), Ident(in)} macro_rules! follow_pat { ($p:pat ()) => {}; //~ERROR `$p:pat` is followed by `(` diff --git a/src/test/compile-fail/macro-followed-by-seq-bad.rs b/src/test/compile-fail/macro-followed-by-seq-bad.rs index 0ee2221bbc1..21cc946ded6 100644 --- a/src/test/compile-fail/macro-followed-by-seq-bad.rs +++ b/src/test/compile-fail/macro-followed-by-seq-bad.rs @@ -11,6 +11,8 @@ // Regression test for issue #25436: check that things which can be // followed by any token also permit X* to come afterwards. +#![allow(unused_macros)] + macro_rules! foo { ( $a:expr $($b:tt)* ) => { }; //~ ERROR not allowed for `expr` fragments ( $a:ty $($b:tt)* ) => { }; //~ ERROR not allowed for `ty` fragments diff --git a/src/test/compile-fail/macro-input-future-proofing.rs b/src/test/compile-fail/macro-input-future-proofing.rs index fe758a4a631..e5fdba63b0f 100644 --- a/src/test/compile-fail/macro-input-future-proofing.rs +++ b/src/test/compile-fail/macro-input-future-proofing.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(unused_macros)] + macro_rules! errors_everywhere { ($ty:ty <) => (); //~ ERROR `$ty:ty` is followed by `<`, which is not allowed for `ty` ($ty:ty < foo ,) => (); //~ ERROR `$ty:ty` is followed by `<`, which is not allowed for `ty` diff --git a/src/test/compile-fail/macro-shadowing.rs b/src/test/compile-fail/macro-shadowing.rs index 8381dc34a6a..f5e7305e4ea 100644 --- a/src/test/compile-fail/macro-shadowing.rs +++ b/src/test/compile-fail/macro-shadowing.rs @@ -10,6 +10,8 @@ // aux-build:two_macros.rs +#![allow(unused_macros)] + macro_rules! foo { () => {} } macro_rules! macro_one { () => {} } #[macro_use(macro_two)] extern crate two_macros; diff --git a/src/test/compile-fail/unused-macro-with-bad-frag-spec.rs b/src/test/compile-fail/unused-macro-with-bad-frag-spec.rs index b868b79365d..28a69e6f9e2 100644 --- a/src/test/compile-fail/unused-macro-with-bad-frag-spec.rs +++ b/src/test/compile-fail/unused-macro-with-bad-frag-spec.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(unused_macros)] + // Issue #21370 macro_rules! test { diff --git a/src/test/compile-fail/unused-macro-with-follow-violation.rs b/src/test/compile-fail/unused-macro-with-follow-violation.rs index e9d09bb6ad9..dda0d3fc955 100644 --- a/src/test/compile-fail/unused-macro-with-follow-violation.rs +++ b/src/test/compile-fail/unused-macro-with-follow-violation.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(unused_macros)] + macro_rules! test { ($e:expr +) => () //~ ERROR not allowed for `expr` fragments } diff --git a/src/test/compile-fail/unused-macro.rs b/src/test/compile-fail/unused-macro.rs new file mode 100644 index 00000000000..5e401c09bda --- /dev/null +++ b/src/test/compile-fail/unused-macro.rs @@ -0,0 +1,39 @@ +// 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. + +#![deny(unused_macros)] + +// Most simple case +macro_rules! unused { //~ ERROR: unused macro definition + () => {}; +} + +// Test macros created by macros +macro_rules! create_macro { + () => { + macro_rules! m { //~ ERROR: unused macro definition + () => {}; + } + }; +} +create_macro!(); + +#[allow(unused_macros)] +mod bar { + // Test that putting the #[deny] close to the macro's definition + // works. + + #[deny(unused_macros)] + macro_rules! unused { //~ ERROR: unused macro definition + () => {}; + } +} + +fn main() {} diff --git a/src/test/compile-fail/user-defined-macro-rules.rs b/src/test/compile-fail/user-defined-macro-rules.rs index d55cef434f8..02e1a585fa8 100644 --- a/src/test/compile-fail/user-defined-macro-rules.rs +++ b/src/test/compile-fail/user-defined-macro-rules.rs @@ -8,4 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(unused_macros)] + macro_rules! macro_rules { () => {} } //~ ERROR user-defined macros may not be named `macro_rules` From 94d2c43300148d5c0ea8c93cedb94151953dcf83 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sat, 13 May 2017 08:21:24 -0500 Subject: [PATCH 020/103] add -Z pre-link-arg{,s} to rustc This commit adds two unstable flags to `rustc`: `-Z pre-link-arg` and `-Z pre-link-args`. These are the counterpart of the existing `-C link-arg{,s}` flags and can be used to pass extra arguments at the *beginning* of the linker invocation, before the Rust object files are passed. --- src/librustc/session/config.rs | 8 ++++++-- src/librustc_trans/back/link.rs | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 884a71f0d32..79bb20599ca 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -824,9 +824,9 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, linker: Option = (None, parse_opt_string, [UNTRACKED], "system linker to link outputs with"), link_arg: Vec = (vec![], parse_string_push, [UNTRACKED], - "a single extra argument to pass to the linker (can be used several times)"), + "a single extra argument to append to the linker invocation (can be used several times)"), link_args: Option> = (None, parse_opt_list, [UNTRACKED], - "extra arguments to pass to the linker (space separated)"), + "extra arguments to append to the linker invocation (space separated)"), link_dead_code: bool = (false, parse_bool, [UNTRACKED], "don't let linker strip dead code (turning it on can be used for code coverage)"), lto: bool = (false, parse_bool, [TRACKED], @@ -1029,6 +1029,10 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "add a mapping target to the file path remapping config"), force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED], "force all crates to be `rustc_private` unstable"), + pre_link_arg: Vec = (vec![], parse_string_push, [UNTRACKED], + "a single extra argument to prepend the linker invocation (can be used several times)"), + pre_link_args: Option> = (None, parse_opt_list, [UNTRACKED], + "extra arguments to prepend to the linker invocation (space separated)"), } pub fn default_lib_output() -> CrateType { diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index e42e69d2a76..d1000a574b5 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -714,6 +714,10 @@ fn link_natively(sess: &Session, if let Some(args) = sess.target.target.options.pre_link_args.get(&flavor) { cmd.args(args); } + if let Some(ref args) = sess.opts.debugging_opts.pre_link_args { + cmd.args(args); + } + cmd.args(&sess.opts.debugging_opts.pre_link_arg); let pre_link_objects = if crate_type == config::CrateTypeExecutable { &sess.target.target.options.pre_link_objects_exe From 0d0cb2796b99ea72fefd7d5759e097a6c529274a Mon Sep 17 00:00:00 2001 From: est31 Date: Sun, 14 May 2017 05:06:21 +0200 Subject: [PATCH 021/103] librustc_incremental: remove unused macro in test case --- .../persist/preds/compress/test_macro.rs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/librustc_incremental/persist/preds/compress/test_macro.rs b/src/librustc_incremental/persist/preds/compress/test_macro.rs index 31b30d2b285..044b143e306 100644 --- a/src/librustc_incremental/persist/preds/compress/test_macro.rs +++ b/src/librustc_incremental/persist/preds/compress/test_macro.rs @@ -37,14 +37,3 @@ macro_rules! graph { } } } - -macro_rules! set { - ($( $value:expr ),*) => { - { - use $crate::rustc_data_structures::fx::FxHashSet; - let mut set = FxHashSet(); - $(set.insert($value);)* - set - } - } -} From a9cb094879fabd23774a0d9dcfed7f3eeb9a4aff Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Sat, 13 May 2017 21:42:51 +0200 Subject: [PATCH 022/103] Explain why `thread::yield_now` could be used. Part of #29378. --- src/libstd/thread/mod.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 200368be275..8f1a88ed305 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -468,6 +468,23 @@ pub fn current() -> Thread { /// Cooperatively gives up a timeslice to the OS scheduler. /// +/// This is used when the programmer knows that the thread will have nothing +/// to do for some time, and thus avoid wasting computing time. +/// +/// For example when polling on a resource, it is common to check that it is +/// available, and if not to yield in order to avoid busy waiting. +/// +/// Thus the pattern of `yield`ing after a failed poll is rather common when +/// implementing low-level shared resources or synchronization primitives. +/// +/// However programmers will usualy prefer to use, [`channel`]s, [`Condvar`]s, +/// [`Mutex`]es or [`join`] for their synchronisation routines, as they avoid +/// thinking about thread schedulling. +/// +/// Note that [`channel`]s for example are implemented using this primitive. +/// Indeed when you call `send` or `recv`, which are blocking, they will yield +/// if the channel is not available. +/// /// # Examples /// /// ``` @@ -475,6 +492,12 @@ pub fn current() -> Thread { /// /// thread::yield_now(); /// ``` +/// +/// [`channel`]: ../../std/sync/mpsc/index.html +/// [`spawn`]: ../../std/thread/fn.spawn.html +/// [`join`]: ../../std/thread/struct.JoinHandle.html#method.join +/// [`Mutex`]: ../../std/sync/struct.Mutex.html +/// [`Condvar`]: ../../std/sync/struct.Condvar.html #[stable(feature = "rust1", since = "1.0.0")] pub fn yield_now() { imp::Thread::yield_now() From 21ca9cab7d3a91379005546ac6b0e8c4118e0f34 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Sun, 14 May 2017 17:56:24 +0100 Subject: [PATCH 023/103] Fix some dead links in The Unstable Book --- .../src/language-features/advanced-slice-patterns.md | 2 +- src/doc/unstable-book/src/language-features/asm.md | 2 +- src/doc/unstable-book/src/language-features/box-patterns.md | 2 +- src/doc/unstable-book/src/language-features/box-syntax.md | 2 +- src/doc/unstable-book/src/language-features/global_asm.md | 4 ++-- .../unstable-book/src/language-features/plugin-registrar.md | 2 +- src/doc/unstable-book/src/language-features/plugin.md | 2 +- src/doc/unstable-book/src/language-features/slice-patterns.md | 3 ++- src/doc/unstable-book/src/library-features/alloc-jemalloc.md | 2 +- src/doc/unstable-book/src/library-features/alloc-system.md | 2 +- 10 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/advanced-slice-patterns.md b/src/doc/unstable-book/src/language-features/advanced-slice-patterns.md index 30d22ca8208..e8256469b14 100644 --- a/src/doc/unstable-book/src/language-features/advanced-slice-patterns.md +++ b/src/doc/unstable-book/src/language-features/advanced-slice-patterns.md @@ -4,7 +4,7 @@ The tracking issue for this feature is: [#23121] [#23121]: https://github.com/rust-lang/rust/issues/23121 -See also [`slice_patterns`](slice-patterns.html). +See also [`slice_patterns`](language-features/slice-patterns.html). ------------------------ diff --git a/src/doc/unstable-book/src/language-features/asm.md b/src/doc/unstable-book/src/language-features/asm.md index 5e68be633e7..8deb8f46256 100644 --- a/src/doc/unstable-book/src/language-features/asm.md +++ b/src/doc/unstable-book/src/language-features/asm.md @@ -190,4 +190,4 @@ constraints, etc. [llvm-docs]: http://llvm.org/docs/LangRef.html#inline-assembler-expressions If you need more power and don't mind losing some of the niceties of -`asm!`, check out [global_asm](global_asm.html). +`asm!`, check out [global_asm](language-features/global_asm.html). diff --git a/src/doc/unstable-book/src/language-features/box-patterns.md b/src/doc/unstable-book/src/language-features/box-patterns.md index 86346364a71..0896627acae 100644 --- a/src/doc/unstable-book/src/language-features/box-patterns.md +++ b/src/doc/unstable-book/src/language-features/box-patterns.md @@ -4,7 +4,7 @@ The tracking issue for this feature is: [#29641] [#29641]: https://github.com/rust-lang/rust/issues/29641 -See also [`box_syntax`](box-syntax.html) +See also [`box_syntax`](language-features/box-syntax.html) ------------------------ diff --git a/src/doc/unstable-book/src/language-features/box-syntax.md b/src/doc/unstable-book/src/language-features/box-syntax.md index 47aade0d045..50e59231a4d 100644 --- a/src/doc/unstable-book/src/language-features/box-syntax.md +++ b/src/doc/unstable-book/src/language-features/box-syntax.md @@ -4,7 +4,7 @@ The tracking issue for this feature is: [#27779] [#27779]: https://github.com/rust-lang/rust/issues/27779 -See also [`box_patterns`](box-patterns.html) +See also [`box_patterns`](language-features/box-patterns.html) ------------------------ diff --git a/src/doc/unstable-book/src/language-features/global_asm.md b/src/doc/unstable-book/src/language-features/global_asm.md index 44921aa309f..f1ef74a63b5 100644 --- a/src/doc/unstable-book/src/language-features/global_asm.md +++ b/src/doc/unstable-book/src/language-features/global_asm.md @@ -74,5 +74,5 @@ usages and placed the larger, single usage in the crate root. If you don't need quite as much power and flexibility as `global_asm!` provides, and you don't mind restricting your inline -assembly to `fn` bodies only, you might try the [asm](asm.html) -feature instead. +assembly to `fn` bodies only, you might try the +[asm](language-features/asm.html) feature instead. diff --git a/src/doc/unstable-book/src/language-features/plugin-registrar.md b/src/doc/unstable-book/src/language-features/plugin-registrar.md index ca3738bd93f..b16e2ac2d22 100644 --- a/src/doc/unstable-book/src/language-features/plugin-registrar.md +++ b/src/doc/unstable-book/src/language-features/plugin-registrar.md @@ -8,6 +8,6 @@ This feature is part of "compiler plugins." It will often be used with the [`plugin`] and `rustc_private` features as well. For more details, see their docs. -[`plugin`]: plugin.html +[`plugin`]: language-features/plugin.html ------------------------ diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md index 3a1872e18dd..4b8603e3c44 100644 --- a/src/doc/unstable-book/src/language-features/plugin.md +++ b/src/doc/unstable-book/src/language-features/plugin.md @@ -8,7 +8,7 @@ The tracking issue for this feature is: [#29597] This feature is part of "compiler plugins." It will often be used with the [`plugin_registrar`] and `rustc_private` features. -[`plugin_registrar`]: plugin-registrar.html +[`plugin_registrar`]: language-features/plugin-registrar.html ------------------------ diff --git a/src/doc/unstable-book/src/language-features/slice-patterns.md b/src/doc/unstable-book/src/language-features/slice-patterns.md index 1e9e1eaafda..69857297582 100644 --- a/src/doc/unstable-book/src/language-features/slice-patterns.md +++ b/src/doc/unstable-book/src/language-features/slice-patterns.md @@ -4,7 +4,8 @@ The tracking issue for this feature is: [#23121] [#23121]: https://github.com/rust-lang/rust/issues/23121 -See also [`advanced_slice_patterns`](advanced-slice-patterns.html). +See also +[`advanced_slice_patterns`](language-features/advanced-slice-patterns.html). ------------------------ diff --git a/src/doc/unstable-book/src/library-features/alloc-jemalloc.md b/src/doc/unstable-book/src/library-features/alloc-jemalloc.md index 9bffa2ff99b..18ff838dd32 100644 --- a/src/doc/unstable-book/src/library-features/alloc-jemalloc.md +++ b/src/doc/unstable-book/src/library-features/alloc-jemalloc.md @@ -4,7 +4,7 @@ The tracking issue for this feature is: [#33082] [#33082]: https://github.com/rust-lang/rust/issues/33082 -See also [`alloc_system`](alloc-system.html). +See also [`alloc_system`](library-features/alloc-system.html). ------------------------ diff --git a/src/doc/unstable-book/src/library-features/alloc-system.md b/src/doc/unstable-book/src/library-features/alloc-system.md index 6fa89179d8e..1d261db6ba1 100644 --- a/src/doc/unstable-book/src/library-features/alloc-system.md +++ b/src/doc/unstable-book/src/library-features/alloc-system.md @@ -4,7 +4,7 @@ The tracking issue for this feature is: [#33082] [#33082]: https://github.com/rust-lang/rust/issues/33082 -See also [`alloc_jemalloc`](alloc-jemalloc.html). +See also [`alloc_jemalloc`](library-features/alloc-jemalloc.html). ------------------------ From d4f20eb7e32bad9049663d30cfcb0e246ef2e031 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Sun, 14 May 2017 17:57:59 +0100 Subject: [PATCH 024/103] linkchecker: Add support for tag Add support for the HTML tag as used by mdBook so The Unstable Book can be checked. Also cleanup a few things: * Stop checking the name attribute. It should never have been used and mdBook has since been fixed not to use it. * Make sure we only check html files. * Remove a few unnecessary allocations. Finally, dead links in The Unstable Book have been fixed. --- src/tools/linkchecker/main.rs | 89 +++++++++++++---------------------- 1 file changed, 33 insertions(+), 56 deletions(-) diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 3d9a4fba6cd..1b55dc792c2 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -41,7 +41,7 @@ macro_rules! t { } fn main() { - let docs = env::args().nth(1).unwrap(); + let docs = env::args_os().nth(1).unwrap(); let docs = env::current_dir().unwrap().join(docs); let mut errors = false; walk(&mut HashMap::new(), &docs, &docs, &mut errors); @@ -65,7 +65,6 @@ enum Redirect { struct FileEntry { source: String, ids: HashSet, - names: HashSet, } type Cache = HashMap; @@ -73,7 +72,7 @@ type Cache = HashMap; impl FileEntry { fn parse_ids(&mut self, file: &Path, contents: &str, errors: &mut bool) { if self.ids.is_empty() { - with_attrs_in_source(contents, " id", |fragment, i| { + with_attrs_in_source(contents, " id", |fragment, i, _| { let frag = fragment.trim_left_matches("#").to_owned(); if !self.ids.insert(frag) { *errors = true; @@ -82,15 +81,6 @@ impl FileEntry { }); } } - - fn parse_names(&mut self, contents: &str) { - if self.names.is_empty() { - with_attrs_in_source(contents, " name", |fragment, _| { - let frag = fragment.trim_left_matches("#").to_owned(); - self.names.insert(frag); - }); - } - } } fn walk(cache: &mut Cache, root: &Path, dir: &Path, errors: &mut bool) { @@ -116,15 +106,8 @@ fn check(cache: &mut Cache, file: &Path, errors: &mut bool) -> Option { - // ignore js files as they are not prone to errors as the rest of the - // documentation is and they otherwise bring up false positives. - if file.extension().and_then(|s| s.to_str()) == Some("js") { - return None; - } - - // ignore handlebars files as they use {{}} to build links, we only - // want to test the generated files - if file.extension().and_then(|s| s.to_str()) == Some("hbs") { + // Ignore none HTML files. + if file.extension().and_then(|s| s.to_str()) != Some("html") { return None; } @@ -147,13 +130,7 @@ fn check(cache: &mut Cache, return None; } - // mdbook uses the HTML tag to handle links for subdirectories, which - // linkchecker doesn't support - if file.to_str().unwrap().contains("unstable-book") { - return None; - } - - let res = load_file(cache, root, PathBuf::from(file), SkipRedirect); + let res = load_file(cache, root, file, SkipRedirect); let (pretty_file, contents) = match res { Ok(res) => res, Err(_) => return None, @@ -162,13 +139,10 @@ fn check(cache: &mut Cache, cache.get_mut(&pretty_file) .unwrap() .parse_ids(&pretty_file, &contents, errors); - cache.get_mut(&pretty_file) - .unwrap() - .parse_names(&contents); } // Search for anything that's the regex 'href[ ]*=[ ]*".*?"' - with_attrs_in_source(&contents, " href", |url, i| { + with_attrs_in_source(&contents, " href", |url, i, base| { // Ignore external URLs if url.starts_with("http:") || url.starts_with("https:") || url.starts_with("javascript:") || url.starts_with("ftp:") || @@ -184,9 +158,9 @@ fn check(cache: &mut Cache, // Once we've plucked out the URL, parse it using our base url and // then try to extract a file path. let mut path = file.to_path_buf(); - if !url.is_empty() { + if !base.is_empty() || !url.is_empty() { path.pop(); - for part in Path::new(url).components() { + for part in Path::new(base).join(url).components() { match part { Component::Prefix(_) | Component::RootDir => panic!(), @@ -197,13 +171,6 @@ fn check(cache: &mut Cache, } } - if let Some(extension) = path.extension() { - // don't check these files - if extension == "png" { - return; - } - } - // Alright, if we've found a file name then this file had better // exist! If it doesn't then we register and print an error. if path.exists() { @@ -218,11 +185,17 @@ fn check(cache: &mut Cache, pretty_path.display()); return; } - let res = load_file(cache, root, path.clone(), FromRedirect(false)); + if let Some(extension) = path.extension() { + // Ignore none HTML files. + if extension != "html" { + return; + } + } + let res = load_file(cache, root, &path, FromRedirect(false)); let (pretty_path, contents) = match res { Ok(res) => res, Err(LoadError::IOError(err)) => { - panic!(format!("error loading {}: {}", path.display(), err)); + panic!("error loading {}: {}", path.display(), err); } Err(LoadError::BrokenRedirect(target, _)) => { *errors = true; @@ -245,11 +218,10 @@ fn check(cache: &mut Cache, let entry = &mut cache.get_mut(&pretty_path).unwrap(); entry.parse_ids(&pretty_path, &contents, errors); - entry.parse_names(&contents); - if !(entry.ids.contains(*fragment) || entry.names.contains(*fragment)) { + if !entry.ids.contains(*fragment) { *errors = true; - print!("{}:{}: broken link fragment ", + print!("{}:{}: broken link fragment ", pretty_file.display(), i + 1); println!("`#{}` pointing to `{}`", fragment, pretty_path.display()); @@ -267,7 +239,7 @@ fn check(cache: &mut Cache, fn load_file(cache: &mut Cache, root: &Path, - mut file: PathBuf, + file: &Path, redirect: Redirect) -> Result<(PathBuf, String), LoadError> { let mut contents = String::new(); @@ -279,9 +251,9 @@ fn load_file(cache: &mut Cache, None } Entry::Vacant(entry) => { - let mut fp = File::open(file.clone()).map_err(|err| { + let mut fp = File::open(file).map_err(|err| { if let FromRedirect(true) = redirect { - LoadError::BrokenRedirect(file.clone(), err) + LoadError::BrokenRedirect(file.to_path_buf(), err) } else { LoadError::IOError(err) } @@ -297,17 +269,14 @@ fn load_file(cache: &mut Cache, entry.insert(FileEntry { source: contents.clone(), ids: HashSet::new(), - names: HashSet::new(), }); } maybe } }; - file.pop(); - match maybe_redirect.map(|url| file.join(url)) { + match maybe_redirect.map(|url| file.parent().unwrap().join(url)) { Some(redirect_file) => { - let path = PathBuf::from(redirect_file); - load_file(cache, root, path, FromRedirect(true)) + load_file(cache, root, &redirect_file, FromRedirect(true)) } None => Ok((pretty_file, contents)), } @@ -329,10 +298,14 @@ fn maybe_redirect(source: &str) -> Option { }) } -fn with_attrs_in_source(contents: &str, attr: &str, mut f: F) { +fn with_attrs_in_source(contents: &str, attr: &str, mut f: F) { + let mut base = ""; for (i, mut line) in contents.lines().enumerate() { while let Some(j) = line.find(attr) { let rest = &line[j + attr.len()..]; + // The base tag should always be the first link in the document so + // we can get away with using one pass. + let is_base = line[..j].ends_with(" Builder { Builder { @@ -280,9 +305,10 @@ impl Builder { self } - /// Spawns a new thread, and returns a join handle for it. + /// Spawns a new thread by taking ownership of the `Builder`, and returns an + /// [`io::Result`] to its [`JoinHandle`]. /// - /// The child thread may outlive the parent (unless the parent thread + /// The spawned thread may outlive the caller (unless the caller thread /// is the main thread; the whole process is terminated when the main /// thread finishes). The join handle can be used to block on /// termination of the child thread, including recovering its panics. @@ -297,6 +323,7 @@ impl Builder { /// /// [`spawn`]: ../../std/thread/fn.spawn.html /// [`io::Result`]: ../../std/io/type.Result.html + /// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html /// /// # Examples /// From 1a24a591dd43c53de7e3f16eff9f67469cf7a52b Mon Sep 17 00:00:00 2001 From: Robin Kruppe Date: Wed, 26 Apr 2017 23:22:45 +0200 Subject: [PATCH 026/103] Remove rustc_llvm dependency from rustc_metadata Move the code for loading metadata from rlibs and dylibs from rustc_metadata into rustc_trans, and introduce a trait to avoid introducing a direct dependency on rustc_trans. This means rustc_metadata is no longer rebuilt when LLVM changes. --- src/Cargo.lock | 19 ++- src/librustc/Cargo.toml | 1 + src/librustc/lib.rs | 1 + src/librustc/middle/cstore.rs | 32 +++- src/librustc_driver/lib.rs | 10 +- src/librustc_driver/test.rs | 3 +- src/librustc_metadata/Cargo.toml | 2 +- src/librustc_metadata/creader.rs | 2 + src/librustc_metadata/cstore.rs | 15 +- src/librustc_metadata/cstore_impl.rs | 21 +-- src/librustc_metadata/decoder.rs | 6 +- src/librustc_metadata/lib.rs | 2 +- src/librustc_metadata/locator.rs | 225 ++++++++------------------- src/librustc_trans/Cargo.toml | 1 + src/librustc_trans/back/archive.rs | 5 +- src/librustc_trans/back/link.rs | 9 +- src/librustc_trans/base.rs | 4 +- src/librustc_trans/lib.rs | 4 + src/librustc_trans/metadata.rs | 122 +++++++++++++++ src/librustdoc/core.rs | 3 +- src/librustdoc/test.rs | 5 +- src/test/run-make/issue-19371/foo.rs | 3 +- 22 files changed, 276 insertions(+), 219 deletions(-) create mode 100644 src/librustc_trans/metadata.rs diff --git a/src/Cargo.lock b/src/Cargo.lock index 776a268aa8d..bd9fda42570 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -316,6 +316,14 @@ name = "open" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "owning_ref" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "panic_abort" version = "0.0.0" @@ -442,6 +450,7 @@ dependencies = [ "fmt_macros 0.0.0", "graphviz 0.0.0", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_back 0.0.0", "rustc_bitflags 0.0.0", "rustc_const_math 0.0.0", @@ -626,13 +635,13 @@ version = "0.0.0" dependencies = [ "flate 0.0.0", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "proc_macro 0.0.0", "rustc 0.0.0", "rustc_back 0.0.0", "rustc_const_math 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", - "rustc_llvm 0.0.0", "serialize 0.0.0", "syntax 0.0.0", "syntax_ext 0.0.0", @@ -734,6 +743,7 @@ version = "0.0.0" dependencies = [ "flate 0.0.0", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_back 0.0.0", "rustc_bitflags 0.0.0", @@ -820,6 +830,11 @@ dependencies = [ name = "serialize" version = "0.0.0" +[[package]] +name = "stable_deref_trait" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "std" version = "0.0.0" @@ -1015,6 +1030,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99" "checksum num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca313f1862c7ec3e0dfe8ace9fa91b1d9cb5c84ace3d00f5ec4216238e93c167" "checksum open 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3478ed1686bd1300c8a981a940abc92b06fac9cbef747f4c668d4e032ff7b842" +"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6dda33d67c26f0aac90d324ab2eb7239c819fc7b2552fe9faa4fe88441edc8" "checksum pulldown-cmark 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9ab1e588ef8efd702c7ed9d2bd774db5e6f4d878bb5a1a9f371828fbdff6973" "checksum pulldown-cmark 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1058d7bb927ca067656537eec4e02c2b4b70eaaa129664c5b90c111e20326f41" @@ -1026,6 +1042,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "684ce48436d6465300c9ea783b6b14c4361d6b8dcbb1375b486a69cc19e2dfb0" "checksum serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "a702319c807c016e51f672e5c77d6f0b46afddd744b5e437d6b8436b888b458f" "checksum serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "dbc45439552eb8fb86907a2c41c1fd0ef97458efb87ff7f878db466eb581824e" +"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" "checksum term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "07b6c1ac5b3fffd75073276bca1ceed01f67a28537097a2a9539e116e50fb21a" "checksum thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4437c97558c70d129e40629a5b385b3fb1ffac301e63941335e4d354081ec14a" diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index fa217acd9f9..3c762e43e9a 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -13,6 +13,7 @@ arena = { path = "../libarena" } fmt_macros = { path = "../libfmt_macros" } graphviz = { path = "../libgraphviz" } log = "0.3" +owning_ref = "0.3.3" rustc_back = { path = "../librustc_back" } rustc_bitflags = { path = "../librustc_bitflags" } rustc_const_math = { path = "../librustc_const_math" } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 5cf26ea8bfc..c979677ff71 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -54,6 +54,7 @@ extern crate fmt_macros; extern crate getopts; extern crate graphviz; extern crate libc; +extern crate owning_ref; extern crate rustc_llvm as llvm; extern crate rustc_back; extern crate rustc_data_structures; diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 569b1aeeb09..a68aca46000 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -36,8 +36,9 @@ use session::search_paths::PathKind; use util::nodemap::{NodeSet, DefIdMap}; use std::any::Any; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::rc::Rc; +use owning_ref::ErasedBoxRef; use syntax::ast; use syntax::ext::base::SyntaxExtension; use syntax::symbol::Symbol; @@ -201,11 +202,33 @@ impl EncodedMetadataHashes { } } +/// The backend's way to give the crate store access to the metadata in a library. +/// Note that it returns the raw metadata bytes stored in the library file, whether +/// it is compressed, uncompressed, some weird mix, etc. +/// rmeta files are backend independent and not handled here. +/// +/// At the time of this writing, there is only one backend and one way to store +/// metadata in library -- this trait just serves to decouple rustc_metadata from +/// the archive reader, which depends on LLVM. +pub trait MetadataLoader { + fn get_rlib_metadata(&self, + target: &Target, + filename: &Path) + -> Result, String>; + fn get_dylib_metadata(&self, + target: &Target, + filename: &Path) + -> Result, String>; +} + /// A store of Rust crates, through with their metadata /// can be accessed. pub trait CrateStore { fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc; + // access to the metadata loader + fn metadata_loader(&self) -> &MetadataLoader; + // item info fn visibility(&self, def: DefId) -> ty::Visibility; fn visible_parent_map<'a>(&'a self) -> ::std::cell::Ref<'a, DefIdMap>; @@ -275,8 +298,6 @@ pub trait CrateStore { fn used_link_args(&self) -> Vec; // utility functions - fn metadata_filename(&self) -> &str; - fn metadata_section_name(&self, target: &Target) -> &str; fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>; fn used_crate_source(&self, cnum: CrateNum) -> CrateSource; fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option; @@ -413,8 +434,6 @@ impl CrateStore for DummyCrateStore { fn used_link_args(&self) -> Vec { vec![] } // utility functions - fn metadata_filename(&self) -> &str { bug!("metadata_filename") } - fn metadata_section_name(&self, target: &Target) -> &str { bug!("metadata_section_name") } fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)> { vec![] } fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") } @@ -427,6 +446,9 @@ impl CrateStore for DummyCrateStore { bug!("encode_metadata") } fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") } + + // access to the metadata loader + fn metadata_loader(&self) -> &MetadataLoader { bug!("metadata_loader") } } pub trait CrateLoader { diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 024fc546a15..2dab680ad45 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -204,7 +204,7 @@ pub fn run_compiler<'a>(args: &[String], }; let dep_graph = DepGraph::new(sopts.build_dep_graph()); - let cstore = Rc::new(CStore::new(&dep_graph)); + let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader)); let loader = file_loader.unwrap_or(box RealFileLoader); let codemap = Rc::new(CodeMap::with_file_loader(loader, sopts.file_path_mapping())); @@ -409,7 +409,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { return None; } let dep_graph = DepGraph::new(sopts.build_dep_graph()); - let cstore = Rc::new(CStore::new(&dep_graph)); + let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader)); let mut sess = build_session(sopts.clone(), &dep_graph, None, @@ -558,7 +558,11 @@ impl RustcDefaultCalls { &Input::File(ref ifile) => { let path = &(*ifile); let mut v = Vec::new(); - locator::list_file_metadata(&sess.target.target, path, &mut v).unwrap(); + locator::list_file_metadata(&sess.target.target, + path, + sess.cstore.metadata_loader(), + &mut v) + .unwrap(); println!("{}", String::from_utf8(v).unwrap()); } &Input::Str { .. } => { diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index e2cbc480715..be4f64b7109 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -14,6 +14,7 @@ use driver; use rustc::dep_graph::DepGraph; use rustc_lint; use rustc_resolve::MakeGlobMap; +use rustc_trans; use rustc::middle::lang_items; use rustc::middle::free_region::FreeRegionMap; use rustc::middle::region::{CodeExtent, RegionMaps}; @@ -104,7 +105,7 @@ fn test_env(source_string: &str, let dep_graph = DepGraph::new(false); let _ignore = dep_graph.in_ignore(); - let cstore = Rc::new(CStore::new(&dep_graph)); + let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader)); let sess = session::build_session_(options, &dep_graph, None, diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index e8b90609273..f47788ee036 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -11,13 +11,13 @@ crate-type = ["dylib"] [dependencies] flate = { path = "../libflate" } log = "0.3" +owning_ref = "0.3.3" proc_macro = { path = "../libproc_macro" } rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } rustc_const_math = { path = "../librustc_const_math" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } -rustc_llvm = { path = "../librustc_llvm" } serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } syntax_ext = { path = "../libsyntax_ext" } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index d2874f16289..dc7be42e452 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -393,6 +393,7 @@ impl<'a> CrateLoader<'a> { rejected_via_filename: vec![], should_match_name: true, is_proc_macro: Some(false), + metadata_loader: &*self.cstore.metadata_loader, }; self.load(&mut locate_ctxt).or_else(|| { @@ -554,6 +555,7 @@ impl<'a> CrateLoader<'a> { rejected_via_filename: vec![], should_match_name: true, is_proc_macro: None, + metadata_loader: &*self.cstore.metadata_loader, }; let library = self.load(&mut locate_ctxt).or_else(|| { if !is_cross { diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index c12b4209675..d2ad6d0ab34 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -11,21 +11,20 @@ // The crate store - a central repo for information collected about external // crates and libraries -use locator; use schema::{self, Tracked}; use rustc::dep_graph::{DepGraph, DepNode, GlobalMetaDataKind}; use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefIndex, DefId}; use rustc::hir::map::definitions::DefPathTable; use rustc::hir::svh::Svh; -use rustc::middle::cstore::{DepKind, ExternCrate}; +use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader}; use rustc_back::PanicStrategy; use rustc_data_structures::indexed_vec::IndexVec; use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap, DefIdMap}; use std::cell::{RefCell, Cell}; use std::rc::Rc; -use flate::Bytes; +use owning_ref::ErasedBoxRef; use syntax::{ast, attr}; use syntax::ext::base::SyntaxExtension; use syntax::symbol::Symbol; @@ -43,11 +42,7 @@ pub use cstore_impl::provide; // own crate numbers. pub type CrateNumMap = IndexVec; -pub enum MetadataBlob { - Inflated(Bytes), - Archive(locator::ArchiveMetadata), - Raw(Vec), -} +pub struct MetadataBlob(pub ErasedBoxRef<[u8]>); /// Holds information about a syntax_pos::FileMap imported from another crate. /// See `imported_filemaps()` for more information. @@ -103,10 +98,11 @@ pub struct CStore { statically_included_foreign_items: RefCell>, pub dllimport_foreign_items: RefCell>, pub visible_parent_map: RefCell>, + pub metadata_loader: Box, } impl CStore { - pub fn new(dep_graph: &DepGraph) -> CStore { + pub fn new(dep_graph: &DepGraph, metadata_loader: Box) -> CStore { CStore { dep_graph: dep_graph.clone(), metas: RefCell::new(FxHashMap()), @@ -116,6 +112,7 @@ impl CStore { statically_included_foreign_items: RefCell::new(FxHashSet()), dllimport_foreign_items: RefCell::new(FxHashSet()), visible_parent_map: RefCell::new(FxHashMap()), + metadata_loader: metadata_loader, } } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index dbf3e94832f..1a2298d3fb1 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -10,12 +10,11 @@ use cstore; use encoder; -use locator; use schema; use rustc::dep_graph::DepTrackingMapConfig; use rustc::middle::cstore::{CrateStore, CrateSource, LibSource, DepKind, - ExternCrate, NativeLibrary, LinkMeta, + ExternCrate, NativeLibrary, MetadataLoader, LinkMeta, LinkagePreference, LoadedMacro, EncodedMetadata}; use rustc::hir::def; use rustc::middle::lang_items; @@ -38,7 +37,6 @@ use syntax::parse::filemap_to_stream; use syntax::symbol::Symbol; use syntax_pos::{Span, NO_EXPANSION}; use rustc::hir::svh::Svh; -use rustc_back::target::Target; use rustc::hir; macro_rules! provide { @@ -135,6 +133,10 @@ impl CrateStore for cstore::CStore { self.get_crate_data(krate) } + fn metadata_loader(&self) -> &MetadataLoader { + &*self.metadata_loader + } + fn visibility(&self, def: DefId) -> ty::Visibility { self.dep_graph.read(DepNode::MetaData(def)); self.get_crate_data(def.krate).get_visibility(def.index) @@ -420,17 +422,6 @@ impl CrateStore for cstore::CStore { { self.get_used_link_args().borrow().clone() } - - fn metadata_filename(&self) -> &str - { - locator::METADATA_FILENAME - } - - fn metadata_section_name(&self, target: &Target) -> &str - { - locator::meta_section_name(target) - } - fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)> { self.do_get_used_crates(prefer) @@ -522,4 +513,4 @@ impl CrateStore for cstore::CStore { drop(visible_parent_map); self.visible_parent_map.borrow() } -} +} \ No newline at end of file diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 819095e2628..c734b9f411c 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -77,11 +77,7 @@ pub trait Metadata<'a, 'tcx>: Copy { impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob { fn raw_bytes(self) -> &'a [u8] { - match *self { - MetadataBlob::Inflated(ref vec) => vec, - MetadataBlob::Archive(ref ar) => ar.as_slice(), - MetadataBlob::Raw(ref vec) => vec, - } + &self.0 } } diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 27555f49e57..e3d9e5ac74a 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -37,6 +37,7 @@ extern crate syntax; extern crate syntax_pos; extern crate flate; extern crate serialize as rustc_serialize; // used by deriving +extern crate owning_ref; extern crate rustc_errors as errors; extern crate syntax_ext; extern crate proc_macro; @@ -46,7 +47,6 @@ extern crate rustc; extern crate rustc_back; extern crate rustc_const_math; extern crate rustc_data_structures; -extern crate rustc_llvm; mod diagnostics; diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 84bb82de370..34b07af9f01 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -224,15 +224,12 @@ use creader::Library; use schema::{METADATA_HEADER, rustc_version}; use rustc::hir::svh::Svh; +use rustc::middle::cstore::MetadataLoader; use rustc::session::{config, Session}; use rustc::session::filesearch::{FileSearch, FileMatches, FileDoesntMatch}; use rustc::session::search_paths::PathKind; -use rustc::util::common; use rustc::util::nodemap::FxHashMap; -use rustc_llvm as llvm; -use rustc_llvm::{False, ObjectFile, mk_section_iter}; -use rustc_llvm::archive_ro::ArchiveRO; use errors::DiagnosticBuilder; use syntax::symbol::Symbol; use syntax_pos::Span; @@ -243,11 +240,10 @@ use std::fmt; use std::fs::{self, File}; use std::io::{self, Read}; use std::path::{Path, PathBuf}; -use std::ptr; -use std::slice; use std::time::Instant; use flate; +use owning_ref::{ErasedBoxRef, OwningRef}; pub struct CrateMismatch { path: PathBuf, @@ -272,12 +268,7 @@ pub struct Context<'a> { pub rejected_via_filename: Vec, pub should_match_name: bool, pub is_proc_macro: Option, -} - -pub struct ArchiveMetadata { - _archive: ArchiveRO, - // points into self._archive - data: *const [u8], + pub metadata_loader: &'a MetadataLoader, } pub struct CratePaths { @@ -287,8 +278,6 @@ pub struct CratePaths { pub rmeta: Option, } -pub const METADATA_FILENAME: &'static str = "rust.metadata.bin"; - #[derive(Copy, Clone, PartialEq)] enum CrateFlavor { Rlib, @@ -596,20 +585,21 @@ impl<'a> Context<'a> { let mut err: Option = None; for (lib, kind) in m { info!("{} reading metadata from: {}", flavor, lib.display()); - let (hash, metadata) = match get_metadata_section(self.target, flavor, &lib) { - Ok(blob) => { - if let Some(h) = self.crate_matches(&blob, &lib) { - (h, blob) - } else { - info!("metadata mismatch"); + let (hash, metadata) = + match get_metadata_section(self.target, flavor, &lib, self.metadata_loader) { + Ok(blob) => { + if let Some(h) = self.crate_matches(&blob, &lib) { + (h, blob) + } else { + info!("metadata mismatch"); + continue; + } + } + Err(err) => { + info!("no metadata found: {}", err); continue; } - } - Err(err) => { - info!("no metadata found: {}", err); - continue; - } - }; + }; // If we see multiple hashes, emit an error about duplicate candidates. if slot.as_ref().map_or(false, |s| s.0 != hash) { let mut e = struct_span_err!(self.sess, @@ -833,50 +823,14 @@ pub fn note_crate_name(err: &mut DiagnosticBuilder, name: &str) { err.note(&format!("crate name: {}", name)); } -impl ArchiveMetadata { - fn new(ar: ArchiveRO) -> Option { - let data = { - let section = ar.iter() - .filter_map(|s| s.ok()) - .find(|sect| sect.name() == Some(METADATA_FILENAME)); - match section { - Some(s) => s.data() as *const [u8], - None => { - debug!("didn't find '{}' in the archive", METADATA_FILENAME); - return None; - } - } - }; - - Some(ArchiveMetadata { - _archive: ar, - data: data, - }) - } - - pub fn as_slice<'a>(&'a self) -> &'a [u8] { - unsafe { &*self.data } - } -} - -fn verify_decompressed_encoding_version(blob: &MetadataBlob, - filename: &Path) - -> Result<(), String> { - if !blob.is_compatible() { - Err((format!("incompatible metadata version found: '{}'", - filename.display()))) - } else { - Ok(()) - } -} - // Just a small wrapper to time how long reading metadata takes. fn get_metadata_section(target: &Target, flavor: CrateFlavor, - filename: &Path) + filename: &Path, + loader: &MetadataLoader) -> Result { let start = Instant::now(); - let ret = get_metadata_section_imp(target, flavor, filename); + let ret = get_metadata_section_imp(target, flavor, filename, loader); info!("reading {:?} => {:?}", filename.file_name().unwrap(), start.elapsed()); @@ -885,118 +839,61 @@ fn get_metadata_section(target: &Target, fn get_metadata_section_imp(target: &Target, flavor: CrateFlavor, - filename: &Path) + filename: &Path, + loader: &MetadataLoader) -> Result { if !filename.exists() { return Err(format!("no such file: '{}'", filename.display())); } - if flavor == CrateFlavor::Rlib { - // Use ArchiveRO for speed here, it's backed by LLVM and uses mmap - // internally to read the file. We also avoid even using a memcpy by - // just keeping the archive along while the metadata is in use. - let archive = match ArchiveRO::open(filename) { - Some(ar) => ar, - None => { - debug!("llvm didn't like `{}`", filename.display()); - return Err(format!("failed to read rlib metadata: '{}'", filename.display())); + let raw_bytes: ErasedBoxRef<[u8]> = match flavor { + CrateFlavor::Rlib => loader.get_rlib_metadata(target, filename)?, + CrateFlavor::Dylib => { + let buf = loader.get_dylib_metadata(target, filename)?; + // The header is uncompressed + let header_len = METADATA_HEADER.len(); + debug!("checking {} bytes of metadata-version stamp", header_len); + let header = &buf[..cmp::min(header_len, buf.len())]; + if header != METADATA_HEADER { + return Err(format!("incompatible metadata version found: '{}'", + filename.display())); } - }; - return match ArchiveMetadata::new(archive).map(|ar| MetadataBlob::Archive(ar)) { - None => Err(format!("failed to read rlib metadata: '{}'", filename.display())), - Some(blob) => { - verify_decompressed_encoding_version(&blob, filename)?; - Ok(blob) - } - }; - } else if flavor == CrateFlavor::Rmeta { - let mut file = File::open(filename).map_err(|_| - format!("could not open file: '{}'", filename.display()))?; - let mut buf = vec![]; - file.read_to_end(&mut buf).map_err(|_| - format!("failed to read rlib metadata: '{}'", filename.display()))?; - let blob = MetadataBlob::Raw(buf); - verify_decompressed_encoding_version(&blob, filename)?; - return Ok(blob); - } - unsafe { - let buf = common::path2cstr(filename); - let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr()); - if mb as isize == 0 { - return Err(format!("error reading library: '{}'", filename.display())); - } - let of = match ObjectFile::new(mb) { - Some(of) => of, - _ => { - return Err((format!("provided path not an object file: '{}'", filename.display()))) - } - }; - let si = mk_section_iter(of.llof); - while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False { - let mut name_buf = ptr::null(); - let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf); - let name = slice::from_raw_parts(name_buf as *const u8, name_len as usize).to_vec(); - let name = String::from_utf8(name).unwrap(); - debug!("get_metadata_section: name {}", name); - if read_meta_section_name(target) == name { - let cbuf = llvm::LLVMGetSectionContents(si.llsi); - let csz = llvm::LLVMGetSectionSize(si.llsi) as usize; - let cvbuf: *const u8 = cbuf as *const u8; - let vlen = METADATA_HEADER.len(); - debug!("checking {} bytes of metadata-version stamp", vlen); - let minsz = cmp::min(vlen, csz); - let buf0 = slice::from_raw_parts(cvbuf, minsz); - let version_ok = buf0 == METADATA_HEADER; - if !version_ok { - return Err((format!("incompatible metadata version found: '{}'", - filename.display()))); - } - let cvbuf1 = cvbuf.offset(vlen as isize); - debug!("inflating {} bytes of compressed metadata", csz - vlen); - let bytes = slice::from_raw_parts(cvbuf1, csz - vlen); - match flate::inflate_bytes(bytes) { - Ok(inflated) => { - let blob = MetadataBlob::Inflated(inflated); - verify_decompressed_encoding_version(&blob, filename)?; - return Ok(blob); - } - Err(_) => {} + // Header is okay -> inflate the actual metadata + let compressed_bytes = &buf[header_len..]; + debug!("inflating {} bytes of compressed metadata", compressed_bytes.len()); + match flate::inflate_bytes(compressed_bytes) { + Ok(inflated) => { + let buf = unsafe { OwningRef::new_assert_stable_address(inflated) }; + buf.map_owner_box().erase_owner() + } + Err(_) => { + return Err(format!("failed to decompress metadata: {}", filename.display())); } } - llvm::LLVMMoveToNextSection(si.llsi); } - Err(format!("metadata not found: '{}'", filename.display())) - } -} - -pub fn meta_section_name(target: &Target) -> &'static str { - // Historical note: - // - // When using link.exe it was seen that the section name `.note.rustc` - // was getting shortened to `.note.ru`, and according to the PE and COFF - // specification: - // - // > Executable images do not use a string table and do not support - // > section names longer than 8 characters - // - // https://msdn.microsoft.com/en-us/library/windows/hardware/gg463119.aspx - // - // As a result, we choose a slightly shorter name! As to why - // `.note.rustc` works on MinGW, that's another good question... - - if target.options.is_like_osx { - "__DATA,.rustc" + CrateFlavor::Rmeta => { + let mut file = File::open(filename).map_err(|_| + format!("could not open file: '{}'", filename.display()))?; + let mut buf = vec![]; + file.read_to_end(&mut buf).map_err(|_| + format!("failed to read rmeta metadata: '{}'", filename.display()))?; + OwningRef::new(buf).map_owner_box().erase_owner() + } + }; + let blob = MetadataBlob(raw_bytes); + if blob.is_compatible() { + Ok(blob) } else { - ".rustc" + Err(format!("incompatible metadata version found: '{}'", filename.display())) } } -pub fn read_meta_section_name(_target: &Target) -> &'static str { - ".rustc" -} - // A diagnostic function for dumping crate metadata to an output stream -pub fn list_file_metadata(target: &Target, path: &Path, out: &mut io::Write) -> io::Result<()> { +pub fn list_file_metadata(target: &Target, + path: &Path, + loader: &MetadataLoader, + out: &mut io::Write) + -> io::Result<()> { let filename = path.file_name().unwrap().to_str().unwrap(); let flavor = if filename.ends_with(".rlib") { CrateFlavor::Rlib @@ -1005,7 +902,7 @@ pub fn list_file_metadata(target: &Target, path: &Path, out: &mut io::Write) -> } else { CrateFlavor::Dylib }; - match get_metadata_section(target, flavor, path) { + match get_metadata_section(target, flavor, path, loader) { Ok(metadata) => metadata.list_crate_metadata(out), Err(msg) => write!(out, "{}\n", msg), } diff --git a/src/librustc_trans/Cargo.toml b/src/librustc_trans/Cargo.toml index af477f5a152..4ccc85257f3 100644 --- a/src/librustc_trans/Cargo.toml +++ b/src/librustc_trans/Cargo.toml @@ -12,6 +12,7 @@ test = false [dependencies] flate = { path = "../libflate" } log = "0.3" +owning_ref = "0.3.3" rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } rustc_bitflags = { path = "../librustc_bitflags" } diff --git a/src/librustc_trans/back/archive.rs b/src/librustc_trans/back/archive.rs index 0f908b7d069..902065c8688 100644 --- a/src/librustc_trans/back/archive.rs +++ b/src/librustc_trans/back/archive.rs @@ -20,6 +20,7 @@ use std::str; use libc; use llvm::archive_ro::{ArchiveRO, Child}; use llvm::{self, ArchiveKind}; +use metadata::METADATA_FILENAME; use rustc::session::Session; pub struct ArchiveConfig<'a> { @@ -158,11 +159,9 @@ impl<'a> ArchiveBuilder<'a> { // Ignoring all bytecode files, no matter of // name let bc_ext = ".bytecode.deflate"; - let metadata_filename = - self.config.sess.cstore.metadata_filename().to_owned(); self.add_archive(rlib, move |fname: &str| { - if fname.ends_with(bc_ext) || fname == metadata_filename { + if fname.ends_with(bc_ext) || fname == METADATA_FILENAME { return true } diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index e42e69d2a76..b8aabef65a9 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -13,6 +13,7 @@ use super::linker::Linker; use super::rpath::RPathConfig; use super::rpath; use super::msvc; +use metadata::METADATA_FILENAME; use session::config; use session::config::NoDebugInfo; use session::config::{OutputFilenames, Input, OutputType}; @@ -521,7 +522,7 @@ fn link_rlib<'a>(sess: &'a Session, // contain the metadata in a separate file. We use a temp directory // here so concurrent builds in the same directory don't try to use // the same filename for metadata (stomping over one another) - let metadata = tmpdir.join(sess.cstore.metadata_filename()); + let metadata = tmpdir.join(METADATA_FILENAME); emit_metadata(sess, trans, &metadata); ab.add_file(&metadata); @@ -1141,8 +1142,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker, archive.update_symbols(); for f in archive.src_files() { - if f.ends_with("bytecode.deflate") || - f == sess.cstore.metadata_filename() { + if f.ends_with("bytecode.deflate") || f == METADATA_FILENAME { archive.remove_file(&f); continue } @@ -1217,8 +1217,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker, let mut any_objects = false; for f in archive.src_files() { - if f.ends_with("bytecode.deflate") || - f == sess.cstore.metadata_filename() { + if f.ends_with("bytecode.deflate") || f == METADATA_FILENAME { archive.remove_file(&f); continue } diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 8689e176f7a..437ced85b2e 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -34,6 +34,7 @@ use back::linker::LinkerInfo; use back::symbol_export::{self, ExportedSymbols}; use llvm::{ContextRef, Linkage, ModuleRef, ValueRef, Vector, get_param}; use llvm; +use metadata; use rustc::hir::def_id::LOCAL_CRATE; use middle::lang_items::StartFnLangItem; use middle::cstore::EncodedMetadata; @@ -778,8 +779,7 @@ fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, }; unsafe { llvm::LLVMSetInitializer(llglobal, llconst); - let section_name = - tcx.sess.cstore.metadata_section_name(&tcx.sess.target.target); + let section_name = metadata::metadata_section_name(&tcx.sess.target.target); let name = CString::new(section_name).unwrap(); llvm::LLVMSetSection(llglobal, name.as_ptr()); diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 8e633ee59b6..15a1b32a5fd 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -45,6 +45,7 @@ use syntax_pos::symbol::Symbol; extern crate flate; extern crate libc; +extern crate owning_ref; #[macro_use] extern crate rustc; extern crate rustc_back; extern crate rustc_data_structures; @@ -70,6 +71,8 @@ pub use rustc::util; pub use base::trans_crate; pub use back::symbol_names::provide; +pub use metadata::LlvmMetadataLoader; + pub mod back { pub use rustc::hir::svh; @@ -120,6 +123,7 @@ mod declare; mod glue; mod intrinsic; mod machine; +mod metadata; mod meth; mod mir; mod monomorphize; diff --git a/src/librustc_trans/metadata.rs b/src/librustc_trans/metadata.rs new file mode 100644 index 00000000000..2c0148dfbb3 --- /dev/null +++ b/src/librustc_trans/metadata.rs @@ -0,0 +1,122 @@ +// 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. + +use rustc::util::common; +use rustc::middle::cstore::MetadataLoader; +use rustc_back::target::Target; +use llvm; +use llvm::{False, ObjectFile, mk_section_iter}; +use llvm::archive_ro::ArchiveRO; + +use owning_ref::{ErasedBoxRef, OwningRef}; +use std::path::Path; +use std::ptr; +use std::slice; + +pub const METADATA_FILENAME: &str = "rust.metadata.bin"; + +pub struct LlvmMetadataLoader; + +impl MetadataLoader for LlvmMetadataLoader { + fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result, String> { + // Use ArchiveRO for speed here, it's backed by LLVM and uses mmap + // internally to read the file. We also avoid even using a memcpy by + // just keeping the archive along while the metadata is in use. + let archive = ArchiveRO::open(filename) + .map(|ar| OwningRef::new(box ar)) + .ok_or_else(|| { + debug!("llvm didn't like `{}`", filename.display()); + format!("failed to read rlib metadata: '{}'", filename.display()) + })?; + let buf: OwningRef<_, [u8]> = archive + .try_map(|ar| { + ar.iter() + .filter_map(|s| s.ok()) + .find(|sect| sect.name() == Some(METADATA_FILENAME)) + .map(|s| s.data()) + .ok_or_else(|| { + debug!("didn't find '{}' in the archive", METADATA_FILENAME); + format!("failed to read rlib metadata: '{}'", + filename.display()) + }) + })?; + Ok(buf.erase_owner()) + } + + fn get_dylib_metadata(&self, + target: &Target, + filename: &Path) + -> Result, String> { + unsafe { + let buf = common::path2cstr(filename); + let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr()); + if mb as isize == 0 { + return Err(format!("error reading library: '{}'", filename.display())); + } + let of = ObjectFile::new(mb) + .map(|of| OwningRef::new(box of)) + .ok_or_else(|| format!("provided path not an object file: '{}'", + filename.display()))?; + let buf = of.try_map(|of| search_meta_section(of, target, filename))?; + Ok(buf.erase_owner()) + } + } +} + +fn search_meta_section<'a>(of: &'a ObjectFile, + target: &Target, + filename: &Path) + -> Result<&'a [u8], String> { + unsafe { + let si = mk_section_iter(of.llof); + while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False { + let mut name_buf = ptr::null(); + let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf); + let name = slice::from_raw_parts(name_buf as *const u8, name_len as usize).to_vec(); + let name = String::from_utf8(name).unwrap(); + debug!("get_metadata_section: name {}", name); + if read_metadata_section_name(target) == name { + let cbuf = llvm::LLVMGetSectionContents(si.llsi); + let csz = llvm::LLVMGetSectionSize(si.llsi) as usize; + // The buffer is valid while the object file is around + let buf: &'a [u8] = slice::from_raw_parts(cbuf as *const u8, csz); + return Ok(buf); + } + llvm::LLVMMoveToNextSection(si.llsi); + } + } + Err(format!("metadata not found: '{}'", filename.display())) +} + +pub fn metadata_section_name(target: &Target) -> &'static str { + // Historical note: + // + // When using link.exe it was seen that the section name `.note.rustc` + // was getting shortened to `.note.ru`, and according to the PE and COFF + // specification: + // + // > Executable images do not use a string table and do not support + // > section names longer than 8 characters + // + // https://msdn.microsoft.com/en-us/library/windows/hardware/gg463119.aspx + // + // As a result, we choose a slightly shorter name! As to why + // `.note.rustc` works on MinGW, that's another good question... + + if target.options.is_like_osx { + "__DATA,.rustc" + } else { + ".rustc" + } +} + +fn read_metadata_section_name(_target: &Target) -> &'static str { + ".rustc" +} diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 9e2d8516333..d41e9931409 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -19,6 +19,7 @@ use rustc::ty::{self, TyCtxt, GlobalArenas}; use rustc::hir::map as hir_map; use rustc::lint; use rustc::util::nodemap::FxHashMap; +use rustc_trans; use rustc_trans::back::link; use rustc_resolve as resolve; use rustc_metadata::cstore::CStore; @@ -138,7 +139,7 @@ pub fn run_core(search_paths: SearchPaths, let dep_graph = DepGraph::new(false); let _ignore = dep_graph.in_ignore(); - let cstore = Rc::new(CStore::new(&dep_graph)); + let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader)); let mut sess = session::build_session_( sessopts, &dep_graph, cpath, diagnostic_handler, codemap, cstore.clone() ); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index d5237d629cf..0600ae5b66e 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -34,6 +34,7 @@ use rustc_driver::{self, driver, Compilation}; use rustc_driver::driver::phase_2_configure_and_expand; use rustc_metadata::cstore::CStore; use rustc_resolve::MakeGlobMap; +use rustc_trans; use rustc_trans::back::link; use syntax::ast; use syntax::codemap::CodeMap; @@ -81,7 +82,7 @@ pub fn run(input: &str, let dep_graph = DepGraph::new(false); let _ignore = dep_graph.in_ignore(); - let cstore = Rc::new(CStore::new(&dep_graph)); + let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader)); let mut sess = session::build_session_( sessopts, &dep_graph, Some(input_path.clone()), handler, codemap.clone(), cstore.clone(), ); @@ -229,7 +230,7 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec, libs: SearchPaths, let diagnostic_handler = errors::Handler::with_emitter(true, false, box emitter); let dep_graph = DepGraph::new(false); - let cstore = Rc::new(CStore::new(&dep_graph)); + let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader)); let mut sess = session::build_session_( sessopts, &dep_graph, None, diagnostic_handler, codemap, cstore.clone(), ); diff --git a/src/test/run-make/issue-19371/foo.rs b/src/test/run-make/issue-19371/foo.rs index 0336fe277c5..74ecdab3372 100644 --- a/src/test/run-make/issue-19371/foo.rs +++ b/src/test/run-make/issue-19371/foo.rs @@ -15,6 +15,7 @@ extern crate rustc_driver; extern crate rustc_lint; extern crate rustc_metadata; extern crate rustc_errors; +extern crate rustc_trans; extern crate syntax; use rustc::dep_graph::DepGraph; @@ -58,7 +59,7 @@ fn basic_sess(sysroot: PathBuf) -> (Session, Rc) { let descriptions = Registry::new(&rustc::DIAGNOSTICS); let dep_graph = DepGraph::new(opts.build_dep_graph()); - let cstore = Rc::new(CStore::new(&dep_graph)); + let cstore = Rc::new(CStore::new(&dep_graph, Box::new(rustc_trans::LlvmMetadataLoader))); let sess = build_session(opts, &dep_graph, None, descriptions, cstore.clone()); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); (sess, cstore) From 93f78bc45e4d4a68038f8d2cf34187d14cb5f918 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Mon, 15 May 2017 00:52:17 +0100 Subject: [PATCH 027/103] rustdoc: Display `extern "C" fn` instead of `extern fn` --- src/librustdoc/html/format.rs | 1 - src/test/rustdoc/extern-impl.rs | 6 +++--- src/test/rustdoc/ffi.rs | 4 ++-- src/test/rustdoc/issue-22038.rs | 4 ++-- src/test/rustdoc/variadic.rs | 2 +- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 5db82e23bbf..612793e2567 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1177,7 +1177,6 @@ impl fmt::Display for AbiSpace { let quot = if f.alternate() { "\"" } else { """ }; match self.0 { Abi::Rust => Ok(()), - Abi::C => write!(f, "extern "), abi => write!(f, "extern {0}{1}{0} ", quot, abi.name()), } } diff --git a/src/test/rustdoc/extern-impl.rs b/src/test/rustdoc/extern-impl.rs index 0e78746704f..5c64b4118c3 100644 --- a/src/test/rustdoc/extern-impl.rs +++ b/src/test/rustdoc/extern-impl.rs @@ -18,9 +18,9 @@ impl Foo { pub fn rust0() {} // @has - '//code' 'fn rust1()' pub extern "Rust" fn rust1() {} - // @has - '//code' 'extern fn c0()' + // @has - '//code' 'extern "C" fn c0()' pub extern fn c0() {} - // @has - '//code' 'extern fn c1()' + // @has - '//code' 'extern "C" fn c1()' pub extern "C" fn c1() {} // @has - '//code' 'extern "system" fn system0()' pub extern "system" fn system0() {} @@ -31,7 +31,7 @@ pub trait Bar {} // @has - '//code' 'impl Bar for fn()' impl Bar for fn() {} -// @has - '//code' 'impl Bar for extern fn()' +// @has - '//code' 'impl Bar for extern "C" fn()' impl Bar for extern fn() {} // @has - '//code' 'impl Bar for extern "system" fn()' impl Bar for extern "system" fn() {} diff --git a/src/test/rustdoc/ffi.rs b/src/test/rustdoc/ffi.rs index 3997dcd81e1..8511d461703 100644 --- a/src/test/rustdoc/ffi.rs +++ b/src/test/rustdoc/ffi.rs @@ -13,10 +13,10 @@ extern crate rustdoc_ffi as lib; -// @has ffi/fn.foreigner.html //pre 'pub unsafe extern fn foreigner(cold_as_ice: u32)' +// @has ffi/fn.foreigner.html //pre 'pub unsafe extern "C" fn foreigner(cold_as_ice: u32)' pub use lib::foreigner; extern "C" { - // @has ffi/fn.another.html //pre 'pub unsafe extern fn another(cold_as_ice: u32)' + // @has ffi/fn.another.html //pre 'pub unsafe extern "C" fn another(cold_as_ice: u32)' pub fn another(cold_as_ice: u32); } diff --git a/src/test/rustdoc/issue-22038.rs b/src/test/rustdoc/issue-22038.rs index 6f84428b079..75df5358945 100644 --- a/src/test/rustdoc/issue-22038.rs +++ b/src/test/rustdoc/issue-22038.rs @@ -10,7 +10,7 @@ extern { // @has issue_22038/fn.foo1.html \ - // '//*[@class="rust fn"]' 'pub unsafe extern fn foo1()' + // '//*[@class="rust fn"]' 'pub unsafe extern "C" fn foo1()' pub fn foo1(); } @@ -21,7 +21,7 @@ extern "system" { } // @has issue_22038/fn.bar.html \ -// '//*[@class="rust fn"]' 'pub extern fn bar()' +// '//*[@class="rust fn"]' 'pub extern "C" fn bar()' pub extern fn bar() {} // @has issue_22038/fn.baz.html \ diff --git a/src/test/rustdoc/variadic.rs b/src/test/rustdoc/variadic.rs index 1b60c2a334f..6ba776ba467 100644 --- a/src/test/rustdoc/variadic.rs +++ b/src/test/rustdoc/variadic.rs @@ -9,6 +9,6 @@ // except according to those terms. extern "C" { - // @has variadic/fn.foo.html //pre 'pub unsafe extern fn foo(x: i32, ...)' + // @has variadic/fn.foo.html //pre 'pub unsafe extern "C" fn foo(x: i32, ...)' pub fn foo(x: i32, ...); } From c0d5aa8aaf478e52d0e96bd0fbd19cde6e30ebb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 23 Apr 2017 17:57:07 -0700 Subject: [PATCH 028/103] Make unsatisfied trait bounds note multiline Make diagnostic note for existing method with unsatisfied trait bounds multiline for cleaner output. ``` = note: the method `count` exists but the following trait bounds were not satisfied: `[closure@../../src/test/compile-fail/issue-36053-2.rs:17:39: 17:53] : std::ops::FnMut<(&_,)>` `std::iter::Filter> [closure@../../src/test/compile-fail/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator` Before: ``` = note: the method `count` exists but the following trait bounds were not satisfied: `[closure@../../src/test/compile-fail/issue-36053-2.rs:17:39: 17:53] : std::ops::FnMut<(&_,)>`, `std::iter::Filter>, [closure@../../src/test/compile-fail/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator` ``` --- src/librustc_typeck/check/method/suggest.rs | 4 ++-- src/test/ui/mismatched_types/issue-36053-2.stderr | 4 +++- .../method-help-unsatisfied-bound.rs | 2 +- .../method-help-unsatisfied-bound.stderr | 11 +++++++++++ 4 files changed, 17 insertions(+), 4 deletions(-) rename src/test/{compile-fail => ui/mismatched_types}/method-help-unsatisfied-bound.rs (87%) create mode 100644 src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index c7ec379b0de..7e70bb92cd6 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -251,9 +251,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let bound_list = unsatisfied_predicates.iter() .map(|p| format!("`{} : {}`", p.self_ty(), p)) .collect::>() - .join(", "); + .join("\n"); err.note(&format!("the method `{}` exists but the following trait bounds \ - were not satisfied: {}", + were not satisfied:\n{}", item_name, bound_list)); } diff --git a/src/test/ui/mismatched_types/issue-36053-2.stderr b/src/test/ui/mismatched_types/issue-36053-2.stderr index adc229aaacc..78e0f7e619b 100644 --- a/src/test/ui/mismatched_types/issue-36053-2.stderr +++ b/src/test/ui/mismatched_types/issue-36053-2.stderr @@ -4,7 +4,9 @@ error: no method named `count` found for type `std::iter::Filter("str").fuse().filter(|a: &str| true).count(); | ^^^^^ | - = note: the method `count` exists but the following trait bounds were not satisfied: `[closure@$DIR/issue-36053-2.rs:17:39: 17:53] : std::ops::FnMut<(&_,)>`, `std::iter::Filter>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator` + = note: the method `count` exists but the following trait bounds were not satisfied: + `[closure@$DIR/issue-36053-2.rs:17:39: 17:53] : std::ops::FnMut<(&_,)>` + `std::iter::Filter>, [closure@$DIR/issue-36053-2.rs:17:39: 17:53]> : std::iter::Iterator` error[E0281]: type mismatch: `[closure@$DIR/issue-36053-2.rs:17:39: 17:53]` implements the trait `for<'r> std::ops::FnMut<(&'r str,)>`, but the trait `for<'r> std::ops::FnMut<(&'r &str,)>` is required --> $DIR/issue-36053-2.rs:17:32 diff --git a/src/test/compile-fail/method-help-unsatisfied-bound.rs b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.rs similarity index 87% rename from src/test/compile-fail/method-help-unsatisfied-bound.rs rename to src/test/ui/mismatched_types/method-help-unsatisfied-bound.rs index 6416d5467c8..a4eb4455551 100644 --- a/src/test/compile-fail/method-help-unsatisfied-bound.rs +++ b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.rs @@ -14,5 +14,5 @@ fn main() { let a: Result<(), Foo> = Ok(()); a.unwrap(); //~^ ERROR no method named `unwrap` found for type `std::result::Result<(), Foo>` - //~| NOTE the following trait bounds were not satisfied: `Foo : std::fmt::Debug` + //~| NOTE the method `unwrap` exists but the following trait bounds were not satisfied } diff --git a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr new file mode 100644 index 00000000000..2bd786c20fe --- /dev/null +++ b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr @@ -0,0 +1,11 @@ +error: no method named `unwrap` found for type `std::result::Result<(), Foo>` in the current scope + --> $DIR/method-help-unsatisfied-bound.rs:15:7 + | +15 | a.unwrap(); + | ^^^^^^ + | + = note: the method `unwrap` exists but the following trait bounds were not satisfied: + `Foo : std::fmt::Debug` + +error: aborting due to previous error + From 020c5ecca710a21f85be028d6225c9c82638ade0 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 8 May 2017 15:01:13 -0700 Subject: [PATCH 029/103] Update to the oxidized rust-installer --- .gitmodules | 2 +- src/Cargo.lock | 165 ++++++++++++++++++++++++++++++++++++- src/Cargo.toml | 1 + src/bootstrap/dist.rs | 46 +++++------ src/bootstrap/step.rs | 13 +++ src/rust-installer | 1 - src/tools/rust-installer | 1 + src/tools/tidy/src/main.rs | 2 +- 8 files changed, 201 insertions(+), 30 deletions(-) delete mode 160000 src/rust-installer create mode 160000 src/tools/rust-installer diff --git a/.gitmodules b/.gitmodules index 7cd896b763f..791404344ef 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,7 +13,7 @@ path = src/jemalloc url = https://github.com/rust-lang/jemalloc.git [submodule "src/rust-installer"] - path = src/rust-installer + path = src/tools/rust-installer url = https://github.com/rust-lang/rust-installer.git [submodule "src/liblibc"] path = src/liblibc diff --git a/src/Cargo.lock b/src/Cargo.lock index 776a268aa8d..9269fc0f448 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -58,6 +58,29 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "backtrace" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bitflags" version = "0.5.0" @@ -102,6 +125,11 @@ dependencies = [ name = "cargotest2" version = "0.1.0" +[[package]] +name = "cfg-if" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "clap" version = "2.22.1" @@ -115,6 +143,7 @@ dependencies = [ "unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "vec_map 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -158,6 +187,15 @@ dependencies = [ name = "core" version = "0.0.0" +[[package]] +name = "dbghelp-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "diff" version = "0.1.10" @@ -177,6 +215,14 @@ dependencies = [ "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "error-chain" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "error_index_generator" version = "0.0.0" @@ -197,6 +243,15 @@ dependencies = [ "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "flate2" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fmt_macros" version = "0.0.0" @@ -224,7 +279,7 @@ name = "handlebars" version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -233,6 +288,21 @@ dependencies = [ "serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "installer" +version = "0.0.0" +dependencies = [ + "clap 2.22.1 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tar 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "xz2 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "itoa" version = "0.3.1" @@ -249,7 +319,7 @@ dependencies = [ [[package]] name = "lazy_static" -version = "0.2.5" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -273,6 +343,16 @@ name = "log" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "lzma-sys" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "mdbook" version = "0.0.21" @@ -298,6 +378,15 @@ dependencies = [ "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "miniz-sys" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "num-traits" version = "0.1.37" @@ -453,6 +542,11 @@ dependencies = [ "syntax_pos 0.0.0", ] +[[package]] +name = "rustc-demangle" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rustc-main" version = "0.0.0" @@ -800,6 +894,15 @@ dependencies = [ "syntax_pos 0.0.0", ] +[[package]] +name = "same-file" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "serde" version = "0.9.11" @@ -887,6 +990,16 @@ dependencies = [ "serialize 0.0.0", ] +[[package]] +name = "tar" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "xattr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "term" version = "0.0.0" @@ -980,6 +1093,16 @@ name = "void" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "walkdir" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi" version = "0.2.8" @@ -990,28 +1113,57 @@ name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "xattr" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "xz2" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lzma-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "yaml-rust" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [metadata] "checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699" "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" "checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159" +"checksum backtrace 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f551bc2ddd53aea015d453ef0b635af89444afa5ed2405dd0b2062ad5d600d80" +"checksum backtrace-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d192fd129132fbc97497c1f2ec2c2c5174e376b95f535199ef4fe0a293d33842" "checksum bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23" "checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4" +"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c" "checksum clap 2.22.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e17a4a72ffea176f77d6e2db609c6c919ef221f23862c9915e687fb54d833485" "checksum cmake 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "92278eb79412c8f75cfc89e707a1bb3a6490b68f7f2e78d15c774f30fe701122" +"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum diff 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0a515461b6c8c08419850ced27bc29e86166dcdcde8fbe76f8b1f0589bb49472" "checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90" "checksum env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e3856f1697098606fc6cb97a93de88ca3f3bc35bb878c725920e6e82ecf05e83" +"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" "checksum filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "5363ab8e4139b8568a6237db5248646e5a8a2f89bd5ccb02092182b11fd3e922" +"checksum flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)" = "36df0166e856739905cd3d7e0b210fe818592211a008862599845e012d8d304c" "checksum gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)" = "181e3cebba1d663bd92eb90e2da787e10597e027eb00de8d742b260a7850948f" "checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685" "checksum handlebars 0.25.2 (registry+https://github.com/rust-lang/crates.io-index)" = "663e1728d8037fb0d4e13bcd1b1909fb5d913690a9929eb385922df157c2ff8f" "checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum lazy_static 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4732c563b9a21a406565c4747daa7b46742f082911ae4753f390dc9ec7ee1a97" +"checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf" "checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135" "checksum log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5141eca02775a762cc6cd564d8d2c50f67c0ea3a372cbf1c51592b3e029e10ad" +"checksum lzma-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c5eaaa53b35fa17482ee2c001b04242827b47ae0faba72663fee3dee32366248" "checksum mdbook 0.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "f1e2e9d848514dcfad4195788d0d42ae5153a477c191d75d5b84fab10f222fbd" "checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4" +"checksum miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "28eaee17666671fa872e567547e8428e83308ebe5808cdf6a0e28397dbe2c726" "checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99" "checksum num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca313f1862c7ec3e0dfe8ace9fa91b1d9cb5c84ace3d00f5ec4216238e93c167" "checksum open 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3478ed1686bd1300c8a981a940abc92b06fac9cbef747f4c668d4e032ff7b842" @@ -1023,10 +1175,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457" "checksum rls-data 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fc4277ce3c57f456b11fe3145b181a844a25201bab5cbaa1978457e6e2f27d47" "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a" +"checksum rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3058a43ada2c2d0b92b3ae38007a2d0fa5e9db971be260e0171408a4ff471c95" "checksum rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "684ce48436d6465300c9ea783b6b14c4361d6b8dcbb1375b486a69cc19e2dfb0" +"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7" "checksum serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "a702319c807c016e51f672e5c77d6f0b46afddd744b5e437d6b8436b888b458f" "checksum serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "dbc45439552eb8fb86907a2c41c1fd0ef97458efb87ff7f878db466eb581824e" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" +"checksum tar 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ab0ef9ead2fe0aa9e18475a96a207bfd5143f4124779ef7429503a8665416ce8" "checksum term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "07b6c1ac5b3fffd75073276bca1ceed01f67a28537097a2a9539e116e50fb21a" "checksum thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4437c97558c70d129e40629a5b385b3fb1ffac301e63941335e4d354081ec14a" "checksum thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c85048c6260d17cf486ceae3282d9fb6b90be220bf5b28c400f5485ffc29f0c7" @@ -1038,5 +1193,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum vec_map 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8cdc8b93bd0198ed872357fb2e667f7125646b1762f16d60b2c96350d361897" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"checksum xattr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "5f04de8a1346489a2f9e9bd8526b73d135ec554227b17568456e86aa35b6f3fc" +"checksum xz2 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e9510bdf100731599107c61f77daf46713a69a568f75458999c1f9dbf6ba25b0" +"checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" diff --git a/src/Cargo.toml b/src/Cargo.toml index 9aca3e134d6..99e8b9f256a 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -13,6 +13,7 @@ members = [ "tools/build-manifest", "tools/remote-test-client", "tools/remote-test-server", + "tools/rust-installer", ] # These projects have their own Cargo.lock diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 1b69f7413b5..028bfe3408f 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -26,12 +26,6 @@ use std::process::{Command, Stdio}; use build_helper::output; -#[cfg(not(target_os = "solaris"))] -const SH_CMD: &'static str = "sh"; -// On Solaris, sh is the historical bourne shell, not a POSIX shell, or bash. -#[cfg(target_os = "solaris")] -const SH_CMD: &'static str = "bash"; - use {Build, Compiler, Mode}; use channel; use util::{cp_r, libdir, is_dylib, cp_filtered, copy, exe}; @@ -55,6 +49,10 @@ pub fn tmpdir(build: &Build) -> PathBuf { build.out.join("tmp/dist") } +fn rust_installer(build: &Build) -> Command { + build.tool_cmd(&Compiler::new(0, &build.config.build), "rust-installer") +} + /// Builds the `rust-docs` installer component. /// /// Slurps up documentation from the `stage`'s `host`. @@ -74,8 +72,8 @@ pub fn docs(build: &Build, stage: u32, host: &str) { let src = build.out.join(host).join("doc"); cp_r(&src, &dst); - let mut cmd = Command::new(SH_CMD); - cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh"))) + let mut cmd = rust_installer(build); + cmd.arg("generate") .arg("--product-name=Rust-Documentation") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=Rust-documentation-is-installed.") @@ -124,8 +122,8 @@ pub fn mingw(build: &Build, host: &str) { .arg(host); build.run(&mut cmd); - let mut cmd = Command::new(SH_CMD); - cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh"))) + let mut cmd = rust_installer(build); + cmd.arg("generate") .arg("--product-name=Rust-MinGW") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=Rust-MinGW-is-installed.") @@ -190,8 +188,8 @@ pub fn rustc(build: &Build, stage: u32, host: &str) { } // Finally, wrap everything up in a nice tarball! - let mut cmd = Command::new(SH_CMD); - cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh"))) + let mut cmd = rust_installer(build); + cmd.arg("generate") .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=Rust-is-ready-to-roll.") @@ -300,8 +298,8 @@ pub fn std(build: &Build, compiler: &Compiler, target: &str) { let src = build.sysroot(compiler).join("lib/rustlib"); cp_r(&src.join(target), &dst); - let mut cmd = Command::new(SH_CMD); - cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh"))) + let mut cmd = rust_installer(build); + cmd.arg("generate") .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=std-is-standing-at-the-ready.") @@ -356,8 +354,8 @@ pub fn analysis(build: &Build, compiler: &Compiler, target: &str) { println!("image_src: {:?}, dst: {:?}", image_src, dst); cp_r(&image_src, &dst); - let mut cmd = Command::new(SH_CMD); - cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh"))) + let mut cmd = rust_installer(build); + cmd.arg("generate") .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=save-analysis-saved.") @@ -521,8 +519,8 @@ pub fn rust_src(build: &Build) { } // Create source tarball in rust-installer format - let mut cmd = Command::new(SH_CMD); - cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh"))) + let mut cmd = rust_installer(build); + cmd.arg("generate") .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=Awesome-Source.") @@ -622,8 +620,8 @@ pub fn cargo(build: &Build, stage: u32, target: &str) { t!(t!(File::create(overlay.join("version"))).write_all(version.as_bytes())); // Generate the installer tarball - let mut cmd = Command::new("sh"); - cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh"))) + let mut cmd = rust_installer(build); + cmd.arg("generate") .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=Rust-is-ready-to-roll.") @@ -671,8 +669,8 @@ pub fn rls(build: &Build, stage: u32, target: &str) { t!(t!(File::create(overlay.join("version"))).write_all(version.as_bytes())); // Generate the installer tarball - let mut cmd = Command::new("sh"); - cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/gen-installer.sh"))) + let mut cmd = rust_installer(build); + cmd.arg("generate") .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=RLS-ready-to-serve.") @@ -742,8 +740,8 @@ pub fn extended(build: &Build, stage: u32, target: &str) { input_tarballs.push_str(&sanitize_sh(&mingw_installer)); } - let mut cmd = Command::new(SH_CMD); - cmd.arg(sanitize_sh(&build.src.join("src/rust-installer/combine-installers.sh"))) + let mut cmd = rust_installer(build); + cmd.arg("combine") .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=Rust-is-ready-to-roll.") diff --git a/src/bootstrap/step.rs b/src/bootstrap/step.rs index 970c0bc565d..99f0e17abab 100644 --- a/src/bootstrap/step.rs +++ b/src/bootstrap/step.rs @@ -574,6 +574,10 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { .dep(|s| s.name("maybe-clean-tools")) .dep(|s| s.name("libstd-tool")) .run(move |s| compile::tool(build, s.stage, s.target, "remote-test-client")); + rules.build("tool-rust-installer", "src/tools/rust-installer") + .dep(|s| s.name("maybe-clean-tools")) + .dep(|s| s.name("libstd-tool")) + .run(move |s| compile::tool(build, s.stage, s.target, "rust-installer")); rules.build("tool-cargo", "src/tools/cargo") .host(true) .default(build.config.extended) @@ -704,6 +708,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { .host(true) .only_host_build(true) .default(true) + .dep(|s| s.name("tool-rust-installer").stage(0)) .run(move |s| dist::rustc(build, s.stage, s.target)); rules.dist("dist-std", "src/libstd") .dep(move |s| { @@ -718,10 +723,12 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { }) .default(true) .only_host_build(true) + .dep(|s| s.name("tool-rust-installer").stage(0)) .run(move |s| dist::std(build, &s.compiler(), s.target)); rules.dist("dist-mingw", "path/to/nowhere") .default(true) .only_host_build(true) + .dep(|s| s.name("tool-rust-installer").stage(0)) .run(move |s| { if s.target.contains("pc-windows-gnu") { dist::mingw(build, s.target) @@ -732,21 +739,25 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { .host(true) .only_build(true) .only_host_build(true) + .dep(|s| s.name("tool-rust-installer").stage(0)) .run(move |_| dist::rust_src(build)); rules.dist("dist-docs", "src/doc") .default(true) .only_host_build(true) .dep(|s| s.name("default:doc")) + .dep(|s| s.name("tool-rust-installer").stage(0)) .run(move |s| dist::docs(build, s.stage, s.target)); rules.dist("dist-analysis", "analysis") .default(build.config.extended) .dep(|s| s.name("dist-std")) .only_host_build(true) + .dep(|s| s.name("tool-rust-installer").stage(0)) .run(move |s| dist::analysis(build, &s.compiler(), s.target)); rules.dist("dist-rls", "rls") .host(true) .only_host_build(true) .dep(|s| s.name("tool-rls")) + .dep(|s| s.name("tool-rust-installer").stage(0)) .run(move |s| dist::rls(build, s.stage, s.target)); rules.dist("install", "path/to/nowhere") .dep(|s| s.name("default:dist")) @@ -755,6 +766,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { .host(true) .only_host_build(true) .dep(|s| s.name("tool-cargo")) + .dep(|s| s.name("tool-rust-installer").stage(0)) .run(move |s| dist::cargo(build, s.stage, s.target)); rules.dist("dist-extended", "extended") .default(build.config.extended) @@ -767,6 +779,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { .dep(|d| d.name("dist-cargo")) .dep(|d| d.name("dist-rls")) .dep(|d| d.name("dist-analysis")) + .dep(|s| s.name("tool-rust-installer").stage(0)) .run(move |s| dist::extended(build, s.stage, s.target)); rules.dist("dist-sign", "hash-and-sign") diff --git a/src/rust-installer b/src/rust-installer deleted file mode 160000 index 2e6417f6af5..00000000000 --- a/src/rust-installer +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2e6417f6af5218a29a8ee72ed17af085560b9b9c diff --git a/src/tools/rust-installer b/src/tools/rust-installer new file mode 160000 index 00000000000..6a2c5d12910 --- /dev/null +++ b/src/tools/rust-installer @@ -0,0 +1 @@ +Subproject commit 6a2c5d129101762d204185b888d62a244011c422 diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index f14a6a03893..6b666fa809f 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -81,12 +81,12 @@ fn filter_dirs(path: &Path) -> bool { "src/libbacktrace", "src/compiler-rt", "src/rustllvm", - "src/rust-installer", "src/liblibc", "src/vendor", "src/rt/hoedown", "src/tools/cargo", "src/tools/rls", + "src/tools/rust-installer", ]; skip.iter().any(|p| path.ends_with(p)) } From 6edb4e22c46ae34b5b8ee0f2672f02d890944105 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 8 May 2017 15:23:30 -0700 Subject: [PATCH 030/103] Use "rust-installer tarball" to create rustc-src too This gives us an extra rustc-src.tar.xz, which is 33% smaller than the .tar.gz! --- src/bootstrap/dist.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 028bfe3408f..254b817b847 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -469,13 +469,17 @@ pub fn rust_src(build: &Build) { write_file(&plain_dst_src.join("version"), build.rust_version().as_bytes()); // Create plain source tarball - let tarball = rust_src_location(build); + let mut tarball = rust_src_location(build); + tarball.set_extension(""); // strip .gz + tarball.set_extension(""); // strip .tar if let Some(dir) = tarball.parent() { t!(fs::create_dir_all(dir)); } - let mut cmd = Command::new("tar"); - cmd.arg("-czf").arg(sanitize_sh(&tarball)) - .arg(&plain_name) + let mut cmd = rust_installer(build); + cmd.arg("tarball") + .arg("--input").arg(&plain_name) + .arg("--output").arg(sanitize_sh(&tarball)) + .arg("--work-dir=.") .current_dir(tmpdir(build)); build.run(&mut cmd); From 3d6ee0a14b351dd1f93025a199966d3661a33037 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 9 May 2017 11:43:48 -0700 Subject: [PATCH 031/103] Force tool-rust-installer deps to build-only --- src/bootstrap/step.rs | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/bootstrap/step.rs b/src/bootstrap/step.rs index 99f0e17abab..92666e8e639 100644 --- a/src/bootstrap/step.rs +++ b/src/bootstrap/step.rs @@ -708,7 +708,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { .host(true) .only_host_build(true) .default(true) - .dep(|s| s.name("tool-rust-installer").stage(0)) + .dep(move |s| tool_rust_installer(build, s)) .run(move |s| dist::rustc(build, s.stage, s.target)); rules.dist("dist-std", "src/libstd") .dep(move |s| { @@ -723,12 +723,12 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { }) .default(true) .only_host_build(true) - .dep(|s| s.name("tool-rust-installer").stage(0)) + .dep(move |s| tool_rust_installer(build, s)) .run(move |s| dist::std(build, &s.compiler(), s.target)); rules.dist("dist-mingw", "path/to/nowhere") .default(true) .only_host_build(true) - .dep(|s| s.name("tool-rust-installer").stage(0)) + .dep(move |s| tool_rust_installer(build, s)) .run(move |s| { if s.target.contains("pc-windows-gnu") { dist::mingw(build, s.target) @@ -739,25 +739,25 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { .host(true) .only_build(true) .only_host_build(true) - .dep(|s| s.name("tool-rust-installer").stage(0)) + .dep(move |s| tool_rust_installer(build, s)) .run(move |_| dist::rust_src(build)); rules.dist("dist-docs", "src/doc") .default(true) .only_host_build(true) .dep(|s| s.name("default:doc")) - .dep(|s| s.name("tool-rust-installer").stage(0)) + .dep(move |s| tool_rust_installer(build, s)) .run(move |s| dist::docs(build, s.stage, s.target)); rules.dist("dist-analysis", "analysis") .default(build.config.extended) .dep(|s| s.name("dist-std")) .only_host_build(true) - .dep(|s| s.name("tool-rust-installer").stage(0)) + .dep(move |s| tool_rust_installer(build, s)) .run(move |s| dist::analysis(build, &s.compiler(), s.target)); rules.dist("dist-rls", "rls") .host(true) .only_host_build(true) .dep(|s| s.name("tool-rls")) - .dep(|s| s.name("tool-rust-installer").stage(0)) + .dep(move |s| tool_rust_installer(build, s)) .run(move |s| dist::rls(build, s.stage, s.target)); rules.dist("install", "path/to/nowhere") .dep(|s| s.name("default:dist")) @@ -766,7 +766,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { .host(true) .only_host_build(true) .dep(|s| s.name("tool-cargo")) - .dep(|s| s.name("tool-rust-installer").stage(0)) + .dep(move |s| tool_rust_installer(build, s)) .run(move |s| dist::cargo(build, s.stage, s.target)); rules.dist("dist-extended", "extended") .default(build.config.extended) @@ -779,7 +779,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { .dep(|d| d.name("dist-cargo")) .dep(|d| d.name("dist-rls")) .dep(|d| d.name("dist-analysis")) - .dep(|s| s.name("tool-rust-installer").stage(0)) + .dep(move |s| tool_rust_installer(build, s)) .run(move |s| dist::extended(build, s.stage, s.target)); rules.dist("dist-sign", "hash-and-sign") @@ -791,6 +791,14 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { rules.verify(); return rules; + + /// Helper to depend on a stage0 build-only rust-installer tool. + fn tool_rust_installer<'a>(build: &'a Build, step: &Step<'a>) -> Step<'a> { + step.name("tool-rust-installer") + .host(&build.config.build) + .target(&build.config.build) + .stage(0) + } } #[derive(PartialEq, Eq, Hash, Clone, Debug)] From 1e709fcff37a55ab4b8d746be615811a77286945 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 10 May 2017 12:20:00 -0700 Subject: [PATCH 032/103] Don't use sanitize_sh with rust-installer There's no shell interpreting the file paths under the new Rusty rust-installer, so we don't need to use `sanitize_sh` for it. Plus, the drive-letter transformation is actually harmful for the now-native Windows rust-installer to understand those paths. --- src/bootstrap/dist.rs | 81 +++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 254b817b847..6557b8410b1 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -77,9 +77,9 @@ pub fn docs(build: &Build, stage: u32, host: &str) { .arg("--product-name=Rust-Documentation") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=Rust-documentation-is-installed.") - .arg(format!("--image-dir={}", sanitize_sh(&image))) - .arg(format!("--work-dir={}", sanitize_sh(&tmpdir(build)))) - .arg(format!("--output-dir={}", sanitize_sh(&distdir(build)))) + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(build)) + .arg("--output-dir").arg(&distdir(build)) .arg(format!("--package-name={}-{}", name, host)) .arg("--component-name=rust-docs") .arg("--legacy-manifest-dirs=rustlib,cargo") @@ -127,9 +127,9 @@ pub fn mingw(build: &Build, host: &str) { .arg("--product-name=Rust-MinGW") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=Rust-MinGW-is-installed.") - .arg(format!("--image-dir={}", sanitize_sh(&image))) - .arg(format!("--work-dir={}", sanitize_sh(&tmpdir(build)))) - .arg(format!("--output-dir={}", sanitize_sh(&distdir(build)))) + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(build)) + .arg("--output-dir").arg(&distdir(build)) .arg(format!("--package-name={}-{}", name, host)) .arg("--component-name=rust-mingw") .arg("--legacy-manifest-dirs=rustlib,cargo"); @@ -193,10 +193,10 @@ pub fn rustc(build: &Build, stage: u32, host: &str) { .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=Rust-is-ready-to-roll.") - .arg(format!("--image-dir={}", sanitize_sh(&image))) - .arg(format!("--work-dir={}", sanitize_sh(&tmpdir(build)))) - .arg(format!("--output-dir={}", sanitize_sh(&distdir(build)))) - .arg(format!("--non-installed-overlay={}", sanitize_sh(&overlay))) + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(build)) + .arg("--output-dir").arg(&distdir(build)) + .arg("--non-installed-overlay").arg(&overlay) .arg(format!("--package-name={}-{}", name, host)) .arg("--component-name=rustc") .arg("--legacy-manifest-dirs=rustlib,cargo"); @@ -303,9 +303,9 @@ pub fn std(build: &Build, compiler: &Compiler, target: &str) { .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=std-is-standing-at-the-ready.") - .arg(format!("--image-dir={}", sanitize_sh(&image))) - .arg(format!("--work-dir={}", sanitize_sh(&tmpdir(build)))) - .arg(format!("--output-dir={}", sanitize_sh(&distdir(build)))) + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(build)) + .arg("--output-dir").arg(&distdir(build)) .arg(format!("--package-name={}-{}", name, target)) .arg(format!("--component-name=rust-std-{}", target)) .arg("--legacy-manifest-dirs=rustlib,cargo"); @@ -359,9 +359,9 @@ pub fn analysis(build: &Build, compiler: &Compiler, target: &str) { .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=save-analysis-saved.") - .arg(format!("--image-dir={}", sanitize_sh(&image))) - .arg(format!("--work-dir={}", sanitize_sh(&tmpdir(build)))) - .arg(format!("--output-dir={}", sanitize_sh(&distdir(build)))) + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(build)) + .arg("--output-dir").arg(&distdir(build)) .arg(format!("--package-name={}-{}", name, target)) .arg(format!("--component-name=rust-analysis-{}", target)) .arg("--legacy-manifest-dirs=rustlib,cargo"); @@ -478,7 +478,7 @@ pub fn rust_src(build: &Build) { let mut cmd = rust_installer(build); cmd.arg("tarball") .arg("--input").arg(&plain_name) - .arg("--output").arg(sanitize_sh(&tarball)) + .arg("--output").arg(&tarball) .arg("--work-dir=.") .current_dir(tmpdir(build)); build.run(&mut cmd); @@ -528,9 +528,9 @@ pub fn rust_src(build: &Build) { .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=Awesome-Source.") - .arg(format!("--image-dir={}", sanitize_sh(&image))) - .arg(format!("--work-dir={}", sanitize_sh(&tmpdir(build)))) - .arg(format!("--output-dir={}", sanitize_sh(&distdir(build)))) + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(build)) + .arg("--output-dir").arg(&distdir(build)) .arg(format!("--package-name={}", name)) .arg("--component-name=rust-src") .arg("--legacy-manifest-dirs=rustlib,cargo"); @@ -629,10 +629,10 @@ pub fn cargo(build: &Build, stage: u32, target: &str) { .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=Rust-is-ready-to-roll.") - .arg(format!("--image-dir={}", sanitize_sh(&image))) - .arg(format!("--work-dir={}", sanitize_sh(&tmpdir(build)))) - .arg(format!("--output-dir={}", sanitize_sh(&distdir(build)))) - .arg(format!("--non-installed-overlay={}", sanitize_sh(&overlay))) + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(build)) + .arg("--output-dir").arg(&distdir(build)) + .arg("--non-installed-overlay").arg(&overlay) .arg(format!("--package-name={}-{}", name, target)) .arg("--component-name=cargo") .arg("--legacy-manifest-dirs=rustlib,cargo"); @@ -678,10 +678,10 @@ pub fn rls(build: &Build, stage: u32, target: &str) { .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=RLS-ready-to-serve.") - .arg(format!("--image-dir={}", sanitize_sh(&image))) - .arg(format!("--work-dir={}", sanitize_sh(&tmpdir(build)))) - .arg(format!("--output-dir={}", sanitize_sh(&distdir(build)))) - .arg(format!("--non-installed-overlay={}", sanitize_sh(&overlay))) + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(build)) + .arg("--output-dir").arg(&distdir(build)) + .arg("--non-installed-overlay").arg(&overlay) .arg(format!("--package-name={}-{}", name, target)) .arg("--component-name=rls") .arg("--legacy-manifest-dirs=rustlib,cargo"); @@ -732,16 +732,15 @@ pub fn extended(build: &Build, stage: u32, target: &str) { // upgrades rustc was upgraded before rust-std. To avoid rustc clobbering // the std files during uninstall. To do this ensure that rustc comes // before rust-std in the list below. - let mut input_tarballs = format!("{},{},{},{},{},{}", - sanitize_sh(&rustc_installer), - sanitize_sh(&cargo_installer), - sanitize_sh(&rls_installer), - sanitize_sh(&analysis_installer), - sanitize_sh(&docs_installer), - sanitize_sh(&std_installer)); + let mut tarballs = vec![rustc_installer, cargo_installer, rls_installer, + analysis_installer, docs_installer, std_installer]; if target.contains("pc-windows-gnu") { - input_tarballs.push_str(","); - input_tarballs.push_str(&sanitize_sh(&mingw_installer)); + tarballs.push(mingw_installer); + } + let mut input_tarballs = tarballs[0].as_os_str().to_owned(); + for tarball in &tarballs[1..] { + input_tarballs.push(","); + input_tarballs.push(tarball); } let mut cmd = rust_installer(build); @@ -749,12 +748,12 @@ pub fn extended(build: &Build, stage: u32, target: &str) { .arg("--product-name=Rust") .arg("--rel-manifest-dir=rustlib") .arg("--success-message=Rust-is-ready-to-roll.") - .arg(format!("--work-dir={}", sanitize_sh(&work))) - .arg(format!("--output-dir={}", sanitize_sh(&distdir(build)))) + .arg("--work-dir").arg(&work) + .arg("--output-dir").arg(&distdir(build)) .arg(format!("--package-name={}-{}", pkgname(build, "rust"), target)) .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg(format!("--input-tarballs={}", input_tarballs)) - .arg(format!("--non-installed-overlay={}", sanitize_sh(&overlay))); + .arg("--input-tarballs").arg(input_tarballs) + .arg("--non-installed-overlay").arg(&overlay); build.run(&mut cmd); let mut license = String::new(); From 25b7f10c781fae5682523c59a73c4c6b49c97091 Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 15 May 2017 07:35:19 +0200 Subject: [PATCH 033/103] Address review comments --- src/librustc_resolve/lib.rs | 10 ++++------ src/librustc_resolve/macros.rs | 14 +++++++------- src/libsyntax/ext/tt/macro_rules.rs | 6 ++---- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index f78dd4890e2..827d902de02 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1195,11 +1195,9 @@ pub struct Resolver<'a> { pub whitelisted_legacy_custom_derives: Vec, pub found_unresolved_macro: bool, - // List of macros that we need to warn about as being unused. - // The bool is true if the macro is unused, and false if its used. - // Setting a bool to false should be much faster than removing a single - // element from a FxHashSet. - unused_macros: FxHashMap, + // List of crate local macros that we need to warn about as being unused. + // Right now this only includes macro_rules! macros. + unused_macros: FxHashSet, // Maps the `Mark` of an expansion to its containing module or block. invocations: FxHashMap>, @@ -1406,7 +1404,7 @@ impl<'a> Resolver<'a> { potentially_unused_imports: Vec::new(), struct_constructors: DefIdMap(), found_unresolved_macro: false, - unused_macros: FxHashMap(), + unused_macros: FxHashSet(), } } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index f6155c6cafd..231d30cd2a2 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -291,24 +291,24 @@ impl<'a> base::Resolver for Resolver<'a> { }, }; self.macro_defs.insert(invoc.expansion_data.mark, def.def_id()); - self.unused_macros.get_mut(&def.def_id()).map(|m| *m = false); + self.unused_macros.remove(&def.def_id()); Ok(Some(self.get_macro(def))) } fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool) -> Result, Determinacy> { self.resolve_macro_to_def(scope, path, kind, force).map(|def| { - self.unused_macros.get_mut(&def.def_id()).map(|m| *m = false); + self.unused_macros.remove(&def.def_id()); self.get_macro(def) }) } fn check_unused_macros(&self) { - for (did, _) in self.unused_macros.iter().filter(|&(_, b)| *b) { + for did in self.unused_macros.iter() { let id_span = match *self.macro_map[did] { - SyntaxExtension::NormalTT(_, isp, _) => isp, - _ => None - }; + SyntaxExtension::NormalTT(_, isp, _) => isp, + _ => None, + }; if let Some((id, span)) = id_span { let lint = lint::builtin::UNUSED_MACROS; let msg = "unused macro definition".to_string(); @@ -708,7 +708,7 @@ impl<'a> Resolver<'a> { let def = Def::Macro(def_id, MacroKind::Bang); self.macro_exports.push(Export { name: ident.name, def: def, span: item.span }); } else { - self.unused_macros.insert(def_id, true); + self.unused_macros.insert(def_id); } } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 0c787dcbecb..39a60e5c080 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -252,11 +252,9 @@ pub fn compile(sess: &ParseSess, features: &RefCell, def: &ast::Item) valid: valid, }); - NormalTT( - exp, + NormalTT(exp, Some((def.id, def.span)), - attr::contains_name(&def.attrs, "allow_internal_unstable") - ) + attr::contains_name(&def.attrs, "allow_internal_unstable")) } fn check_lhs_nt_follows(sess: &ParseSess, From f92bd3dbd005bb0bbcdeb64eea263634428d660a Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Sun, 14 May 2017 20:06:54 +0200 Subject: [PATCH 034/103] Add links to the `thread::LocalKey` doc. Part of #29378 . --- src/libstd/thread/local.rs | 45 +++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index e2b22b1d89f..c2c6e6cf87d 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -19,16 +19,16 @@ use mem; /// A thread local storage key which owns its contents. /// /// This key uses the fastest possible implementation available to it for the -/// target platform. It is instantiated with the `thread_local!` macro and the -/// primary method is the `with` method. +/// target platform. It is instantiated with the [`thread_local!`] macro and the +/// primary method is the [`with`] method. /// -/// The `with` method yields a reference to the contained value which cannot be +/// The [`with`] method yields a reference to the contained value which cannot be /// sent across threads or escape the given closure. /// /// # Initialization and Destruction /// -/// Initialization is dynamically performed on the first call to `with()` -/// within a thread, and values that implement `Drop` get destructed when a +/// Initialization is dynamically performed on the first call to [`with`] +/// within a thread, and values that implement [`Drop`] get destructed when a /// thread exits. Some caveats apply, which are explained below. /// /// # Examples @@ -77,6 +77,10 @@ use mem; /// 3. On macOS, initializing TLS during destruction of other TLS slots can /// sometimes cancel *all* destructors for the current thread, whether or not /// the slots have already had their destructors run or not. +/// +/// [`with`]: ../../std/thread/struct.LocalKey.html#method.with +/// [`thread_local!`]: ../../std/macro.thread_local.html +/// [`Drop`]: ../../std/ops/trait.Drop.html #[stable(feature = "rust1", since = "1.0.0")] pub struct LocalKey { // This outer `LocalKey` type is what's going to be stored in statics, @@ -106,7 +110,7 @@ impl fmt::Debug for LocalKey { } } -/// Declare a new thread local storage key of type `std::thread::LocalKey`. +/// Declare a new thread local storage key of type [`std::thread::LocalKey`]. /// /// # Syntax /// @@ -124,8 +128,10 @@ impl fmt::Debug for LocalKey { /// # fn main() {} /// ``` /// -/// See [LocalKey documentation](thread/struct.LocalKey.html) for more +/// See [LocalKey documentation][`std::thread::LocalKey`] for more /// information. +/// +/// [`std::thread::LocalKey`]: ../std/thread/struct.LocalKey.html #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] #[allow_internal_unstable] @@ -195,11 +201,13 @@ macro_rules! __thread_local_inner { #[derive(Debug, Eq, PartialEq, Copy, Clone)] pub enum LocalKeyState { /// All keys are in this state whenever a thread starts. Keys will - /// transition to the `Valid` state once the first call to `with` happens + /// transition to the `Valid` state once the first call to [`with`] happens /// and the initialization expression succeeds. /// /// Keys in the `Uninitialized` state will yield a reference to the closure - /// passed to `with` so long as the initialization routine does not panic. + /// passed to [`with`] so long as the initialization routine does not panic. + /// + /// [`with`]: ../../std/thread/struct.LocalKey.html#method.with Uninitialized, /// Once a key has been accessed successfully, it will enter the `Valid` @@ -208,7 +216,9 @@ pub enum LocalKeyState { /// `Destroyed` state. /// /// Keys in the `Valid` state will be guaranteed to yield a reference to the - /// closure passed to `with`. + /// closure passed to [`with`]. + /// + /// [`with`]: ../../std/thread/struct.LocalKey.html#method.with Valid, /// When a thread exits, the destructors for keys will be run (if @@ -216,7 +226,9 @@ pub enum LocalKeyState { /// destructor has run, a key is in the `Destroyed` state. /// /// Keys in the `Destroyed` states will trigger a panic when accessed via - /// `with`. + /// [`with`]. + /// + /// [`with`]: ../../std/thread/struct.LocalKey.html#method.with Destroyed, } @@ -283,23 +295,26 @@ impl LocalKey { /// Query the current state of this key. /// /// A key is initially in the `Uninitialized` state whenever a thread - /// starts. It will remain in this state up until the first call to `with` + /// starts. It will remain in this state up until the first call to [`with`] /// within a thread has run the initialization expression successfully. /// /// Once the initialization expression succeeds, the key transitions to the - /// `Valid` state which will guarantee that future calls to `with` will + /// `Valid` state which will guarantee that future calls to [`with`] will /// succeed within the thread. /// /// When a thread exits, each key will be destroyed in turn, and as keys are /// destroyed they will enter the `Destroyed` state just before the /// destructor starts to run. Keys may remain in the `Destroyed` state after /// destruction has completed. Keys without destructors (e.g. with types - /// that are `Copy`), may never enter the `Destroyed` state. + /// that are [`Copy`]), may never enter the `Destroyed` state. /// /// Keys in the `Uninitialized` state can be accessed so long as the /// initialization does not panic. Keys in the `Valid` state are guaranteed /// to be able to be accessed. Keys in the `Destroyed` state will panic on - /// any call to `with`. + /// any call to [`with`]. + /// + /// [`with`]: ../../std/thread/struct.LocalKey.html#method.with + /// [`Copy`]: ../../std/marker/trait.Copy.html #[unstable(feature = "thread_local_state", reason = "state querying was recently added", issue = "27716")] From 8e4f3151166d8ddea2d365c589bf4ac7ab6f20c9 Mon Sep 17 00:00:00 2001 From: Robin Kruppe Date: Sun, 30 Apr 2017 20:04:35 +0200 Subject: [PATCH 035/103] Remove rustc_llvm dependency from librustc Consequently, session creation can no longer initialize LLVM. The few places that use the compiler without going through rustc_driver/CompilerCalls thus need to be careful to manually initialize LLVM (via rustc_trans!) immediately after session creation. This means librustc is not rebuilt when LLVM changes. --- src/Cargo.lock | 1 - src/librustc/Cargo.toml | 1 - src/librustc/lib.rs | 1 - src/librustc/session/mod.rs | 54 ---------------------------- src/librustc_driver/lib.rs | 2 ++ src/librustc_driver/test.rs | 1 + src/librustc_trans/lib.rs | 52 +++++++++++++++++++++++++++ src/librustdoc/core.rs | 1 + src/librustdoc/test.rs | 2 ++ src/test/run-make/issue-19371/foo.rs | 1 + 10 files changed, 59 insertions(+), 57 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index bd9fda42570..8bf360751c5 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -456,7 +456,6 @@ dependencies = [ "rustc_const_math 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", - "rustc_llvm 0.0.0", "serialize 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 3c762e43e9a..9d64f511914 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -19,7 +19,6 @@ rustc_bitflags = { path = "../librustc_bitflags" } rustc_const_math = { path = "../librustc_const_math" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } -rustc_llvm = { path = "../librustc_llvm" } serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index c979677ff71..f32ee790064 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -55,7 +55,6 @@ extern crate getopts; extern crate graphviz; extern crate libc; extern crate owning_ref; -extern crate rustc_llvm as llvm; extern crate rustc_back; extern crate rustc_data_structures; extern crate serialize; diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 2e2d5a6bd4d..814246330a4 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -37,19 +37,16 @@ use syntax_pos::{Span, MultiSpan, FileMap}; use rustc_back::{LinkerFlavor, PanicStrategy}; use rustc_back::target::Target; use rustc_data_structures::flock; -use llvm; use std::path::{Path, PathBuf}; use std::cell::{self, Cell, RefCell}; use std::collections::HashMap; use std::env; -use std::ffi::CString; use std::io::Write; use std::rc::Rc; use std::fmt; use std::time::Duration; use std::sync::Arc; -use libc::c_int; mod code_stats; pub mod config; @@ -713,8 +710,6 @@ pub fn build_session_(sopts: config::Options, out_of_fuel: Cell::new(false), }; - init_llvm(&sess); - sess } @@ -743,55 +738,6 @@ pub enum IncrCompSession { } } -fn init_llvm(sess: &Session) { - unsafe { - // Before we touch LLVM, make sure that multithreading is enabled. - use std::sync::Once; - static INIT: Once = Once::new(); - static mut POISONED: bool = false; - INIT.call_once(|| { - if llvm::LLVMStartMultithreaded() != 1 { - // use an extra bool to make sure that all future usage of LLVM - // cannot proceed despite the Once not running more than once. - POISONED = true; - } - - configure_llvm(sess); - }); - - if POISONED { - bug!("couldn't enable multi-threaded LLVM"); - } - } -} - -unsafe fn configure_llvm(sess: &Session) { - let mut llvm_c_strs = Vec::new(); - let mut llvm_args = Vec::new(); - - { - let mut add = |arg: &str| { - let s = CString::new(arg).unwrap(); - llvm_args.push(s.as_ptr()); - llvm_c_strs.push(s); - }; - add("rustc"); // fake program name - if sess.time_llvm_passes() { add("-time-passes"); } - if sess.print_llvm_passes() { add("-debug-pass=Structure"); } - - for arg in &sess.opts.cg.llvm_args { - add(&(*arg)); - } - } - - llvm::LLVMInitializePasses(); - - llvm::initialize_available_targets(); - - llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, - llvm_args.as_ptr()); -} - pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! { let emitter: Box = match output { config::ErrorOutputType::HumanReadable(color_config) => { diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 2dab680ad45..20eba802e85 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -211,6 +211,7 @@ pub fn run_compiler<'a>(args: &[String], let mut sess = session::build_session_with_codemap( sopts, &dep_graph, input_file_path, descriptions, cstore.clone(), codemap, emitter_dest, ); + rustc_trans::init(&sess); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let mut cfg = config::build_configuration(&sess, cfg); @@ -415,6 +416,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { None, descriptions.clone(), cstore.clone()); + rustc_trans::init(&sess); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let mut cfg = config::build_configuration(&sess, cfg.clone()); target_features::add_configuration(&mut cfg, &sess); diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index be4f64b7109..1d236a96bf6 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -112,6 +112,7 @@ fn test_env(source_string: &str, diagnostic_handler, Rc::new(CodeMap::new(FilePathMapping::empty())), cstore.clone()); + rustc_trans::init(&sess); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let input = config::Input::Str { name: driver::anon_src(), diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 15a1b32a5fd..d9552eb08b4 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -178,3 +178,55 @@ pub struct CrateTranslation { } __build_diagnostic_array! { librustc_trans, DIAGNOSTICS } + +use rustc::session::Session; +pub fn init(sess: &Session) { + unsafe { + // Before we touch LLVM, make sure that multithreading is enabled. + use std::sync::Once; + static INIT: Once = Once::new(); + static mut POISONED: bool = false; + INIT.call_once(|| { + if llvm::LLVMStartMultithreaded() != 1 { + // use an extra bool to make sure that all future usage of LLVM + // cannot proceed despite the Once not running more than once. + POISONED = true; + } + + configure_llvm(sess); + }); + + if POISONED { + bug!("couldn't enable multi-threaded LLVM"); + } + } +} + +use std::ffi::CString; +use libc::c_int; +unsafe fn configure_llvm(sess: &Session) { + let mut llvm_c_strs = Vec::new(); + let mut llvm_args = Vec::new(); + + { + let mut add = |arg: &str| { + let s = CString::new(arg).unwrap(); + llvm_args.push(s.as_ptr()); + llvm_c_strs.push(s); + }; + add("rustc"); // fake program name + if sess.time_llvm_passes() { add("-time-passes"); } + if sess.print_llvm_passes() { add("-debug-pass=Structure"); } + + for arg in &sess.opts.cg.llvm_args { + add(&(*arg)); + } + } + + llvm::LLVMInitializePasses(); + + llvm::initialize_available_targets(); + + llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, + llvm_args.as_ptr()); +} diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index d41e9931409..9a689ed079e 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -143,6 +143,7 @@ pub fn run_core(search_paths: SearchPaths, let mut sess = session::build_session_( sessopts, &dep_graph, cpath, diagnostic_handler, codemap, cstore.clone() ); + rustc_trans::init(&sess); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let mut cfg = config::build_configuration(&sess, config::parse_cfgspecs(cfgs)); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 0600ae5b66e..cfe2fad0fa4 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -86,6 +86,7 @@ pub fn run(input: &str, let mut sess = session::build_session_( sessopts, &dep_graph, Some(input_path.clone()), handler, codemap.clone(), cstore.clone(), ); + rustc_trans::init(&sess); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); sess.parse_sess.config = config::build_configuration(&sess, config::parse_cfgspecs(cfgs.clone())); @@ -234,6 +235,7 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec, libs: SearchPaths, let mut sess = session::build_session_( sessopts, &dep_graph, None, diagnostic_handler, codemap, cstore.clone(), ); + rustc_trans::init(&sess); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let outdir = Mutex::new(TempDir::new("rustdoctest").ok().expect("rustdoc needs a tempdir")); diff --git a/src/test/run-make/issue-19371/foo.rs b/src/test/run-make/issue-19371/foo.rs index 74ecdab3372..e96588c6e5a 100644 --- a/src/test/run-make/issue-19371/foo.rs +++ b/src/test/run-make/issue-19371/foo.rs @@ -61,6 +61,7 @@ fn basic_sess(sysroot: PathBuf) -> (Session, Rc) { let dep_graph = DepGraph::new(opts.build_dep_graph()); let cstore = Rc::new(CStore::new(&dep_graph, Box::new(rustc_trans::LlvmMetadataLoader))); let sess = build_session(opts, &dep_graph, None, descriptions, cstore.clone()); + rustc_trans::init(&sess); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); (sess, cstore) } From e3f6e68d633040be0b88a0e11e6645bc506f8655 Mon Sep 17 00:00:00 2001 From: Robin Kruppe Date: Sun, 30 Apr 2017 20:33:25 +0200 Subject: [PATCH 036/103] Remove (direct) rustc_llvm dependency from rustc_driver This does not actually improve build times, since it still depends on rustc_trans, but is better layering and fits the multi-backend future slightly better. --- src/Cargo.lock | 1 - src/librustc/session/config.rs | 2 +- src/librustc_driver/Cargo.toml | 1 - src/librustc_driver/lib.rs | 25 ++--- src/librustc_driver/target_features.rs | 34 +------ src/librustc_trans/lib.rs | 54 +---------- src/librustc_trans/llvm_util.rs | 125 +++++++++++++++++++++++++ 7 files changed, 139 insertions(+), 103 deletions(-) create mode 100644 src/librustc_trans/llvm_util.rs diff --git a/src/Cargo.lock b/src/Cargo.lock index 8bf360751c5..05b99b07007 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -560,7 +560,6 @@ dependencies = [ "rustc_errors 0.0.0", "rustc_incremental 0.0.0", "rustc_lint 0.0.0", - "rustc_llvm 0.0.0", "rustc_metadata 0.0.0", "rustc_mir 0.0.0", "rustc_passes 0.0.0", diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 884a71f0d32..4212fa1f8b1 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -328,7 +328,7 @@ top_level_options!( } ); -#[derive(Clone, PartialEq, Eq)] +#[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum PrintRequest { FileNames, Sysroot, diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index 5b5113caa8e..2e949f48c17 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -22,7 +22,6 @@ rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } rustc_incremental = { path = "../librustc_incremental" } rustc_lint = { path = "../librustc_lint" } -rustc_llvm = { path = "../librustc_llvm" } rustc_metadata = { path = "../librustc_metadata" } rustc_mir = { path = "../librustc_mir" } rustc_passes = { path = "../librustc_passes" } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 20eba802e85..34f636d0b9a 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -56,7 +56,6 @@ extern crate rustc_save_analysis; extern crate rustc_trans; extern crate rustc_typeck; extern crate serialize; -extern crate rustc_llvm as llvm; #[macro_use] extern crate log; extern crate syntax; @@ -70,7 +69,7 @@ use rustc_resolve as resolve; use rustc_save_analysis as save; use rustc_save_analysis::DumpHandler; use rustc_trans::back::link; -use rustc_trans::back::write::{create_target_machine, RELOC_MODEL_ARGS, CODE_GEN_MODEL_ARGS}; +use rustc_trans::back::write::{RELOC_MODEL_ARGS, CODE_GEN_MODEL_ARGS}; use rustc::dep_graph::DepGraph; use rustc::session::{self, config, Session, build_session, CompileResult}; use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType}; @@ -182,7 +181,7 @@ pub fn run_compiler<'a>(args: &[String], let (sopts, cfg) = config::build_session_options_and_crate_config(&matches); if sopts.debugging_opts.debug_llvm { - unsafe { llvm::LLVMRustSetDebug(1); } + rustc_trans::enable_llvm_debug(); } let descriptions = diagnostics_registry(); @@ -671,14 +670,6 @@ impl RustcDefaultCalls { println!("{}", cfg); } } - PrintRequest::TargetCPUs => { - let tm = create_target_machine(sess); - unsafe { llvm::LLVMRustPrintTargetCPUs(tm); } - } - PrintRequest::TargetFeatures => { - let tm = create_target_machine(sess); - unsafe { llvm::LLVMRustPrintTargetFeatures(tm); } - } PrintRequest::RelocationModels => { println!("Available relocation models:"); for &(name, _) in RELOC_MODEL_ARGS.iter() { @@ -693,6 +684,9 @@ impl RustcDefaultCalls { } println!(""); } + PrintRequest::TargetCPUs | PrintRequest::TargetFeatures => { + rustc_trans::print(*req, sess); + } } } return Compilation::Stop; @@ -730,10 +724,7 @@ pub fn version(binary: &str, matches: &getopts::Matches) { println!("commit-date: {}", unw(commit_date_str())); println!("host: {}", config::host_triple()); println!("release: {}", unw(release_str())); - unsafe { - println!("LLVM version: {}.{}", - llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor()); - } + rustc_trans::print_version(); } } @@ -1026,9 +1017,7 @@ pub fn handle_options(args: &[String]) -> Option { } if cg_flags.contains(&"passes=list".to_string()) { - unsafe { - ::llvm::LLVMRustPrintPasses(); - } + rustc_trans::print_passes(); return None; } diff --git a/src/librustc_driver/target_features.rs b/src/librustc_driver/target_features.rs index 61bc7c6eb4c..bee61bb3980 100644 --- a/src/librustc_driver/target_features.rs +++ b/src/librustc_driver/target_features.rs @@ -9,24 +9,9 @@ // except according to those terms. use syntax::ast; -use llvm::LLVMRustHasFeature; use rustc::session::Session; -use rustc_trans::back::write::create_target_machine; use syntax::symbol::Symbol; -use libc::c_char; - -// WARNING: the features must be known to LLVM or the feature -// detection code will walk past the end of the feature array, -// leading to crashes. - -const ARM_WHITELIST: &'static [&'static str] = &["neon\0", "vfp2\0", "vfp3\0", "vfp4\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"]; - -const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"]; +use rustc_trans; /// Add `target_feature = "..."` cfgs for a variety of platform /// specific features (SSE, NEON etc.). @@ -34,21 +19,10 @@ const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"]; /// This is performed by checking whether a whitelisted set of /// features is available on the target machine, by querying LLVM. pub fn add_configuration(cfg: &mut ast::CrateConfig, sess: &Session) { - let target_machine = create_target_machine(sess); - - let whitelist = match &*sess.target.target.arch { - "arm" => ARM_WHITELIST, - "x86" | "x86_64" => X86_WHITELIST, - "hexagon" => HEXAGON_WHITELIST, - _ => &[], - }; - let tf = Symbol::intern("target_feature"); - for feat in whitelist { - assert_eq!(feat.chars().last(), Some('\0')); - if unsafe { LLVMRustHasFeature(target_machine, feat.as_ptr() as *const c_char) } { - cfg.insert((tf, Some(Symbol::intern(&feat[..feat.len() - 1])))); - } + + for feat in rustc_trans::target_features(sess) { + cfg.insert((tf, Some(feat))); } let requested_features = sess.opts.cg.target_feature.split(','); diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index d9552eb08b4..3ac0d88b90d 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -72,6 +72,7 @@ pub use base::trans_crate; pub use back::symbol_names::provide; pub use metadata::LlvmMetadataLoader; +pub use llvm_util::{init, target_features, print_version, print_passes, print, enable_llvm_debug}; pub mod back { pub use rustc::hir::svh; @@ -122,6 +123,7 @@ mod debuginfo; mod declare; mod glue; mod intrinsic; +mod llvm_util; mod machine; mod metadata; mod meth; @@ -178,55 +180,3 @@ pub struct CrateTranslation { } __build_diagnostic_array! { librustc_trans, DIAGNOSTICS } - -use rustc::session::Session; -pub fn init(sess: &Session) { - unsafe { - // Before we touch LLVM, make sure that multithreading is enabled. - use std::sync::Once; - static INIT: Once = Once::new(); - static mut POISONED: bool = false; - INIT.call_once(|| { - if llvm::LLVMStartMultithreaded() != 1 { - // use an extra bool to make sure that all future usage of LLVM - // cannot proceed despite the Once not running more than once. - POISONED = true; - } - - configure_llvm(sess); - }); - - if POISONED { - bug!("couldn't enable multi-threaded LLVM"); - } - } -} - -use std::ffi::CString; -use libc::c_int; -unsafe fn configure_llvm(sess: &Session) { - let mut llvm_c_strs = Vec::new(); - let mut llvm_args = Vec::new(); - - { - let mut add = |arg: &str| { - let s = CString::new(arg).unwrap(); - llvm_args.push(s.as_ptr()); - llvm_c_strs.push(s); - }; - add("rustc"); // fake program name - if sess.time_llvm_passes() { add("-time-passes"); } - if sess.print_llvm_passes() { add("-debug-pass=Structure"); } - - for arg in &sess.opts.cg.llvm_args { - add(&(*arg)); - } - } - - llvm::LLVMInitializePasses(); - - llvm::initialize_available_targets(); - - llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, - llvm_args.as_ptr()); -} diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs new file mode 100644 index 00000000000..0f4c6b64080 --- /dev/null +++ b/src/librustc_trans/llvm_util.rs @@ -0,0 +1,125 @@ +// 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. + +use syntax_pos::symbol::Symbol; +use back::write::create_target_machine; +use llvm; +use rustc::session::Session; +use rustc::session::config::PrintRequest; +use libc::{c_int, c_char}; +use std::ffi::CString; + +pub fn init(sess: &Session) { + unsafe { + // Before we touch LLVM, make sure that multithreading is enabled. + use std::sync::Once; + static INIT: Once = Once::new(); + static mut POISONED: bool = false; + INIT.call_once(|| { + if llvm::LLVMStartMultithreaded() != 1 { + // use an extra bool to make sure that all future usage of LLVM + // cannot proceed despite the Once not running more than once. + POISONED = true; + } + + configure_llvm(sess); + }); + + if POISONED { + bug!("couldn't enable multi-threaded LLVM"); + } + } +} + +unsafe fn configure_llvm(sess: &Session) { + let mut llvm_c_strs = Vec::new(); + let mut llvm_args = Vec::new(); + + { + let mut add = |arg: &str| { + let s = CString::new(arg).unwrap(); + llvm_args.push(s.as_ptr()); + llvm_c_strs.push(s); + }; + add("rustc"); // fake program name + if sess.time_llvm_passes() { add("-time-passes"); } + if sess.print_llvm_passes() { add("-debug-pass=Structure"); } + + for arg in &sess.opts.cg.llvm_args { + add(&(*arg)); + } + } + + llvm::LLVMInitializePasses(); + + llvm::initialize_available_targets(); + + llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, + llvm_args.as_ptr()); +} + +// WARNING: the features must be known to LLVM or the feature +// detection code will walk past the end of the feature array, +// leading to crashes. + +const ARM_WHITELIST: &'static [&'static str] = &["neon\0", "vfp2\0", "vfp3\0", "vfp4\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"]; + +const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"]; + +pub fn target_features(sess: &Session) -> Vec { + let target_machine = create_target_machine(sess); + + let whitelist = match &*sess.target.target.arch { + "arm" => ARM_WHITELIST, + "x86" | "x86_64" => X86_WHITELIST, + "hexagon" => HEXAGON_WHITELIST, + _ => &[], + }; + + let mut features = Vec::new(); + for feat in whitelist { + assert_eq!(feat.chars().last(), Some('\0')); + if unsafe { llvm::LLVMRustHasFeature(target_machine, feat.as_ptr() as *const c_char) } { + features.push(Symbol::intern(&feat[..feat.len() - 1])); + } + } + features +} + +pub fn print_version() { + unsafe { + println!("LLVM version: {}.{}", + llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor()); + } +} + +pub fn print_passes() { + unsafe { llvm::LLVMRustPrintPasses(); } +} + +pub fn print(req: PrintRequest, sess: &Session) { + let tm = create_target_machine(sess); + unsafe { + match req { + PrintRequest::TargetCPUs => llvm::LLVMRustPrintTargetCPUs(tm), + PrintRequest::TargetFeatures => llvm::LLVMRustPrintTargetFeatures(tm), + _ => bug!("rustc_trans can't handle print request: {:?}", req), + } + } +} + +pub fn enable_llvm_debug() { + unsafe { llvm::LLVMRustSetDebug(1); } +} From acdeedc19253130798916a8bb20651657d9f01e5 Mon Sep 17 00:00:00 2001 From: Robin Kruppe Date: Sun, 14 May 2017 20:33:37 +0200 Subject: [PATCH 037/103] Use AtomicBool instead of a 'static mut' for LLVM init posioning --- src/librustc_trans/llvm_util.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs index 0f4c6b64080..15f56036b0c 100644 --- a/src/librustc_trans/llvm_util.rs +++ b/src/librustc_trans/llvm_util.rs @@ -16,23 +16,25 @@ use rustc::session::config::PrintRequest; use libc::{c_int, c_char}; use std::ffi::CString; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Once; + pub fn init(sess: &Session) { unsafe { // Before we touch LLVM, make sure that multithreading is enabled. - use std::sync::Once; + static POISONED: AtomicBool = AtomicBool::new(false); static INIT: Once = Once::new(); - static mut POISONED: bool = false; INIT.call_once(|| { if llvm::LLVMStartMultithreaded() != 1 { // use an extra bool to make sure that all future usage of LLVM // cannot proceed despite the Once not running more than once. - POISONED = true; + POISONED.store(true, Ordering::SeqCst); } configure_llvm(sess); }); - if POISONED { + if POISONED.load(Ordering::SeqCst) { bug!("couldn't enable multi-threaded LLVM"); } } From 9f4e1e10a48f54738b373f4be3667d8f1a8cc2c7 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Mon, 15 May 2017 09:26:26 +0000 Subject: [PATCH 038/103] Fix regression in `macro_rules!` name matching. --- src/libsyntax/ext/tt/macro_parser.rs | 11 +++++----- src/test/run-pass/issue-41803.rs | 30 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 src/test/run-pass/issue-41803.rs diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index eb0b7c29f8d..780b7ec8c2a 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -267,11 +267,12 @@ pub fn parse_failure_msg(tok: Token) -> String { /// Perform a token equality check, ignoring syntax context (that is, an unhygienic comparison) fn token_name_eq(t1 : &Token, t2 : &Token) -> bool { - match (t1,t2) { - (&token::Ident(id1),&token::Ident(id2)) - | (&token::Lifetime(id1),&token::Lifetime(id2)) => - id1.name == id2.name, - _ => *t1 == *t2 + if let (Some(id1), Some(id2)) = (t1.ident(), t2.ident()) { + id1.name == id2.name + } else if let (&token::Lifetime(id1), &token::Lifetime(id2)) = (t1, t2) { + id1.name == id2.name + } else { + *t1 == *t2 } } diff --git a/src/test/run-pass/issue-41803.rs b/src/test/run-pass/issue-41803.rs new file mode 100644 index 00000000000..e18b4204584 --- /dev/null +++ b/src/test/run-pass/issue-41803.rs @@ -0,0 +1,30 @@ +// 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. + +/// A compile-time map from identifiers to arbitrary (heterogeneous) expressions +macro_rules! ident_map { + ( $name:ident = { $($key:ident => $e:expr,)* } ) => { + macro_rules! $name { + $( + ( $key ) => { $e }; + )* + // Empty invocation expands to nothing. Needed when the map is empty. + () => {}; + } + }; +} + +ident_map!(my_map = { + main => 0, +}); + +fn main() { + my_map!(main); +} From 4f2f27014de578c26478848fc746182e22413540 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Mon, 15 May 2017 09:41:05 +0000 Subject: [PATCH 039/103] Fix regression on `include!(line!())`. --- src/libsyntax/ext/base.rs | 4 ++-- src/libsyntax/ext/source_util.rs | 6 +++--- src/test/compile-fail/issue-41776.rs | 13 +++++++++++++ 3 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 src/test/compile-fail/issue-41776.rs diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index fda026fec64..1f279cc9c80 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -695,7 +695,7 @@ impl<'a> ExtCtxt<'a> { /// Returns span for the macro which originally caused the current expansion to happen. /// /// Stops backtracing at include! boundary. - pub fn expansion_cause(&self) -> Span { + pub fn expansion_cause(&self) -> Option { let mut ctxt = self.backtrace(); let mut last_macro = None; loop { @@ -711,7 +711,7 @@ impl<'a> ExtCtxt<'a> { break } } - last_macro.expect("missing expansion backtrace") + last_macro } pub fn struct_span_warn(&self, diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 22a5776315a..fc557a78dda 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -35,7 +35,7 @@ pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree]) -> Box { base::check_zero_tts(cx, sp, tts, "line!"); - let topmost = cx.expansion_cause(); + let topmost = cx.expansion_cause().unwrap_or(sp); let loc = cx.codemap().lookup_char_pos(topmost.lo); base::MacEager::expr(cx.expr_u32(topmost, loc.line as u32)) @@ -46,7 +46,7 @@ pub fn expand_column(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree]) -> Box { base::check_zero_tts(cx, sp, tts, "column!"); - let topmost = cx.expansion_cause(); + let topmost = cx.expansion_cause().unwrap_or(sp); let loc = cx.codemap().lookup_char_pos(topmost.lo); base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32)) @@ -59,7 +59,7 @@ pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::TokenTree]) -> Box { base::check_zero_tts(cx, sp, tts, "file!"); - let topmost = cx.expansion_cause(); + let topmost = cx.expansion_cause().unwrap_or(sp); let loc = cx.codemap().lookup_char_pos(topmost.lo); base::MacEager::expr(cx.expr_str(topmost, Symbol::intern(&loc.file.name))) } diff --git a/src/test/compile-fail/issue-41776.rs b/src/test/compile-fail/issue-41776.rs new file mode 100644 index 00000000000..5f108e0a1ed --- /dev/null +++ b/src/test/compile-fail/issue-41776.rs @@ -0,0 +1,13 @@ +// 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. + +fn main() { + include!(line!()); //~ ERROR argument must be a string literal +} From 04a16ff5acaaccf6332f706f090442f0ab9b0f95 Mon Sep 17 00:00:00 2001 From: Robin Kruppe Date: Mon, 15 May 2017 15:09:05 +0200 Subject: [PATCH 040/103] Fix run-make/llvm-pass --- src/test/run-make/llvm-pass/plugin.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/run-make/llvm-pass/plugin.rs b/src/test/run-make/llvm-pass/plugin.rs index f77b2fca857..37aab2bbd05 100644 --- a/src/test/run-make/llvm-pass/plugin.rs +++ b/src/test/run-make/llvm-pass/plugin.rs @@ -14,6 +14,7 @@ extern crate rustc; extern crate rustc_plugin; +extern crate rustc_trans; #[link(name = "llvm-function-pass", kind = "static")] #[link(name = "llvm-module-pass", kind = "static")] From c2d9b4e3349552ec0bf53e3fc7a1f509d449b210 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 8 May 2017 23:36:37 +0200 Subject: [PATCH 041/103] ICH: Hash lists of local trait impls as part of the HIR. --- src/librustc/dep_graph/dep_node.rs | 3 + src/librustc/hir/map/mod.rs | 4 +- src/librustc/ich/fingerprint.rs | 8 +++ src/librustc/ich/hcx.rs | 24 +++++++- src/librustc/ich/mod.rs | 3 +- src/librustc_incremental/calculate_svh/mod.rs | 55 ++++++++++++++++++- src/librustc_metadata/creader.rs | 9 +++ src/librustc_metadata/cstore.rs | 2 + src/librustc_metadata/cstore_impl.rs | 4 +- src/librustc_metadata/decoder.rs | 18 +++--- src/librustc_metadata/schema.rs | 14 +++++ 11 files changed, 127 insertions(+), 17 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 25fc5b7a4f6..93dd76a6984 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -116,6 +116,8 @@ pub enum DepNode { // than changes in the impl body. TraitImpls(D), + AllLocalTraitImpls, + // Nodes representing caches. To properly handle a true cache, we // don't use a DepTrackingMap, but rather we push a task node. // Otherwise the write into the map would be incorrectly @@ -263,6 +265,7 @@ impl DepNode { ConstEval(ref d) => op(d).map(ConstEval), SymbolName(ref d) => op(d).map(SymbolName), TraitImpls(ref d) => op(d).map(TraitImpls), + AllLocalTraitImpls => Some(AllLocalTraitImpls), TraitItems(ref d) => op(d).map(TraitItems), ReprHints(ref d) => op(d).map(ReprHints), TraitSelect { ref trait_def_id, ref input_def_id } => { diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index c715484a934..868730edfed 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -497,7 +497,7 @@ impl<'hir> Map<'hir> { } pub fn trait_impls(&self, trait_did: DefId) -> &'hir [NodeId] { - self.dep_graph.read(DepNode::TraitImpls(trait_did)); + self.dep_graph.read(DepNode::AllLocalTraitImpls); // NB: intentionally bypass `self.forest.krate()` so that we // do not trigger a read of the whole krate here @@ -505,7 +505,7 @@ impl<'hir> Map<'hir> { } pub fn trait_default_impl(&self, trait_did: DefId) -> Option { - self.dep_graph.read(DepNode::TraitImpls(trait_did)); + self.dep_graph.read(DepNode::AllLocalTraitImpls); // NB: intentionally bypass `self.forest.krate()` so that we // do not trigger a read of the whole krate here diff --git a/src/librustc/ich/fingerprint.rs b/src/librustc/ich/fingerprint.rs index e760f7efc93..ccdbab88b8b 100644 --- a/src/librustc/ich/fingerprint.rs +++ b/src/librustc/ich/fingerprint.rs @@ -94,3 +94,11 @@ impl stable_hasher::StableHasherResult for Fingerprint { fingerprint } } + +impl stable_hasher::HashStable for Fingerprint { + fn hash_stable(&self, + _: &mut CTX, + hasher: &mut stable_hasher::StableHasher) { + ::std::hash::Hash::hash(&self.0, hasher); + } +} diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 3a6367c353c..786d1c5035d 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -16,7 +16,7 @@ use ty; use util::nodemap::NodeMap; use std::hash as std_hash; -use std::collections::{HashMap, HashSet}; +use std::collections::{HashMap, HashSet, BTreeMap}; use syntax::ast; use syntax::attr; @@ -348,3 +348,25 @@ pub fn hash_stable_nodemap<'a, 'tcx, V, W>(hcx: &mut StableHashingContext<'a, 't hcx.tcx.hir.definitions().node_to_hir_id(*node_id).local_id }); } + + +pub fn hash_stable_btreemap<'a, 'tcx, K, V, SK, F, W>(hcx: &mut StableHashingContext<'a, 'tcx>, + hasher: &mut StableHasher, + map: &BTreeMap, + extract_stable_key: F) + where K: Eq + Ord, + V: HashStable>, + SK: HashStable> + Ord + Clone, + F: Fn(&mut StableHashingContext<'a, 'tcx>, &K) -> SK, + W: StableHasherResult, +{ + let mut keys: Vec<_> = map.keys() + .map(|k| (extract_stable_key(hcx, k), k)) + .collect(); + keys.sort_unstable_by_key(|&(ref stable_key, _)| stable_key.clone()); + keys.len().hash_stable(hcx, hasher); + for (stable_key, key) in keys { + stable_key.hash_stable(hcx, hasher); + map[key].hash_stable(hcx, hasher); + } +} diff --git a/src/librustc/ich/mod.rs b/src/librustc/ich/mod.rs index d881a1cc45a..5b238090850 100644 --- a/src/librustc/ich/mod.rs +++ b/src/librustc/ich/mod.rs @@ -13,7 +13,8 @@ pub use self::fingerprint::Fingerprint; pub use self::caching_codemap_view::CachingCodemapView; pub use self::hcx::{StableHashingContext, NodeIdHashingMode, hash_stable_hashmap, - hash_stable_hashset, hash_stable_nodemap}; + hash_stable_hashset, hash_stable_nodemap, + hash_stable_btreemap}; mod fingerprint; mod caching_codemap_view; mod hcx; diff --git a/src/librustc_incremental/calculate_svh/mod.rs b/src/librustc_incremental/calculate_svh/mod.rs index 6f5cc1f3f45..8cdabc1d894 100644 --- a/src/librustc_incremental/calculate_svh/mod.rs +++ b/src/librustc_incremental/calculate_svh/mod.rs @@ -36,9 +36,10 @@ use rustc::hir::def_id::{LOCAL_CRATE, CRATE_DEF_INDEX, DefId}; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::ich::{Fingerprint, StableHashingContext}; use rustc::ty::TyCtxt; +use rustc::util::common::record_time; use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; use rustc_data_structures::fx::FxHashMap; -use rustc::util::common::record_time; +use rustc_data_structures::accumulate_vec::AccumulateVec; pub type IchHasher = StableHasher; @@ -159,6 +160,11 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { // difference, filter them out. return None } + DepNode::AllLocalTraitImpls => { + // These are already covered by hashing + // the HIR. + return None + } ref other => { bug!("Found unexpected DepNode during \ SVH computation: {:?}", @@ -213,6 +219,49 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { true, (module, (span, attrs))); } + + fn compute_and_store_ich_for_trait_impls(&mut self, krate: &'tcx hir::Crate) + { + let tcx = self.hcx.tcx(); + + let mut impls: Vec<(u64, Fingerprint)> = krate + .trait_impls + .iter() + .map(|(&trait_id, impls)| { + let trait_id = tcx.def_path_hash(trait_id); + let mut impls: AccumulateVec<[_; 32]> = impls + .iter() + .map(|&node_id| { + let def_id = tcx.hir.local_def_id(node_id); + tcx.def_path_hash(def_id) + }) + .collect(); + + impls.sort_unstable(); + let mut hasher = StableHasher::new(); + impls.hash_stable(&mut self.hcx, &mut hasher); + (trait_id, hasher.finish()) + }) + .collect(); + + impls.sort_unstable(); + + let mut default_impls: AccumulateVec<[_; 32]> = krate + .trait_default_impl + .iter() + .map(|(&trait_def_id, &impl_node_id)| { + let impl_def_id = tcx.hir.local_def_id(impl_node_id); + (tcx.def_path_hash(trait_def_id), tcx.def_path_hash(impl_def_id)) + }) + .collect(); + + default_impls.sort_unstable(); + + let mut hasher = StableHasher::new(); + impls.hash_stable(&mut self.hcx, &mut hasher); + + self.hashes.insert(DepNode::AllLocalTraitImpls, hasher.finish()); + } } impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for ComputeItemHashesVisitor<'a, 'tcx> { @@ -235,6 +284,8 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for ComputeItemHashesVisitor<'a, 'tcx> } } + + pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> IncrementalHashesMap { let _ignore = tcx.dep_graph.in_ignore(); @@ -272,6 +323,8 @@ pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) let fingerprint = hasher.finish(); visitor.hashes.insert(dep_node, fingerprint); } + + visitor.compute_and_store_ich_for_trait_impls(krate); }); tcx.sess.perf_stats.incr_comp_hashes_count.set(visitor.hashes.len() as u64); diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index d2874f16289..54f09a0f319 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -315,11 +315,20 @@ impl<'a> CrateLoader<'a> { let exported_symbols = crate_root.exported_symbols .map(|x| x.decode(&metadata).collect()); + let trait_impls = crate_root + .impls + .map(|impls| { + impls.decode(&metadata) + .map(|trait_impls| (trait_impls.trait_id, trait_impls.impls)) + .collect() + }); + let mut cmeta = cstore::CrateMetadata { name: name, extern_crate: Cell::new(None), def_path_table: def_path_table, exported_symbols: exported_symbols, + trait_impls: trait_impls, proc_macros: crate_root.macro_derive_registrar.map(|_| { self.load_derive_macros(&crate_root, dylib.clone().map(|p| p.0), span) }), diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index c12b4209675..4e70387c8b0 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -85,6 +85,8 @@ pub struct CrateMetadata { pub exported_symbols: Tracked>, + pub trait_impls: Tracked>>, + pub dep_kind: Cell, pub source: CrateSource, diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index dbf3e94832f..d42aab60c6e 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -147,10 +147,8 @@ impl CrateStore for cstore::CStore { fn implementations_of_trait(&self, filter: Option) -> Vec { - if let Some(def_id) = filter { - self.dep_graph.read(DepNode::MetaData(def_id)); - } let mut result = vec![]; + self.iter_crate_data(|_, cdata| { cdata.get_implementations_for_trait(filter, &self.dep_graph, &mut result) }); diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 819095e2628..51822474254 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -961,17 +961,17 @@ impl<'a, 'tcx> CrateMetadata { None => None, }; - // FIXME(eddyb) Make this O(1) instead of O(n). let dep_node = self.metadata_dep_node(GlobalMetaDataKind::Impls); - for trait_impls in self.root.impls.get(dep_graph, dep_node).decode(self) { - if filter.is_some() && filter != Some(trait_impls.trait_id) { - continue; + + if let Some(filter) = filter { + if let Some(impls) = self.trait_impls + .get(dep_graph, dep_node) + .get(&filter) { + result.extend(impls.decode(self).map(|idx| self.local_def_id(idx))); } - - result.extend(trait_impls.impls.decode(self).map(|index| self.local_def_id(index))); - - if filter.is_some() { - break; + } else { + for impls in self.trait_impls.get(dep_graph, dep_node).values() { + result.extend(impls.decode(self).map(|idx| self.local_def_id(idx))); } } } diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 5abe1adfb6f..91a22d92219 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -221,6 +221,20 @@ impl Tracked { } } +impl<'a, 'tcx, T> HashStable> for Tracked + where T: HashStable> +{ + fn hash_stable(&self, + hcx: &mut StableHashingContext<'a, 'tcx>, + hasher: &mut StableHasher) { + let Tracked { + ref state + } = *self; + + state.hash_stable(hcx, hasher); + } +} + #[derive(RustcEncodable, RustcDecodable)] pub struct CrateRoot { From 513cc6d538885959f504b2fba4f613d2b9690a4c Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 11 May 2017 15:46:22 +0200 Subject: [PATCH 042/103] Make incr. comp. test case dependent on specific ICH instead of SVH --- .../remapped_paths_cc/auxiliary/extern_crate.rs | 7 +++---- src/test/incremental/remapped_paths_cc/main.rs | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/test/incremental/remapped_paths_cc/auxiliary/extern_crate.rs b/src/test/incremental/remapped_paths_cc/auxiliary/extern_crate.rs index 09db90d618b..9feefb4c037 100644 --- a/src/test/incremental/remapped_paths_cc/auxiliary/extern_crate.rs +++ b/src/test/incremental/remapped_paths_cc/auxiliary/extern_crate.rs @@ -10,10 +10,9 @@ // ignore-tidy-linelength -// aux-build:extern_crate.rs -//[rpass1] compile-flags: -g -//[rpass2] compile-flags: -g -//[rpass3] compile-flags: -g -Zremap-path-prefix-from={{src-base}} -Zremap-path-prefix-to=/the/src +//[rpass1] compile-flags: -g -Zincremental-cc +//[rpass2] compile-flags: -g -Zincremental-cc +//[rpass3] compile-flags: -g -Zincremental-cc -Zremap-path-prefix-from={{src-base}} -Zremap-path-prefix-to=/the/src #![feature(rustc_attrs)] #![crate_type="rlib"] diff --git a/src/test/incremental/remapped_paths_cc/main.rs b/src/test/incremental/remapped_paths_cc/main.rs index 8a8c658accc..be4764c7d99 100644 --- a/src/test/incremental/remapped_paths_cc/main.rs +++ b/src/test/incremental/remapped_paths_cc/main.rs @@ -9,7 +9,7 @@ // except according to those terms. // revisions:rpass1 rpass2 rpass3 -// compile-flags: -Z query-dep-graph -g +// compile-flags: -Z query-dep-graph -g -Zincremental-cc // aux-build:extern_crate.rs From 77b7df33077aedfe8df903f95165872243f4acd4 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 11 May 2017 15:47:15 +0200 Subject: [PATCH 043/103] Fix instability in GlobalMetadata::Impls ICH. --- src/librustc_metadata/encoder.rs | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index fa4ebed1618..93fcdc455e5 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -943,7 +943,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { let trait_ref = tcx.impl_trait_ref(def_id); let parent = if let Some(trait_ref) = trait_ref { let trait_def = tcx.trait_def(trait_ref.def_id); - trait_def.ancestors(def_id).skip(1).next().and_then(|node| { + trait_def.ancestors(tcx, def_id).skip(1).next().and_then(|node| { match node { specialization_graph::Node::Impl(parent) => Some(parent), _ => None, @@ -1295,23 +1295,37 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { /// Encodes an index, mapping each trait to its (local) implementations. fn encode_impls(&mut self, _: ()) -> LazySeq { + debug!("IsolatedEncoder::encode_impls()"); + let tcx = self.tcx; let mut visitor = ImplVisitor { - tcx: self.tcx, + tcx: tcx, impls: FxHashMap(), }; - self.tcx.hir.krate().visit_all_item_likes(&mut visitor); + tcx.hir.krate().visit_all_item_likes(&mut visitor); - let all_impls: Vec<_> = visitor.impls + let mut all_impls: Vec<_> = visitor.impls.into_iter().collect(); + + // Bring everything into deterministic order for hashing + all_impls.sort_unstable_by_key(|&(trait_def_id, _)| { + tcx.def_path_hash(trait_def_id) + }); + + let all_impls: Vec<_> = all_impls .into_iter() - .map(|(trait_def_id, impls)| { + .map(|(trait_def_id, mut impls)| { + // Bring everything into deterministic order for hashing + impls.sort_unstable_by_key(|&def_index| { + tcx.hir.definitions().def_path_hash(def_index) + }); + TraitImpls { trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index), - impls: self.lazy_seq(impls), + impls: self.lazy_seq_from_slice(&impls[..]), } }) .collect(); - self.lazy_seq(all_impls) + self.lazy_seq_from_slice(&all_impls[..]) } // Encodes all symbols exported from this crate into the metadata. From 8da2fe8ed72cc9960f4043867fc55c2b4bc4a3e3 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 11 May 2017 16:01:19 +0200 Subject: [PATCH 044/103] Remove interior mutability from TraitDef by turning fields into queries. --- src/librustc/dep_graph/dep_node.rs | 4 + src/librustc/diagnostics.rs | 61 ++++ src/librustc/traits/mod.rs | 18 +- src/librustc/traits/object_safety.rs | 25 +- src/librustc/traits/project.rs | 21 +- src/librustc/traits/specialize/mod.rs | 50 ++- .../traits/specialize/specialization_graph.rs | 25 +- src/librustc/ty/maps.rs | 40 +++ src/librustc/ty/mod.rs | 38 +- src/librustc/ty/trait_def.rs | 336 ++++-------------- src/librustc_driver/driver.rs | 3 + src/librustc_metadata/decoder.rs | 15 +- src/librustc_metadata/lib.rs | 1 + src/librustc_typeck/check/mod.rs | 4 +- src/librustc_typeck/coherence/mod.rs | 4 - src/librustc_typeck/coherence/overlap.rs | 35 +- src/librustc_typeck/collect.rs | 12 +- src/librustc_typeck/diagnostics.rs | 61 ---- 18 files changed, 300 insertions(+), 453 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 93dd76a6984..15c4469b746 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -106,6 +106,8 @@ pub enum DepNode { UsedTraitImports(D), ConstEval(D), SymbolName(D), + SpecializationGraph(D), + ObjectSafety(D), // The set of impls for a given trait. Ultimately, it would be // nice to get more fine-grained here (e.g., to include a @@ -264,6 +266,8 @@ impl DepNode { UsedTraitImports(ref d) => op(d).map(UsedTraitImports), ConstEval(ref d) => op(d).map(ConstEval), SymbolName(ref d) => op(d).map(SymbolName), + SpecializationGraph(ref d) => op(d).map(SpecializationGraph), + ObjectSafety(ref d) => op(d).map(ObjectSafety), TraitImpls(ref d) => op(d).map(TraitImpls), AllLocalTraitImpls => Some(AllLocalTraitImpls), TraitItems(ref d) => op(d).map(TraitItems), diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 8ef42826fac..470dcb4bd61 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -409,6 +409,67 @@ RFC. It is, however, [currently unimplemented][iss15872]. [iss15872]: https://github.com/rust-lang/rust/issues/15872 "##, +E0119: r##" +There are conflicting trait implementations for the same type. +Example of erroneous code: + +```compile_fail,E0119 +trait MyTrait { + fn get(&self) -> usize; +} + +impl MyTrait for T { + fn get(&self) -> usize { 0 } +} + +struct Foo { + value: usize +} + +impl MyTrait for Foo { // error: conflicting implementations of trait + // `MyTrait` for type `Foo` + fn get(&self) -> usize { self.value } +} +``` + +When looking for the implementation for the trait, the compiler finds +both the `impl MyTrait for T` where T is all types and the `impl +MyTrait for Foo`. Since a trait cannot be implemented multiple times, +this is an error. So, when you write: + +``` +trait MyTrait { + fn get(&self) -> usize; +} + +impl MyTrait for T { + fn get(&self) -> usize { 0 } +} +``` + +This makes the trait implemented on all types in the scope. So if you +try to implement it on another one after that, the implementations will +conflict. Example: + +``` +trait MyTrait { + fn get(&self) -> usize; +} + +impl MyTrait for T { + fn get(&self) -> usize { 0 } +} + +struct Foo; + +fn main() { + let f = Foo; + + f.get(); // the trait is implemented so we can use it +} +``` +"##, + E0133: r##" Unsafe code was used outside of an unsafe function or block. diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 2f525e1b8b4..1823373348b 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -619,8 +619,6 @@ pub fn get_vtable_methods<'a, 'tcx>( debug!("get_vtable_methods({:?})", trait_ref); supertraits(tcx, trait_ref).flat_map(move |trait_ref| { - tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id()); - let trait_methods = tcx.associated_items(trait_ref.def_id()) .filter(|item| item.kind == ty::AssociatedKind::Method); @@ -782,3 +780,19 @@ impl<'tcx> TraitObligation<'tcx> { ty::Binder(self.predicate.skip_binder().self_ty()) } } + +pub fn provide(providers: &mut ty::maps::Providers) { + *providers = ty::maps::Providers { + is_object_safe: object_safety::is_object_safe_provider, + specialization_graph_of: specialize::specialization_graph_provider, + ..*providers + }; +} + +pub fn provide_extern(providers: &mut ty::maps::Providers) { + *providers = ty::maps::Providers { + is_object_safe: object_safety::is_object_safe_provider, + specialization_graph_of: specialize::specialization_graph_provider, + ..*providers + }; +} diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 66e8e503be4..0e3a53129d1 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -77,25 +77,6 @@ pub enum MethodViolationCode { } impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { - pub fn is_object_safe(self, trait_def_id: DefId) -> bool { - // Because we query yes/no results frequently, we keep a cache: - let def = self.trait_def(trait_def_id); - - let result = def.object_safety().unwrap_or_else(|| { - let result = self.object_safety_violations(trait_def_id).is_empty(); - - // Record just a yes/no result in the cache; this is what is - // queried most frequently. Note that this may overwrite a - // previous result, but always with the same thing. - def.set_object_safety(result); - - result - }); - - debug!("is_object_safe({:?}) = {}", trait_def_id, result); - - result - } /// Returns the object safety violations that affect /// astconv - currently, Self in supertraits. This is needed @@ -391,3 +372,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { error } } + +pub(super) fn is_object_safe_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + trait_def_id: DefId) + -> bool { + tcx.object_safety_violations(trait_def_id).is_empty() +} diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index e01f97eb1f3..d6f6350373a 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -1320,23 +1320,10 @@ fn assoc_ty_def<'cx, 'gcx, 'tcx>( let trait_def_id = selcx.tcx().impl_trait_ref(impl_def_id).unwrap().def_id; let trait_def = selcx.tcx().trait_def(trait_def_id); - if !trait_def.is_complete(selcx.tcx()) { - let impl_node = specialization_graph::Node::Impl(impl_def_id); - for item in impl_node.items(selcx.tcx()) { - if item.kind == ty::AssociatedKind::Type && item.name == assoc_ty_name { - return Some(specialization_graph::NodeItem { - node: specialization_graph::Node::Impl(impl_def_id), - item: item, - }); - } - } - None - } else { - trait_def - .ancestors(impl_def_id) - .defs(selcx.tcx(), assoc_ty_name, ty::AssociatedKind::Type) - .next() - } + trait_def + .ancestors(selcx.tcx(), impl_def_id) + .defs(selcx.tcx(), assoc_ty_name, ty::AssociatedKind::Type) + .next() } // # Cache diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 3882e218241..b3956e813c4 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -27,6 +27,7 @@ use ty::subst::{Subst, Substs}; use traits::{self, Reveal, ObligationCause}; use ty::{self, TyCtxt, TypeFoldable}; use syntax_pos::DUMMY_SP; +use std::rc::Rc; pub mod specialization_graph; @@ -118,7 +119,7 @@ pub fn find_associated_item<'a, 'tcx>( let trait_def_id = tcx.trait_id_of_impl(impl_data.impl_def_id).unwrap(); let trait_def = tcx.trait_def(trait_def_id); - let ancestors = trait_def.ancestors(impl_data.impl_def_id); + let ancestors = trait_def.ancestors(tcx, impl_data.impl_def_id); match ancestors.defs(tcx, item.name, item.kind).next() { Some(node_item) => { let substs = tcx.infer_ctxt((), Reveal::All).enter(|infcx| { @@ -285,3 +286,50 @@ impl SpecializesCache { self.map.insert((a, b), result); } } + +// Query provider for `specialization_graph_of`. +pub(super) fn specialization_graph_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + trait_id: DefId) + -> Rc { + let mut sg = specialization_graph::Graph::new(); + + for &impl_def_id in tcx.trait_impls_of(trait_id).iter() { + if impl_def_id.is_local() { + // This is where impl overlap checking happens: + let insert_result = sg.insert(tcx, impl_def_id); + // Report error if there was one. + if let Err(overlap) = insert_result { + let mut err = struct_span_err!(tcx.sess, + tcx.span_of_impl(impl_def_id).unwrap(), + E0119, + "conflicting implementations of trait `{}`{}:", + overlap.trait_desc, + overlap.self_desc.clone().map_or(String::new(), + |ty| { + format!(" for type `{}`", ty) + })); + + match tcx.span_of_impl(overlap.with_impl) { + Ok(span) => { + err.span_label(span, format!("first implementation here")); + err.span_label(tcx.span_of_impl(impl_def_id).unwrap(), + format!("conflicting implementation{}", + overlap.self_desc + .map_or(String::new(), + |ty| format!(" for `{}`", ty)))); + } + Err(cname) => { + err.note(&format!("conflicting implementation in crate `{}`", cname)); + } + } + + err.emit(); + } + } else { + let parent = tcx.impl_parent(impl_def_id).unwrap_or(trait_id); + sg.record_impl_from_cstore(tcx, parent, impl_def_id) + } + } + + Rc::new(sg) +} diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index 6e2c16c82ae..87c98a0ef0e 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -12,8 +12,9 @@ use super::{OverlapError, specializes}; use hir::def_id::DefId; use traits::{self, Reveal}; -use ty::{self, TyCtxt, TraitDef, TypeFoldable}; +use ty::{self, TyCtxt, TypeFoldable}; use ty::fast_reject::{self, SimplifiedType}; +use std::rc::Rc; use syntax::ast::Name; use util::nodemap::{DefIdMap, FxHashMap}; @@ -301,18 +302,19 @@ impl<'a, 'gcx, 'tcx> Node { } } -pub struct Ancestors<'a> { - trait_def: &'a TraitDef, +pub struct Ancestors { + trait_def_id: DefId, + specialization_graph: Rc, current_source: Option, } -impl<'a> Iterator for Ancestors<'a> { +impl Iterator for Ancestors { type Item = Node; fn next(&mut self) -> Option { let cur = self.current_source.take(); if let Some(Node::Impl(cur_impl)) = cur { - let parent = self.trait_def.specialization_graph.borrow().parent(cur_impl); - if parent == self.trait_def.def_id { + let parent = self.specialization_graph.parent(cur_impl); + if parent == self.trait_def_id { self.current_source = Some(Node::Trait(parent)); } else { self.current_source = Some(Node::Impl(parent)); @@ -336,7 +338,7 @@ impl NodeItem { } } -impl<'a, 'gcx, 'tcx> Ancestors<'a> { +impl<'a, 'gcx, 'tcx> Ancestors { /// Search the items from the given ancestors, returning each definition /// with the given name and the given kind. #[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait. @@ -351,9 +353,14 @@ impl<'a, 'gcx, 'tcx> Ancestors<'a> { /// Walk up the specialization ancestors of a given impl, starting with that /// impl itself. -pub fn ancestors<'a>(trait_def: &'a TraitDef, start_from_impl: DefId) -> Ancestors<'a> { +pub fn ancestors(tcx: TyCtxt, + trait_def_id: DefId, + start_from_impl: DefId) + -> Ancestors { + let specialization_graph = tcx.specialization_graph_of(trait_def_id); Ancestors { - trait_def: trait_def, + trait_def_id, + specialization_graph, current_source: Some(Node::Impl(start_from_impl)), } } diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 1fd9e8f7375..188ef289ba9 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -18,10 +18,12 @@ use middle::region::RegionMaps; use mir; use mir::transform::{MirSuite, MirPassIndex}; use session::CompileResult; +use traits::specialization_graph; use ty::{self, CrateInherentImpls, Ty, TyCtxt}; use ty::item_path; use ty::steal::Steal; use ty::subst::Substs; +use ty::fast_reject::SimplifiedType; use util::nodemap::{DefIdSet, NodeSet}; use rustc_data_structures::indexed_vec::IndexVec; @@ -98,6 +100,15 @@ impl Key for (CrateNum, DefId) { } } +impl Key for (DefId, SimplifiedType) { + fn map_crate(&self) -> CrateNum { + self.0.krate + } + fn default_span(&self, tcx: TyCtxt) -> Span { + self.0.default_span(tcx) + } +} + impl<'tcx> Key for (DefId, &'tcx Substs<'tcx>) { fn map_crate(&self) -> CrateNum { self.0.krate @@ -391,6 +402,24 @@ impl<'tcx> QueryDescription for queries::is_mir_available<'tcx> { } } +impl<'tcx> QueryDescription for queries::trait_impls_of<'tcx> { + fn describe(tcx: TyCtxt, def_id: DefId) -> String { + format!("trait impls of `{}`", tcx.item_path_str(def_id)) + } +} + +impl<'tcx> QueryDescription for queries::relevant_trait_impls_for<'tcx> { + fn describe(tcx: TyCtxt, (def_id, ty): (DefId, SimplifiedType)) -> String { + format!("relevant impls for: `({}, {:?})`", tcx.item_path_str(def_id), ty) + } +} + +impl<'tcx> QueryDescription for queries::is_object_safe<'tcx> { + fn describe(tcx: TyCtxt, def_id: DefId) -> String { + format!("determine object safety of trait `{}`", tcx.item_path_str(def_id)) + } +} + macro_rules! define_maps { (<$tcx:tt> $($(#[$attr:meta])* @@ -820,6 +849,13 @@ define_maps! { <'tcx> [] item_body_nested_bodies: ItemBodyNestedBodies(DefId) -> Rc>, [] const_is_rvalue_promotable_to_static: ConstIsRvaluePromotableToStatic(DefId) -> bool, [] is_mir_available: IsMirAvailable(DefId) -> bool, + + [] trait_impls_of: TraitImpls(DefId) -> Rc>, + // Note that TraitDef::for_each_relevant_impl() will do type simplication for you. + [] relevant_trait_impls_for: relevant_trait_impls_for((DefId, SimplifiedType)) + -> Rc>, + [] specialization_graph_of: SpecializationGraph(DefId) -> Rc, + [] is_object_safe: ObjectSafety(DefId) -> bool, } fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode { @@ -859,3 +895,7 @@ fn mir_keys(_: CrateNum) -> DepNode { fn crate_variances(_: CrateNum) -> DepNode { DepNode::CrateVariances } + +fn relevant_trait_impls_for((def_id, _): (DefId, SimplifiedType)) -> DepNode { + DepNode::TraitImpls(def_id) +} diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 6ca401d27ac..a86d7351ef4 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -80,7 +80,7 @@ pub use self::context::{Lift, TypeckTables}; pub use self::instance::{Instance, InstanceDef}; -pub use self::trait_def::{TraitDef, TraitFlags}; +pub use self::trait_def::TraitDef; pub use self::maps::queries; @@ -2324,37 +2324,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn trait_has_default_impl(self, trait_def_id: DefId) -> bool { - let def = self.trait_def(trait_def_id); - def.flags.get().intersects(TraitFlags::HAS_DEFAULT_IMPL) - } - - /// Populates the type context with all the implementations for the given - /// trait if necessary. - pub fn populate_implementations_for_trait_if_necessary(self, trait_id: DefId) { - if trait_id.is_local() { - return - } - - // The type is not local, hence we are reading this out of - // metadata and don't need to track edges. - let _ignore = self.dep_graph.in_ignore(); - - let def = self.trait_def(trait_id); - if def.flags.get().intersects(TraitFlags::HAS_REMOTE_IMPLS) { - return; - } - - debug!("populate_implementations_for_trait_if_necessary: searching for {:?}", def); - - for impl_def_id in self.sess.cstore.implementations_of_trait(Some(trait_id)) { - let trait_ref = self.impl_trait_ref(impl_def_id).unwrap(); - - // Record the trait->implementation mapping. - let parent = self.impl_parent(impl_def_id).unwrap_or(trait_id); - def.record_remote_impl(self, impl_def_id, trait_ref, parent); - } - - def.flags.set(def.flags.get() | TraitFlags::HAS_REMOTE_IMPLS); + self.trait_def(trait_def_id).has_default_impl } /// Given the def_id of an impl, return the def_id of the trait it implements. @@ -2603,6 +2573,8 @@ pub fn provide(providers: &mut ty::maps::Providers) { adt_dtorck_constraint, def_span, trait_of_item, + trait_impls_of: trait_def::trait_impls_of_provider, + relevant_trait_impls_for: trait_def::relevant_trait_impls_provider, ..*providers }; } @@ -2611,6 +2583,8 @@ pub fn provide_extern(providers: &mut ty::maps::Providers) { *providers = ty::maps::Providers { adt_sized_constraint, adt_dtorck_constraint, + trait_impls_of: trait_def::trait_impls_of_provider, + relevant_trait_impls_for: trait_def::relevant_trait_impls_provider, ..*providers }; } diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs index 097b596c5eb..b0357a35b83 100644 --- a/src/librustc/ty/trait_def.rs +++ b/src/librustc/ty/trait_def.rs @@ -8,18 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use dep_graph::DepNode; -use hir::def_id::{DefId, LOCAL_CRATE}; -use traits::{self, specialization_graph}; -use ty; +use hir::def_id::DefId; +use traits::specialization_graph; use ty::fast_reject; -use ty::{Ty, TyCtxt, TraitRef}; -use std::cell::{Cell, RefCell}; +use ty::fold::TypeFoldable; +use ty::{Ty, TyCtxt}; +use std::rc::Rc; use hir; -use util::nodemap::FxHashMap; - -use syntax::ast; -use syntax_pos::DUMMY_SP; /// A trait's definition with type information. pub struct TraitDef { @@ -33,40 +28,7 @@ pub struct TraitDef { /// be usable with the sugar (or without it). pub paren_sugar: bool, - // Impls of a trait. To allow for quicker lookup, the impls are indexed by a - // simplified version of their `Self` type: impls with a simplifiable `Self` - // are stored in `nonblanket_impls` keyed by it, while all other impls are - // stored in `blanket_impls`. - // - // A similar division is used within `specialization_graph`, but the ones - // here are (1) stored as a flat list for the trait and (2) populated prior - // to -- and used while -- determining specialization order. - // - // FIXME: solve the reentrancy issues and remove these lists in favor of the - // ones in `specialization_graph`. - // - // These lists are tracked by `DepNode::TraitImpls`; we don't use - // a DepTrackingMap but instead have the `TraitDef` insert the - // required reads/writes. - - /// Impls of the trait. - nonblanket_impls: RefCell< - FxHashMap> - >, - - /// Blanket impls associated with the trait. - blanket_impls: RefCell>, - - /// The specialization order for impls of this trait. - pub specialization_graph: RefCell, - - /// Various flags - pub flags: Cell, - - /// The number of impls we've added from the local crate. - /// When this number matches up the list in the HIR map, - /// we're done, and the specialization graph is correct. - local_impl_count: Cell, + pub has_default_impl: bool, /// The ICH of this trait's DefPath, cached here so it doesn't have to be /// recomputed all the time. @@ -77,193 +39,28 @@ impl<'a, 'gcx, 'tcx> TraitDef { pub fn new(def_id: DefId, unsafety: hir::Unsafety, paren_sugar: bool, + has_default_impl: bool, def_path_hash: u64) -> TraitDef { TraitDef { - def_id: def_id, - paren_sugar: paren_sugar, - unsafety: unsafety, - nonblanket_impls: RefCell::new(FxHashMap()), - blanket_impls: RefCell::new(vec![]), - flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS), - local_impl_count: Cell::new(0), - specialization_graph: RefCell::new(traits::specialization_graph::Graph::new()), - def_path_hash: def_path_hash, + def_id, + paren_sugar, + unsafety, + has_default_impl, + def_path_hash, } } - // returns None if not yet calculated - pub fn object_safety(&self) -> Option { - if self.flags.get().intersects(TraitFlags::OBJECT_SAFETY_VALID) { - Some(self.flags.get().intersects(TraitFlags::IS_OBJECT_SAFE)) - } else { - None - } - } - - pub fn set_object_safety(&self, is_safe: bool) { - assert!(self.object_safety().map(|cs| cs == is_safe).unwrap_or(true)); - self.flags.set( - self.flags.get() | if is_safe { - TraitFlags::OBJECT_SAFETY_VALID | TraitFlags::IS_OBJECT_SAFE - } else { - TraitFlags::OBJECT_SAFETY_VALID - } - ); - } - - fn write_trait_impls(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) { - tcx.dep_graph.write(DepNode::TraitImpls(self.def_id)); - } - - fn read_trait_impls(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) { - tcx.dep_graph.read(DepNode::TraitImpls(self.def_id)); - } - - /// Records a basic trait-to-implementation mapping. - /// - /// Returns `true` iff the impl has not previously been recorded. - fn record_impl(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, - impl_def_id: DefId, - impl_trait_ref: TraitRef<'tcx>) - -> bool { - debug!("TraitDef::record_impl for {:?}, from {:?}", - self, impl_trait_ref); - - // Record the write into the impl set, but only for local - // impls: external impls are handled differently. - if impl_def_id.is_local() { - self.write_trait_impls(tcx); - } - - // We don't want to borrow_mut after we already populated all impls, - // so check if an impl is present with an immutable borrow first. - if let Some(sty) = fast_reject::simplify_type(tcx, - impl_trait_ref.self_ty(), false) { - if let Some(is) = self.nonblanket_impls.borrow().get(&sty) { - if is.contains(&impl_def_id) { - return false; // duplicate - skip - } - } - - self.nonblanket_impls.borrow_mut().entry(sty).or_insert(vec![]).push(impl_def_id) - } else { - if self.blanket_impls.borrow().contains(&impl_def_id) { - return false; // duplicate - skip - } - self.blanket_impls.borrow_mut().push(impl_def_id) - } - - true - } - - /// Records a trait-to-implementation mapping for a crate-local impl. - pub fn record_local_impl(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, - impl_def_id: DefId, - impl_trait_ref: TraitRef<'tcx>) { - assert!(impl_def_id.is_local()); - let was_new = self.record_impl(tcx, impl_def_id, impl_trait_ref); - assert!(was_new); - - self.local_impl_count.set(self.local_impl_count.get() + 1); - } - - /// Records a trait-to-implementation mapping. - pub fn record_has_default_impl(&self) { - self.flags.set(self.flags.get() | TraitFlags::HAS_DEFAULT_IMPL); - } - - /// Records a trait-to-implementation mapping for a non-local impl. - /// - /// The `parent_impl` is the immediately-less-specialized impl, or the - /// trait's def ID if the impl is not a specialization -- information that - /// should be pulled from the metadata. - pub fn record_remote_impl(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, - impl_def_id: DefId, - impl_trait_ref: TraitRef<'tcx>, - parent_impl: DefId) { - assert!(!impl_def_id.is_local()); - - // if the impl has not previously been recorded - if self.record_impl(tcx, impl_def_id, impl_trait_ref) { - // if the impl is non-local, it's placed directly into the - // specialization graph using parent information drawn from metadata. - self.specialization_graph.borrow_mut() - .record_impl_from_cstore(tcx, parent_impl, impl_def_id) - } - } - - /// Adds a local impl into the specialization graph, returning an error with - /// overlap information if the impl overlaps but does not specialize an - /// existing impl. - pub fn add_impl_for_specialization(&self, - tcx: TyCtxt<'a, 'gcx, 'tcx>, - impl_def_id: DefId) - -> Result<(), traits::OverlapError> { - assert!(impl_def_id.is_local()); - - self.specialization_graph.borrow_mut() - .insert(tcx, impl_def_id) - } - - pub fn ancestors(&'a self, of_impl: DefId) -> specialization_graph::Ancestors<'a> { - specialization_graph::ancestors(self, of_impl) - } - - /// Whether the impl set and specialization graphs are complete. - pub fn is_complete(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool { - tcx.populate_implementations_for_trait_if_necessary(self.def_id); - ty::queries::coherent_trait::try_get(tcx, DUMMY_SP, (LOCAL_CRATE, self.def_id)).is_ok() - } - - /// If any local impls haven't been added yet, returns - /// Some(list of local impls for this trait). - fn missing_local_impls(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) - -> Option<&'gcx [ast::NodeId]> { - if self.flags.get().intersects(TraitFlags::HAS_LOCAL_IMPLS) { - return None; - } - - if self.is_complete(tcx) { - self.flags.set(self.flags.get() | TraitFlags::HAS_LOCAL_IMPLS); - return None; - } - - let impls = tcx.hir.trait_impls(self.def_id); - assert!(self.local_impl_count.get() <= impls.len()); - if self.local_impl_count.get() == impls.len() { - self.flags.set(self.flags.get() | TraitFlags::HAS_LOCAL_IMPLS); - return None; - } - - Some(impls) + pub fn ancestors(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, + of_impl: DefId) + -> specialization_graph::Ancestors { + specialization_graph::ancestors(tcx, self.def_id, of_impl) } pub fn for_each_impl(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, mut f: F) { - self.read_trait_impls(tcx); - tcx.populate_implementations_for_trait_if_necessary(self.def_id); - - let local_impls = self.missing_local_impls(tcx); - if let Some(impls) = local_impls { - for &id in impls { - f(tcx.hir.local_def_id(id)); - } - } - let mut f = |def_id: DefId| { - if !(local_impls.is_some() && def_id.is_local()) { - f(def_id); - } - }; - - for &impl_def_id in self.blanket_impls.borrow().iter() { + for &impl_def_id in tcx.trait_impls_of(self.def_id).iter() { f(impl_def_id); } - - for v in self.nonblanket_impls.borrow().values() { - for &impl_def_id in v { - f(impl_def_id); - } - } } /// Iterate over every impl that could possibly match the @@ -273,25 +70,6 @@ impl<'a, 'gcx, 'tcx> TraitDef { self_ty: Ty<'tcx>, mut f: F) { - self.read_trait_impls(tcx); - tcx.populate_implementations_for_trait_if_necessary(self.def_id); - - let local_impls = self.missing_local_impls(tcx); - if let Some(impls) = local_impls { - for &id in impls { - f(tcx.hir.local_def_id(id)); - } - } - let mut f = |def_id: DefId| { - if !(local_impls.is_some() && def_id.is_local()) { - f(def_id); - } - }; - - for &impl_def_id in self.blanket_impls.borrow().iter() { - f(impl_def_id); - } - // simplify_type(.., false) basically replaces type parameters and // projections with infer-variables. This is, of course, done on // the impl trait-ref when it is instantiated, but not on the @@ -304,29 +82,71 @@ impl<'a, 'gcx, 'tcx> TraitDef { // replace `S` with anything - this impl of course can't be // selected, and as there are hundreds of similar impls, // considering them would significantly harm performance. - if let Some(simp) = fast_reject::simplify_type(tcx, self_ty, true) { - if let Some(impls) = self.nonblanket_impls.borrow().get(&simp) { - for &impl_def_id in impls { - f(impl_def_id); - } - } + let relevant_impls = if let Some(simplified_self_ty) = + fast_reject::simplify_type(tcx, self_ty, true) { + tcx.relevant_trait_impls_for((self.def_id, simplified_self_ty)) } else { - for v in self.nonblanket_impls.borrow().values() { - for &impl_def_id in v { - f(impl_def_id); - } - } + tcx.trait_impls_of(self.def_id) + }; + + for &impl_def_id in relevant_impls.iter() { + f(impl_def_id); } } } -bitflags! { - flags TraitFlags: u32 { - const NO_TRAIT_FLAGS = 0, - const HAS_DEFAULT_IMPL = 1 << 0, - const IS_OBJECT_SAFE = 1 << 1, - const OBJECT_SAFETY_VALID = 1 << 2, - const HAS_REMOTE_IMPLS = 1 << 3, - const HAS_LOCAL_IMPLS = 1 << 4, +// Query provider for `trait_impls_of`. +pub(super) fn trait_impls_of_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + trait_id: DefId) + -> Rc> { + let mut impls = if trait_id.is_local() { + // Traits defined in the current crate can't have impls in upstream + // crates, so we don't bother querying the cstore. + Vec::new() + } else { + tcx.sess.cstore.implementations_of_trait(Some(trait_id)) + }; + + impls.extend(tcx.hir + .trait_impls(trait_id) + .iter() + .map(|&node_id| tcx.hir.local_def_id(node_id)) + .filter(|&impl_def_id| { + let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); + !trait_ref.references_error() + })); + Rc::new(impls) +} + +// Query provider for `relevant_trait_impls_for`. +pub(super) fn relevant_trait_impls_provider<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + (trait_id, self_ty): (DefId, fast_reject::SimplifiedType)) + -> Rc> +{ + let all_trait_impls = tcx.trait_impls_of(trait_id); + + let relevant: Vec = all_trait_impls + .iter() + .map(|&impl_def_id| impl_def_id) + .filter(|&impl_def_id| { + let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); + let impl_simple_self_ty = fast_reject::simplify_type(tcx, + impl_trait_ref.self_ty(), + false); + if let Some(impl_simple_self_ty) = impl_simple_self_ty { + impl_simple_self_ty == self_ty + } else { + // blanket impl (?) + true + } + }) + .collect(); + + if all_trait_impls.len() == relevant.len() { + // If we didn't filter anything out, re-use the existing vec. + all_trait_impls + } else { + Rc::new(relevant) } } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 8fddbe110b0..c23563e13be 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -22,6 +22,7 @@ use rustc::middle::{self, dependency_format, stability, reachable}; use rustc::middle::privacy::AccessLevels; use rustc::mir::transform::{MIR_CONST, MIR_VALIDATED, MIR_OPTIMIZED, Passes}; use rustc::ty::{self, TyCtxt, Resolutions, GlobalArenas}; +use rustc::traits; use rustc::util::common::time; use rustc::util::nodemap::NodeSet; use rustc::util::fs::rename_or_copy_remove; @@ -892,6 +893,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, trans::provide(&mut local_providers); typeck::provide(&mut local_providers); ty::provide(&mut local_providers); + traits::provide(&mut local_providers); reachable::provide(&mut local_providers); rustc_const_eval::provide(&mut local_providers); middle::region::provide(&mut local_providers); @@ -900,6 +902,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, cstore::provide(&mut extern_providers); trans::provide(&mut extern_providers); ty::provide_extern(&mut extern_providers); + traits::provide_extern(&mut extern_providers); // FIXME(eddyb) get rid of this once we replace const_eval with miri. rustc_const_eval::provide(&mut extern_providers); diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 51822474254..941b965d9a4 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -505,16 +505,11 @@ impl<'a, 'tcx> CrateMetadata { _ => bug!(), }; - let def = ty::TraitDef::new(self.local_def_id(item_id), - data.unsafety, - data.paren_sugar, - self.def_path_table.def_path_hash(item_id)); - - if data.has_default_impl { - def.record_has_default_impl(); - } - - def + ty::TraitDef::new(self.local_def_id(item_id), + data.unsafety, + data.paren_sugar, + data.has_default_impl, + self.def_path_table.def_path_hash(item_id)) } fn get_variant(&self, item: &Entry, index: DefIndex) -> ty::VariantDef { diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 27555f49e57..6a40174fa02 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -29,6 +29,7 @@ #![cfg_attr(stage0, unstable(feature = "rustc_private", issue = "27812"))] #![cfg_attr(stage0, feature(staged_api))] +#![feature(sort_unstable)] #[macro_use] extern crate log; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 70d2867c08c..d304d79bc52 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1200,7 +1200,7 @@ fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_id: DefId, impl_item: &hir::ImplItem) { - let ancestors = trait_def.ancestors(impl_id); + let ancestors = trait_def.ancestors(tcx, impl_id); let kind = match impl_item.node { hir::ImplItemKind::Const(..) => ty::AssociatedKind::Const, @@ -1330,7 +1330,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let mut invalidated_items = Vec::new(); let associated_type_overridden = overridden_associated_type.is_some(); for trait_item in tcx.associated_items(impl_trait_ref.def_id) { - let is_implemented = trait_def.ancestors(impl_id) + let is_implemented = trait_def.ancestors(tcx, impl_id) .defs(tcx, trait_item.name, trait_item.kind) .next() .map(|node_item| !node_item.node.is_from_trait()) diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 8b9dc20315d..165be49f760 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -46,8 +46,6 @@ fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) { } enforce_trait_manually_implementable(tcx, impl_def_id, trait_ref.def_id); - let trait_def = tcx.trait_def(trait_ref.def_id); - trait_def.record_local_impl(tcx, impl_def_id, trait_ref); } } @@ -117,8 +115,6 @@ pub fn provide(providers: &mut Providers) { fn coherent_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, (_, def_id): (CrateNum, DefId)) { - tcx.populate_implementations_for_trait_if_necessary(def_id); - let impls = tcx.hir.trait_impls(def_id); for &impl_id in impls { check_impl(tcx, impl_id); diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index f479dc2e6ab..ba1d7b18e8c 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -41,39 +41,10 @@ pub fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) { let _task = tcx.dep_graph.in_task(DepNode::CoherenceOverlapCheck(trait_def_id)); - let def = tcx.trait_def(trait_def_id); + // Trigger building the specialization graph for the trait of this impl. + // This will detect any overlap errors. + tcx.specialization_graph_of(trait_def_id); - // attempt to insert into the specialization graph - let insert_result = def.add_impl_for_specialization(tcx, impl_def_id); - - // insertion failed due to overlap - if let Err(overlap) = insert_result { - let mut err = struct_span_err!(tcx.sess, - tcx.span_of_impl(impl_def_id).unwrap(), - E0119, - "conflicting implementations of trait `{}`{}:", - overlap.trait_desc, - overlap.self_desc.clone().map_or(String::new(), - |ty| { - format!(" for type `{}`", ty) - })); - - match tcx.span_of_impl(overlap.with_impl) { - Ok(span) => { - err.span_label(span, "first implementation here"); - err.span_label(tcx.span_of_impl(impl_def_id).unwrap(), - format!("conflicting implementation{}", - overlap.self_desc - .map_or(String::new(), - |ty| format!(" for `{}`", ty)))); - } - Err(cname) => { - err.note(&format!("conflicting implementation in crate `{}`", cname)); - } - } - - err.emit(); - } // check for overlap with the automatic `impl Trait for Trait` if let ty::TyDynamic(ref data, ..) = trait_ref.self_ty().sty { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 7c6c70024ce..cb1bd3e099d 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -749,12 +749,12 @@ fn trait_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } let def_path_hash = tcx.def_path_hash(def_id); - let def = ty::TraitDef::new(def_id, unsafety, paren_sugar, def_path_hash); - - if tcx.hir.trait_is_auto(def_id) { - def.record_has_default_impl(); - } - + let has_default_impl = tcx.hir.trait_is_auto(def_id); + let def = ty::TraitDef::new(def_id, + unsafety, + paren_sugar, + has_default_impl, + def_path_hash); tcx.alloc_trait_def(def) } diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 0f42ee15ecf..f9ebe3fff5b 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1524,67 +1524,6 @@ impl TypeWrapper { ``` "##, -E0119: r##" -There are conflicting trait implementations for the same type. -Example of erroneous code: - -```compile_fail,E0119 -trait MyTrait { - fn get(&self) -> usize; -} - -impl MyTrait for T { - fn get(&self) -> usize { 0 } -} - -struct Foo { - value: usize -} - -impl MyTrait for Foo { // error: conflicting implementations of trait - // `MyTrait` for type `Foo` - fn get(&self) -> usize { self.value } -} -``` - -When looking for the implementation for the trait, the compiler finds -both the `impl MyTrait for T` where T is all types and the `impl -MyTrait for Foo`. Since a trait cannot be implemented multiple times, -this is an error. So, when you write: - -``` -trait MyTrait { - fn get(&self) -> usize; -} - -impl MyTrait for T { - fn get(&self) -> usize { 0 } -} -``` - -This makes the trait implemented on all types in the scope. So if you -try to implement it on another one after that, the implementations will -conflict. Example: - -``` -trait MyTrait { - fn get(&self) -> usize; -} - -impl MyTrait for T { - fn get(&self) -> usize { 0 } -} - -struct Foo; - -fn main() { - let f = Foo; - - f.get(); // the trait is implemented so we can use it -} -``` -"##, - E0120: r##" An attempt was made to implement Drop on a trait, which is not allowed: only structs and enums can implement Drop. An example causing this error: From 40a6734ae1a1ec9ad96b8f5b58a64d10d0cdbe76 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 15 May 2017 12:21:28 +0200 Subject: [PATCH 045/103] Re-introduce cycle-check in assoc. item resolution. --- src/librustc/traits/project.rs | 38 ++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index d6f6350373a..e119ead7473 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -29,6 +29,7 @@ use infer::type_variable::TypeVariableOrigin; use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap}; use syntax::ast; use syntax::symbol::Symbol; +use syntax_pos::DUMMY_SP; use ty::subst::Subst; use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt}; use ty::fold::{TypeFoldable, TypeFolder}; @@ -1317,13 +1318,38 @@ fn assoc_ty_def<'cx, 'gcx, 'tcx>( assoc_ty_name: ast::Name) -> Option> { - let trait_def_id = selcx.tcx().impl_trait_ref(impl_def_id).unwrap().def_id; - let trait_def = selcx.tcx().trait_def(trait_def_id); + let tcx = selcx.tcx(); + let trait_def_id = tcx.impl_trait_ref(impl_def_id).unwrap().def_id; + let trait_def = tcx.trait_def(trait_def_id); - trait_def - .ancestors(selcx.tcx(), impl_def_id) - .defs(selcx.tcx(), assoc_ty_name, ty::AssociatedKind::Type) - .next() + // This function may be called while we are still building the + // specialization graph that is queried below (via TraidDef::ancestors()), + // so, in order to avoid infinite recursion, we detect this case by + // seeing if a query of the specialization graph fails with a cycle error. + // If we are in cycle, and thus still building the graph, we perform a + // reduced version of the associated item lookup that does not need the + // specialization graph. + let specialization_graph_complete = + ty::queries::specialization_graph_of::try_get(tcx, + DUMMY_SP, + trait_def_id).is_ok(); + if !specialization_graph_complete { + let impl_node = specialization_graph::Node::Impl(impl_def_id); + for item in impl_node.items(tcx) { + if item.kind == ty::AssociatedKind::Type && item.name == assoc_ty_name { + return Some(specialization_graph::NodeItem { + node: specialization_graph::Node::Impl(impl_def_id), + item: item, + }); + } + } + None + } else { + trait_def + .ancestors(tcx, impl_def_id) + .defs(tcx, assoc_ty_name, ty::AssociatedKind::Type) + .next() + } } // # Cache From 742ebc17ff4d033f6b5c6348ddb1c94d730c56b8 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 15 May 2017 15:09:30 +0200 Subject: [PATCH 046/103] Share lists of blanket impls in results of relevant_impls_for() query. --- src/librustc/traits/specialize/mod.rs | 14 ++- src/librustc/ty/maps.rs | 4 +- src/librustc/ty/trait_def.rs | 117 ++++++++++++++++++++------ 3 files changed, 108 insertions(+), 27 deletions(-) diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index b3956e813c4..0e5779f9d17 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -293,7 +293,19 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx -> Rc { let mut sg = specialization_graph::Graph::new(); - for &impl_def_id in tcx.trait_impls_of(trait_id).iter() { + let mut trait_impls: Vec = tcx.trait_impls_of(trait_id).iter().collect(); + + // The coherence checking implementation seems to rely on impls being + // iterated over (roughly) in definition order, so we are sorting by + // negated CrateNum (so remote definitions are visited first) and then + // by a flattend version of the DefIndex. + trait_impls.sort_unstable_by_key(|def_id| { + (-(def_id.krate.as_u32() as i64), + def_id.index.address_space().index(), + def_id.index.as_array_index()) + }); + + for impl_def_id in trait_impls { if impl_def_id.is_local() { // This is where impl overlap checking happens: let insert_result = sg.insert(tcx, impl_def_id); diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 188ef289ba9..0926da2005d 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -850,10 +850,10 @@ define_maps! { <'tcx> [] const_is_rvalue_promotable_to_static: ConstIsRvaluePromotableToStatic(DefId) -> bool, [] is_mir_available: IsMirAvailable(DefId) -> bool, - [] trait_impls_of: TraitImpls(DefId) -> Rc>, + [] trait_impls_of: TraitImpls(DefId) -> ty::trait_def::TraitImpls, // Note that TraitDef::for_each_relevant_impl() will do type simplication for you. [] relevant_trait_impls_for: relevant_trait_impls_for((DefId, SimplifiedType)) - -> Rc>, + -> ty::trait_def::TraitImpls, [] specialization_graph_of: SpecializationGraph(DefId) -> Rc, [] is_object_safe: ObjectSafety(DefId) -> bool, } diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs index b0357a35b83..eb60f9d1010 100644 --- a/src/librustc/ty/trait_def.rs +++ b/src/librustc/ty/trait_def.rs @@ -35,6 +35,60 @@ pub struct TraitDef { pub def_path_hash: u64, } +// We don't store the list of impls in a flat list because each cached list of +// `relevant_impls_for` we would then duplicate all blanket impls. By keeping +// blanket and non-blanket impls separate, we can share the list of blanket +// impls. +#[derive(Clone)] +pub struct TraitImpls { + blanket_impls: Rc>, + non_blanket_impls: Rc>, +} + +impl TraitImpls { + pub fn iter(&self) -> TraitImplsIter { + TraitImplsIter { + blanket_impls: self.blanket_impls.clone(), + non_blanket_impls: self.non_blanket_impls.clone(), + index: 0 + } + } +} + +#[derive(Clone)] +pub struct TraitImplsIter { + blanket_impls: Rc>, + non_blanket_impls: Rc>, + index: usize, +} + +impl Iterator for TraitImplsIter { + type Item = DefId; + + fn next(&mut self) -> Option { + if self.index < self.blanket_impls.len() { + let bi_index = self.index; + self.index += 1; + Some(self.blanket_impls[bi_index]) + } else { + let nbi_index = self.index - self.blanket_impls.len(); + if nbi_index < self.non_blanket_impls.len() { + self.index += 1; + Some(self.non_blanket_impls[nbi_index]) + } else { + None + } + } + } + + fn size_hint(&self) -> (usize, Option) { + let items_left = (self.blanket_impls.len() + self.non_blanket_impls.len()) - self.index; + (items_left, Some(items_left)) + } +} + +impl ExactSizeIterator for TraitImplsIter {} + impl<'a, 'gcx, 'tcx> TraitDef { pub fn new(def_id: DefId, unsafety: hir::Unsafety, @@ -58,7 +112,7 @@ impl<'a, 'gcx, 'tcx> TraitDef { } pub fn for_each_impl(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, mut f: F) { - for &impl_def_id in tcx.trait_impls_of(self.def_id).iter() { + for impl_def_id in tcx.trait_impls_of(self.def_id).iter() { f(impl_def_id); } } @@ -89,7 +143,7 @@ impl<'a, 'gcx, 'tcx> TraitDef { tcx.trait_impls_of(self.def_id) }; - for &impl_def_id in relevant_impls.iter() { + for impl_def_id in relevant_impls.iter() { f(impl_def_id); } } @@ -98,8 +152,8 @@ impl<'a, 'gcx, 'tcx> TraitDef { // Query provider for `trait_impls_of`. pub(super) fn trait_impls_of_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_id: DefId) - -> Rc> { - let mut impls = if trait_id.is_local() { + -> TraitImpls { + let remote_impls = if trait_id.is_local() { // Traits defined in the current crate can't have impls in upstream // crates, so we don't bother querying the cstore. Vec::new() @@ -107,46 +161,61 @@ pub(super) fn trait_impls_of_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx.sess.cstore.implementations_of_trait(Some(trait_id)) }; - impls.extend(tcx.hir - .trait_impls(trait_id) - .iter() - .map(|&node_id| tcx.hir.local_def_id(node_id)) - .filter(|&impl_def_id| { - let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); - !trait_ref.references_error() - })); - Rc::new(impls) + let mut blanket_impls = Vec::new(); + let mut non_blanket_impls = Vec::new(); + + let local_impls = tcx.hir + .trait_impls(trait_id) + .into_iter() + .map(|&node_id| tcx.hir.local_def_id(node_id)); + + for impl_def_id in local_impls.chain(remote_impls.into_iter()) { + let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); + if impl_def_id.is_local() && impl_trait_ref.references_error() { + continue + } + + if fast_reject::simplify_type(tcx, impl_trait_ref.self_ty(), false).is_some() { + non_blanket_impls.push(impl_def_id); + } else { + blanket_impls.push(impl_def_id); + } + } + + TraitImpls { + blanket_impls: Rc::new(blanket_impls), + non_blanket_impls: Rc::new(non_blanket_impls), + } } // Query provider for `relevant_trait_impls_for`. pub(super) fn relevant_trait_impls_provider<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, (trait_id, self_ty): (DefId, fast_reject::SimplifiedType)) - -> Rc> + -> TraitImpls { let all_trait_impls = tcx.trait_impls_of(trait_id); let relevant: Vec = all_trait_impls + .non_blanket_impls .iter() - .map(|&impl_def_id| impl_def_id) + .cloned() .filter(|&impl_def_id| { let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); let impl_simple_self_ty = fast_reject::simplify_type(tcx, impl_trait_ref.self_ty(), - false); - if let Some(impl_simple_self_ty) = impl_simple_self_ty { - impl_simple_self_ty == self_ty - } else { - // blanket impl (?) - true - } + false).unwrap(); + impl_simple_self_ty == self_ty }) .collect(); - if all_trait_impls.len() == relevant.len() { + if all_trait_impls.non_blanket_impls.len() == relevant.len() { // If we didn't filter anything out, re-use the existing vec. all_trait_impls } else { - Rc::new(relevant) + TraitImpls { + blanket_impls: all_trait_impls.blanket_impls.clone(), + non_blanket_impls: Rc::new(relevant), + } } } From 7644508b4e1216731d11378d2dd487eba20217f8 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 14 May 2017 12:41:42 -0700 Subject: [PATCH 047/103] appveyor: Wrap handle.exe download in a retry Should help deal with spurious download failures. --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 42c6256a95a..96de1d90f25 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -141,9 +141,9 @@ install: - set PATH="C:\Program Files (x86)\Inno Setup 5";%PATH% # Help debug some handle issues on AppVeyor - - ps: Invoke-WebRequest -Uri https://download.sysinternals.com/files/Handle.zip -OutFile handle.zip + - appveyor-retry appveyor DownloadFile https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-15-Handle.zip - mkdir handle - - ps: Expand-Archive handle.zip -dest handle + - 7z x -ohandle 2017-05-15-Handle.zip - set PATH=%PATH%;%CD%\handle - handle.exe -accepteula -help From c5a35f4a8d0bd1726f52710063d4f72cb4cc338b Mon Sep 17 00:00:00 2001 From: Ivan Dardi Date: Mon, 15 May 2017 16:59:43 -0300 Subject: [PATCH 048/103] Update documentation --- src/libcore/iter/iterator.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 1277acfb8bb..27b7bb2fa2e 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -266,8 +266,7 @@ pub trait Iterator { /// /// # Panics /// - /// If the given step is `0`, the method will panic if debug assertions are - /// enabled. + /// The method will panic if the given step is `0`. /// /// # Examples /// From 49555172016d3ca59b8ece596e28578741d8d076 Mon Sep 17 00:00:00 2001 From: Ivan Dardi Date: Mon, 15 May 2017 17:00:02 -0300 Subject: [PATCH 049/103] Add entry to the Unstable Book --- .../unstable-book/src/library-features/iterator-step-by.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/doc/unstable-book/src/library-features/iterator-step-by.md diff --git a/src/doc/unstable-book/src/library-features/iterator-step-by.md b/src/doc/unstable-book/src/library-features/iterator-step-by.md new file mode 100644 index 00000000000..8467cb68862 --- /dev/null +++ b/src/doc/unstable-book/src/library-features/iterator-step-by.md @@ -0,0 +1,7 @@ +# `iterator_step_by` + +The tracking issue for this feature is: [#27741] + +[#27741]: https://github.com/rust-lang/rust/issues/27741 + +------------------------ From 6db4beb3e833eb7d8daad30e2a9ecc27d54a0318 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 12 May 2017 05:43:48 -0400 Subject: [PATCH 050/103] use equality in the coerce-unsized check This seems both to be a safe, conservative choice, and it sidesteps the cycle in #41936. Fixes #41936. --- src/librustc/infer/combine.rs | 19 +++++++ src/librustc_typeck/coherence/builtin.rs | 51 ++++++++++++++++++- ...sue-41936-variance-coerce-unsized-cycle.rs | 38 ++++++++++++++ 3 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 src/test/run-pass/issue-41936-variance-coerce-unsized-cycle.rs diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index 18909a784d6..aabb6aff551 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -39,10 +39,12 @@ use super::sub::Sub; use super::InferCtxt; use super::{MiscVariable, TypeTrace}; +use hir::def_id::DefId; use ty::{IntType, UintType}; use ty::{self, Ty, TyCtxt}; use ty::error::TypeError; use ty::relate::{self, Relate, RelateResult, TypeRelation}; +use ty::subst::Substs; use traits::{Obligation, PredicateObligations}; use syntax::ast; @@ -336,6 +338,23 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, ' Ok(ty::Binder(self.relate(a.skip_binder(), b.skip_binder())?)) } + fn relate_item_substs(&mut self, + item_def_id: DefId, + a_subst: &'tcx Substs<'tcx>, + b_subst: &'tcx Substs<'tcx>) + -> RelateResult<'tcx, &'tcx Substs<'tcx>> + { + if self.ambient_variance == ty::Variance::Invariant { + // Avoid fetching the variance if we are in an invariant + // context; no need, and it can induce dependency cycles + // (e.g. #41849). + relate::relate_substs(self, None, a_subst, b_subst) + } else { + let opt_variances = self.tcx().variances_of(item_def_id); + relate::relate_substs(self, Some(&opt_variances), a_subst, b_subst) + } + } + fn relate_with_variance>(&mut self, variance: ty::Variance, a: &T, diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index d40a68e6056..556bd618c78 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -249,6 +249,45 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, return err_info; } + // Here we are considering a case of converting + // `S` to S`. As an example, let's imagine a struct `Foo`, + // which acts like a pointer to `U`, but carries along some extra data of type `T`: + // + // struct Foo { + // extra: T, + // ptr: *mut U, + // } + // + // We might have an impl that allows (e.g.) `Foo` to be unsized + // to `Foo`. That impl would look like: + // + // impl, V> CoerceUnsized> for Foo {} + // + // Here `U = [i32; 3]` and `V = [i32]`. At runtime, + // when this coercion occurs, we would be changing the + // field `ptr` from a thin pointer of type `*mut [i32; + // 3]` to a fat pointer of type `*mut [i32]` (with + // extra data `3`). **The purpose of this check is to + // make sure that we know how to do this conversion.** + // + // To check if this impl is legal, we would walk down + // the fields of `Foo` and consider their types with + // both substitutes. We are looking to find that + // exactly one (non-phantom) field has changed its + // type, which we will expect to be the pointer that + // is becoming fat (we could probably generalize this + // to mutiple thin pointers of the same type becoming + // fat, but we don't). In this case: + // + // - `extra` has type `T` before and type `T` after + // - `ptr` has type `*mut U` before and type `*mut V` after + // + // Since just one field changed, we would then check + // that `*mut U: CoerceUnsized<*mut V>` is implemented + // (in other words, that we know how to do this + // conversion). This will work out because `U: + // Unsize`, and we have a builtin rule that `*mut + // U` can be coerced to `*mut V` if `U: Unsize`. let fields = &def_a.struct_variant().fields; let diff_fields = fields.iter() .enumerate() @@ -260,8 +299,16 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, return None; } - // Ignore fields that aren't significantly changed - if let Ok(ok) = infcx.sub_types(false, &cause, b, a) { + // Ignore fields that aren't changed; it may + // be that we could get away with subtyping or + // something more accepting, but we use + // equality because we want to be able to + // perform this check without computing + // variance where possible. (This is because + // we may have to evaluate constraint + // expressions in the course of execution.) + // See e.g. #41936. + if let Ok(ok) = infcx.eq_types(false, &cause, b, a) { if ok.obligations.is_empty() { return None; } diff --git a/src/test/run-pass/issue-41936-variance-coerce-unsized-cycle.rs b/src/test/run-pass/issue-41936-variance-coerce-unsized-cycle.rs new file mode 100644 index 00000000000..bfbead87891 --- /dev/null +++ b/src/test/run-pass/issue-41936-variance-coerce-unsized-cycle.rs @@ -0,0 +1,38 @@ +// Copyright 2016 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. + +// Regression test for #41936. The coerce-unsized trait check in +// coherence was using subtyping, which triggered variance +// computation, which failed because it required type info for fields +// that had not (yet) been computed. + +#![feature(unsize)] +#![feature(coerce_unsized)] + +use std::{marker,ops}; + +// Change the array to a non-array, and error disappears +// Adding a new field to the end keeps the error +struct LogDataBuf([u8;8]); + +struct Aref +{ + // Inner structure triggers the error, removing the inner removes the message. + ptr: Box>, +} +impl, U: ?Sized> ops::CoerceUnsized> for Aref {} + +struct ArefInner +{ + // Even with this field commented out, the error is raised. + data: T, +} + +fn main(){} From 958c67d9c8ca74370e2052fd8a3d209b8184d1f4 Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Sat, 13 May 2017 21:40:06 +0200 Subject: [PATCH 051/103] adressed comments by @kennytm and @petrochenkov --- src/libsyntax/diagnostics/plugin.rs | 4 +-- src/libsyntax/ext/base.rs | 4 +-- src/libsyntax/ext/tt/macro_parser.rs | 50 +++++++++++++++------------- src/libsyntax/ext/tt/macro_rules.rs | 3 +- src/libsyntax/feature_gate.rs | 7 ++-- src/libsyntax/parse/classify.rs | 2 +- src/libsyntax/parse/mod.rs | 1 - src/libsyntax/parse/parser.rs | 6 ++-- src/libsyntax/print/pprust.rs | 2 +- 9 files changed, 41 insertions(+), 38 deletions(-) diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index ca89a80fdee..73aeb40df84 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -111,7 +111,7 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt, // overflow the maximum line width. description.map(|raw_msg| { let msg = raw_msg.as_str(); - if !msg.starts_with('\n') || !msg.ends_with('\n') { + if !msg.starts_with("\n") || !msg.ends_with("\n") { ecx.span_err(span, &format!( "description for error code {} doesn't start and end with a newline", code @@ -120,7 +120,7 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt, // URLs can be unavoidably longer than the line limit, so we allow them. // Allowed format is: `[name]: https://www.rust-lang.org/` - let is_url = |l: &str| l.starts_with('[') && l.contains("]:") && l.contains("http"); + let is_url = |l: &str| l.starts_with("[") && l.contains("]:") && l.contains("http"); if msg.lines().any(|line| line.len() > MAX_DESCRIPTION_WIDTH && !is_url(line)) { ecx.span_err(span, &format!( diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index f78089aaa75..31a7e0d58d0 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -635,8 +635,8 @@ pub struct ExpansionData { } /// One of these is made during expansion and incrementally updated as we go; -/// when a macro expansion occurs, the resulting nodes have the backtrace() -/// -> `expn_info` of their expansion context stored into their span. +/// when a macro expansion occurs, the resulting nodes have the `backtrace() +/// -> expn_info` of their expansion context stored into their span. pub struct ExtCtxt<'a> { pub parse_sess: &'a parse::ParseSess, pub ecfg: expand::ExpansionConfig<'a>, diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 8e28135b11d..a0103a1e3fe 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -36,43 +36,47 @@ //! repetitions indicated by Kleene stars. It only advances or calls out to the //! real Rust parser when no `cur_eis` items remain //! -//! Example: Start parsing `a a a a b` against [· a $( a )* a b]. +//! Example: //! -//! Remaining input: `a a a a b` -//! `next_eis`: `[· a $( a )* a b]` +//! ```text, ignore +//! Start parsing a a a a b against [· a $( a )* a b]. //! -//! - - - Advance over an `a`. - - - +//! Remaining input: a a a a b +//! next_eis: [· a $( a )* a b] //! -//! Remaining input: `a a a b` -//! cur: `[a · $( a )* a b]` +//! - - - Advance over an a. - - - +//! +//! Remaining input: a a a b +//! cur: [a · $( a )* a b] //! Descend/Skip (first item). -//! next: `[a $( · a )* a b] [a $( a )* · a b]`. +//! next: [a $( · a )* a b] [a $( a )* · a b]. //! -//! - - - Advance over an `a`. - - - +//! - - - Advance over an a. - - - //! -//! Remaining input: `a a b` -//! cur: `[a $( a · )* a b]` next: `[a $( a )* a · b]` +//! Remaining input: a a b +//! cur: [a $( a · )* a b] next: [a $( a )* a · b] //! Finish/Repeat (first item) -//! next: `[a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b]` +//! next: [a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b] //! -//! - - - Advance over an `a`. - - - (this looks exactly like the last step) +//! - - - Advance over an a. - - - (this looks exactly like the last step) //! -//! Remaining input: `a b` -//! cur: `[a $( a · )* a b]` next: `[a $( a )* a · b]` +//! Remaining input: a b +//! cur: [a $( a · )* a b] next: [a $( a )* a · b] //! Finish/Repeat (first item) -//! next: `[a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b]` +//! next: [a $( a )* · a b] [a $( · a )* a b] [a $( a )* a · b] //! -//! - - - Advance over an `a`. - - - (this looks exactly like the last step) +//! - - - Advance over an a. - - - (this looks exactly like the last step) //! -//! Remaining input: `b` -//! cur: `[a $( a · )* a b]` next: `[a $( a )* a · b]` +//! Remaining input: b +//! cur: [a $( a · )* a b] next: [a $( a )* a · b] //! Finish/Repeat (first item) -//! next: `[a $( a )* · a b] [a $( · a )* a b]` +//! next: [a $( a )* · a b] [a $( · a )* a b] //! -//! - - - Advance over a `b`. - - - +//! - - - Advance over a b. - - - //! -//! Remaining input: `` -//! eof: `[a $( a )* a b ·]` +//! Remaining input: '' +//! eof: [a $( a )* a b ·] +//! ``` pub use self::NamedMatch::*; pub use self::ParseResult::*; @@ -485,7 +489,7 @@ pub fn parse(sess: &ParseSess, tts: TokenStream, ms: &[TokenTree], directory: Op } fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal { - if let "tt" = name { + if name == "tt" { return token::NtTT(p.parse_token_tree()); } // check at the beginning and the parser checks after each bump diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 9e3fe30e7bf..4a307ab18a5 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -858,6 +858,7 @@ fn quoted_tt_to_string(tt: "ed::TokenTree) -> String { match *tt { quoted::TokenTree::Token(_, ref tok) => ::print::pprust::token_to_string(tok), quoted::TokenTree::MetaVarDecl(_, name, kind) => format!("${}:{}", name, kind), - _ => panic!("unexpected quoted::TokenTree::{{Sequence or Delimited}} in follow set checker"), + _ => panic!("unexpected quoted::TokenTree::{{Sequence or Delimited}} \ + in follow set checker"), } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index f95693f6820..09090ab8731 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1216,7 +1216,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, _) => { - if let ast::ImplPolarity::Negative = polarity { + if polarity == ast::ImplPolarity::Negative { gate_feature_post!(&self, optin_builtin_traits, i.span, "negative trait bounds are not yet fully implemented; \ @@ -1269,10 +1269,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FunctionRetTy) { if let ast::FunctionRetTy::Ty(ref output_ty) = *ret_ty { - if let ast::TyKind::Never = output_ty.node { - return + if output_ty.node != ast::TyKind::Never { + self.visit_ty(output_ty) } - self.visit_ty(output_ty) } } diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs index c2755cf0591..0c6f09ba766 100644 --- a/src/libsyntax/parse/classify.rs +++ b/src/libsyntax/parse/classify.rs @@ -48,8 +48,8 @@ pub fn expr_is_simple_block(e: &ast::Expr) -> bool { pub fn stmt_ends_with_semi(stmt: &ast::StmtKind) -> bool { match *stmt { ast::StmtKind::Local(_) => true, - ast::StmtKind::Item(_) => false, ast::StmtKind::Expr(ref e) => expr_requires_semi_to_be_stmt(e), + ast::StmtKind::Item(_) | ast::StmtKind::Semi(..) | ast::StmtKind::Mac(..) => false, } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 4fcf7614622..1eff819d755 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -341,7 +341,6 @@ pub fn raw_str_lit(lit: &str) -> String { debug!("raw_str_lit: given {}", escape_default(lit)); let mut res = String::with_capacity(lit.len()); - // FIXME #8372: This could be a for-loop if it didn't borrow the iterator let mut chars = lit.chars().peekable(); while let Some(c) = chars.next() { if c == '\r' { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 28c57e0855f..4741f896d3c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1546,7 +1546,7 @@ impl<'a> Parser<'a> { pub fn is_named_argument(&mut self) -> bool { let offset = match self.token { token::BinOp(token::And) | - token::AndAnd | + token::AndAnd => 1, _ if self.token.is_keyword(keywords::Mut) => 1, _ => 0 }; @@ -2569,7 +2569,7 @@ impl<'a> Parser<'a> { s.print_usize(float.trunc() as usize)?; s.pclose()?; word(&mut s.s, ".")?; - word(&mut s.s, fstr.splitn(2, '.').last().unwrap()) + word(&mut s.s, fstr.splitn(2, ".").last().unwrap()) }); err.span_suggestion( lo.to(self.prev_span), @@ -4917,7 +4917,7 @@ impl<'a> Parser<'a> { } } } else { - if let ast::ImplPolarity::Negative = polarity { + if polarity == ast::ImplPolarity::Negative { // This is a negated type implementation // `impl !MyType {}`, which is not allowed. self.span_err(neg_span, "inherent implementation can't be negated"); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 6114db25fe8..bdb4ce34b91 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1327,7 +1327,7 @@ impl<'a> State<'a> { space(&mut self.s)?; } - if let ast::ImplPolarity::Negative = polarity { + if polarity == ast::ImplPolarity::Negative { word(&mut self.s, "!")?; } From 67a203f42cf9c215148a574ff285ca943dcb135e Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 15 May 2017 21:02:38 -0400 Subject: [PATCH 052/103] move issue-41697 to a mir-opt test --- src/test/{run-pass => mir-opt}/issue-41697.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/test/{run-pass => mir-opt}/issue-41697.rs (100%) diff --git a/src/test/run-pass/issue-41697.rs b/src/test/mir-opt/issue-41697.rs similarity index 100% rename from src/test/run-pass/issue-41697.rs rename to src/test/mir-opt/issue-41697.rs From d9a3f624330724c99a9f7dbedcf305c4c3407012 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 15 May 2017 21:12:40 -0400 Subject: [PATCH 053/103] remove compile-flags --- src/test/mir-opt/issue-41697.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/mir-opt/issue-41697.rs b/src/test/mir-opt/issue-41697.rs index d59b6a16562..47eeffe35a8 100644 --- a/src/test/mir-opt/issue-41697.rs +++ b/src/test/mir-opt/issue-41697.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags:-Zdump-mir=NEVER_MATCHED - // Regression test for #41697. Using dump-mir was triggering // artificial cycles: during type-checking, we had to get the MIR for // the constant expressions in `[u8; 2]`, which in turn would trigger From 7caf08447ee3a5a94c4214e8439b61bbef30c98f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 11 May 2017 17:52:39 -0400 Subject: [PATCH 054/103] avoid cycles in mir-dump, take 2 --- src/librustc_mir/util/pretty.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 14f277d1767..eaba573dcd2 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -324,7 +324,9 @@ fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut Write) MirSource::Promoted(_, i) => write!(w, "{:?} in", i)? } - write!(w, " {}", tcx.node_path_str(src.item_id()))?; + item_path::with_forced_impl_filename_line(|| { // see notes on #41697 elsewhere + write!(w, " {}", tcx.node_path_str(src.item_id())) + })?; if let MirSource::Fn(_) = src { write!(w, "(")?; From c9f9bc27804e9ff7f87481f3eb5edf167936a3bd Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 15 May 2017 21:23:51 -0400 Subject: [PATCH 055/103] fix typo making maps public --- src/librustc/ty/maps.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 1fd9e8f7375..f448ca89347 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -592,7 +592,7 @@ macro_rules! define_map_struct { output: $output:tt) => { define_map_struct! { tcx: $tcx, - ready: ([pub] $attrs $name), + ready: ([] $attrs $name), input: ($($input)*), output: $output } From b310a259f80210d3ea2b4eac4ab19cd611b6bfba Mon Sep 17 00:00:00 2001 From: Marc-Antoine Perennou Date: Fri, 28 Apr 2017 11:01:15 +0200 Subject: [PATCH 056/103] rustbuild: allow configuring bindir Signed-off-by: Marc-Antoine Perennou --- src/bootstrap/config.rs | 10 ++++++++-- src/bootstrap/config.toml.example | 9 ++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 9c536111811..28ff14ab30f 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -100,6 +100,7 @@ pub struct Config { pub musl_root: Option, pub prefix: Option, pub docdir: Option, + pub bindir: Option, pub libdir: Option, pub libdir_relative: Option, pub mandir: Option, @@ -165,9 +166,10 @@ struct Build { #[derive(RustcDecodable, Default, Clone)] struct Install { prefix: Option, - mandir: Option, docdir: Option, + bindir: Option, libdir: Option, + mandir: Option, } /// TOML representation of how the LLVM build is configured. @@ -315,9 +317,10 @@ impl Config { if let Some(ref install) = toml.install { config.prefix = install.prefix.clone().map(PathBuf::from); - config.mandir = install.mandir.clone().map(PathBuf::from); config.docdir = install.docdir.clone().map(PathBuf::from); + config.bindir = install.bindir.clone().map(PathBuf::from); config.libdir = install.libdir.clone().map(PathBuf::from); + config.mandir = install.mandir.clone().map(PathBuf::from); } if let Some(ref llvm) = toml.llvm { @@ -526,6 +529,9 @@ impl Config { "CFG_DOCDIR" => { self.docdir = Some(PathBuf::from(value)); } + "CFG_BINDIR" => { + self.bindir = Some(PathBuf::from(value)); + } "CFG_LIBDIR" => { self.libdir = Some(PathBuf::from(value)); } diff --git a/src/bootstrap/config.toml.example b/src/bootstrap/config.toml.example index 25da976a555..57cafbaf280 100644 --- a/src/bootstrap/config.toml.example +++ b/src/bootstrap/config.toml.example @@ -160,15 +160,18 @@ # Instead of installing to /usr/local, install to this path instead. #prefix = "/usr/local" +# Where to install documentation in `prefix` above +#docdir = "share/doc/rust" + +# Where to install binaries in `prefix` above +#bindir = "bin" + # Where to install libraries in `prefix` above #libdir = "lib" # Where to install man pages in `prefix` above #mandir = "share/man" -# Where to install documentation in `prefix` above -#docdir = "share/doc/rust" - # ============================================================================= # Options for compiling Rust code itself # ============================================================================= From 0a8b8febb0b456c4df930ee8086a2e447e27f243 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Perennou Date: Fri, 28 Apr 2017 13:50:50 +0200 Subject: [PATCH 057/103] configure: allow configuring bindir Signed-off-by: Marc-Antoine Perennou --- configure | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configure b/configure index db41f0dfb94..af59d5b0bb8 100755 --- a/configure +++ b/configure @@ -519,6 +519,7 @@ valopt_nosave host "${CFG_BUILD}" "GNUs ./configure syntax LLVM host triples" valopt_nosave target "${CFG_HOST}" "GNUs ./configure syntax LLVM target triples" valopt_nosave mandir "${CFG_PREFIX}/share/man" "install man pages in PATH" valopt_nosave docdir "${CFG_PREFIX}/share/doc/rust" "install documentation in PATH" +valopt_nosave bindir "${CFG_PREFIX}/bin" "install binaries" # On Windows this determines root of the subtree for target libraries. # Host runtime libs always go to 'bin'. @@ -710,6 +711,7 @@ envopt LDFLAGS CFG_PREFIX=${CFG_PREFIX%/} CFG_MANDIR=${CFG_MANDIR%/} CFG_DOCDIR=${CFG_DOCDIR%/} +CFG_BINDIR=${CFG_BINDIR%/} CFG_HOST="$(echo $CFG_HOST | tr ',' ' ')" CFG_TARGET="$(echo $CFG_TARGET | tr ',' ' ')" @@ -750,6 +752,7 @@ putvar CFG_X86_64_LINUX_ANDROID_NDK putvar CFG_NACL_CROSS_PATH putvar CFG_MANDIR putvar CFG_DOCDIR +putvar CFG_BINDIR putvar CFG_USING_LIBCPP msg From 93f3b0c9139926c6acf0b2d63ab8d39f45c90089 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Perennou Date: Fri, 28 Apr 2017 10:58:46 +0200 Subject: [PATCH 058/103] rustbuild: pass bindir to install_sh Signed-off-by: Marc-Antoine Perennou --- src/bootstrap/install.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index c805522fbf5..c16e6c72819 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -25,14 +25,17 @@ use dist::{sanitize_sh, tmpdir}; pub fn install(build: &Build, stage: u32, host: &str) { let prefix_default = PathBuf::from("/usr/local"); let docdir_default = PathBuf::from("share/doc/rust"); - let mandir_default = PathBuf::from("share/man"); + let bindir_default = PathBuf::from("bin"); let libdir_default = PathBuf::from("lib"); + let mandir_default = PathBuf::from("share/man"); let prefix = build.config.prefix.as_ref().unwrap_or(&prefix_default); let docdir = build.config.docdir.as_ref().unwrap_or(&docdir_default); + let bindir = build.config.bindir.as_ref().unwrap_or(&bindir_default); let libdir = build.config.libdir.as_ref().unwrap_or(&libdir_default); let mandir = build.config.mandir.as_ref().unwrap_or(&mandir_default); let docdir = prefix.join(docdir); + let bindir = prefix.join(bindir); let libdir = prefix.join(libdir); let mandir = prefix.join(mandir); @@ -40,6 +43,7 @@ pub fn install(build: &Build, stage: u32, host: &str) { let prefix = add_destdir(&prefix, &destdir); let docdir = add_destdir(&docdir, &destdir); + let bindir = add_destdir(&bindir, &destdir); let libdir = add_destdir(&libdir, &destdir); let mandir = add_destdir(&mandir, &destdir); @@ -47,29 +51,29 @@ pub fn install(build: &Build, stage: u32, host: &str) { t!(fs::create_dir_all(&empty_dir)); if build.config.docs { install_sh(&build, "docs", "rust-docs", &build.rust_package_vers(), - stage, host, &prefix, &docdir, &libdir, &mandir, &empty_dir); + stage, host, &prefix, &docdir, &bindir, &libdir, &mandir, &empty_dir); } for target in build.config.target.iter() { install_sh(&build, "std", "rust-std", &build.rust_package_vers(), - stage, target, &prefix, &docdir, &libdir, &mandir, &empty_dir); + stage, target, &prefix, &docdir, &bindir, &libdir, &mandir, &empty_dir); } if build.config.extended { install_sh(&build, "cargo", "cargo", &build.cargo_package_vers(), - stage, host, &prefix, &docdir, &libdir, &mandir, &empty_dir); + stage, host, &prefix, &docdir, &bindir, &libdir, &mandir, &empty_dir); install_sh(&build, "rls", "rls", &build.rls_package_vers(), - stage, host, &prefix, &docdir, &libdir, &mandir, &empty_dir); + stage, host, &prefix, &docdir, &bindir, &libdir, &mandir, &empty_dir); } install_sh(&build, "rustc", "rustc", &build.rust_package_vers(), - stage, host, &prefix, &docdir, &libdir, &mandir, &empty_dir); + stage, host, &prefix, &docdir, &bindir, &libdir, &mandir, &empty_dir); t!(fs::remove_dir_all(&empty_dir)); } fn install_sh(build: &Build, package: &str, name: &str, version: &str, stage: u32, host: &str, - prefix: &Path, docdir: &Path, libdir: &Path, mandir: &Path, empty_dir: &Path) { + prefix: &Path, docdir: &Path, bindir: &Path, libdir: &Path, mandir: &Path, empty_dir: &Path) { println!("Install {} stage{} ({})", package, stage, host); let package_name = format!("{}-{}-{}", name, version, host); @@ -78,6 +82,7 @@ fn install_sh(build: &Build, package: &str, name: &str, version: &str, stage: u3 .arg(sanitize_sh(&tmpdir(build).join(&package_name).join("install.sh"))) .arg(format!("--prefix={}", sanitize_sh(prefix))) .arg(format!("--docdir={}", sanitize_sh(docdir))) + .arg(format!("--bindir={}", sanitize_sh(bindir))) .arg(format!("--libdir={}", sanitize_sh(libdir))) .arg(format!("--mandir={}", sanitize_sh(mandir))) .arg("--disable-ldconfig"); From e8a74c32a429b1745b7abaa132c1bdbe5f6c656a Mon Sep 17 00:00:00 2001 From: Marc-Antoine Perennou Date: Fri, 28 Apr 2017 11:03:58 +0200 Subject: [PATCH 059/103] rustbuild: allow configuring sysconfdir Signed-off-by: Marc-Antoine Perennou --- src/bootstrap/config.rs | 6 ++++++ src/bootstrap/config.toml.example | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 28ff14ab30f..0fb597564e3 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -99,6 +99,7 @@ pub struct Config { // Fallback musl-root for all targets pub musl_root: Option, pub prefix: Option, + pub sysconfdir: Option, pub docdir: Option, pub bindir: Option, pub libdir: Option, @@ -166,6 +167,7 @@ struct Build { #[derive(RustcDecodable, Default, Clone)] struct Install { prefix: Option, + sysconfdir: Option, docdir: Option, bindir: Option, libdir: Option, @@ -317,6 +319,7 @@ impl Config { if let Some(ref install) = toml.install { config.prefix = install.prefix.clone().map(PathBuf::from); + config.sysconfdir = install.sysconfdir.clone().map(PathBuf::from); config.docdir = install.docdir.clone().map(PathBuf::from); config.bindir = install.bindir.clone().map(PathBuf::from); config.libdir = install.libdir.clone().map(PathBuf::from); @@ -526,6 +529,9 @@ impl Config { "CFG_PREFIX" => { self.prefix = Some(PathBuf::from(value)); } + "CFG_SYSCONFDIR" => { + self.sysconfdir = Some(PathBuf::from(value)); + } "CFG_DOCDIR" => { self.docdir = Some(PathBuf::from(value)); } diff --git a/src/bootstrap/config.toml.example b/src/bootstrap/config.toml.example index 57cafbaf280..df180be4e27 100644 --- a/src/bootstrap/config.toml.example +++ b/src/bootstrap/config.toml.example @@ -160,6 +160,10 @@ # Instead of installing to /usr/local, install to this path instead. #prefix = "/usr/local" +# Where to install system configuration files +# If this is a relative path, it will get installed in `prefix` above +#sysconfdir = "/etc" + # Where to install documentation in `prefix` above #docdir = "share/doc/rust" From f72fce598c50544e1741cd3cb8fa19d8bc5d9bda Mon Sep 17 00:00:00 2001 From: Marc-Antoine Perennou Date: Fri, 28 Apr 2017 11:08:47 +0200 Subject: [PATCH 060/103] rustbuild: pass sysconfdir to install_sh Signed-off-by: Marc-Antoine Perennou --- src/bootstrap/install.rs | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index c16e6c72819..386b001971b 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -24,16 +24,19 @@ use dist::{sanitize_sh, tmpdir}; /// Installs everything. pub fn install(build: &Build, stage: u32, host: &str) { let prefix_default = PathBuf::from("/usr/local"); + let sysconfdir_default = PathBuf::from("/etc"); let docdir_default = PathBuf::from("share/doc/rust"); let bindir_default = PathBuf::from("bin"); let libdir_default = PathBuf::from("lib"); let mandir_default = PathBuf::from("share/man"); let prefix = build.config.prefix.as_ref().unwrap_or(&prefix_default); + let sysconfdir = build.config.sysconfdir.as_ref().unwrap_or(&sysconfdir_default); let docdir = build.config.docdir.as_ref().unwrap_or(&docdir_default); let bindir = build.config.bindir.as_ref().unwrap_or(&bindir_default); let libdir = build.config.libdir.as_ref().unwrap_or(&libdir_default); let mandir = build.config.mandir.as_ref().unwrap_or(&mandir_default); + let sysconfdir = prefix.join(sysconfdir); let docdir = prefix.join(docdir); let bindir = prefix.join(bindir); let libdir = prefix.join(libdir); @@ -42,6 +45,7 @@ pub fn install(build: &Build, stage: u32, host: &str) { let destdir = env::var_os("DESTDIR").map(PathBuf::from); let prefix = add_destdir(&prefix, &destdir); + let sysconfdir = add_destdir(&sysconfdir, &destdir); let docdir = add_destdir(&docdir, &destdir); let bindir = add_destdir(&bindir, &destdir); let libdir = add_destdir(&libdir, &destdir); @@ -51,29 +55,35 @@ pub fn install(build: &Build, stage: u32, host: &str) { t!(fs::create_dir_all(&empty_dir)); if build.config.docs { install_sh(&build, "docs", "rust-docs", &build.rust_package_vers(), - stage, host, &prefix, &docdir, &bindir, &libdir, &mandir, &empty_dir); + stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, + &mandir, &empty_dir); } for target in build.config.target.iter() { install_sh(&build, "std", "rust-std", &build.rust_package_vers(), - stage, target, &prefix, &docdir, &bindir, &libdir, &mandir, &empty_dir); + stage, target, &prefix, &sysconfdir, &docdir, &bindir, &libdir, + &mandir, &empty_dir); } if build.config.extended { install_sh(&build, "cargo", "cargo", &build.cargo_package_vers(), - stage, host, &prefix, &docdir, &bindir, &libdir, &mandir, &empty_dir); + stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, + &mandir, &empty_dir); install_sh(&build, "rls", "rls", &build.rls_package_vers(), - stage, host, &prefix, &docdir, &bindir, &libdir, &mandir, &empty_dir); + stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, + &mandir, &empty_dir); } install_sh(&build, "rustc", "rustc", &build.rust_package_vers(), - stage, host, &prefix, &docdir, &bindir, &libdir, &mandir, &empty_dir); + stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, + &mandir, &empty_dir); t!(fs::remove_dir_all(&empty_dir)); } fn install_sh(build: &Build, package: &str, name: &str, version: &str, stage: u32, host: &str, - prefix: &Path, docdir: &Path, bindir: &Path, libdir: &Path, mandir: &Path, empty_dir: &Path) { + prefix: &Path, sysconfdir: &Path, docdir: &Path, bindir: &Path, libdir: &Path, + mandir: &Path, empty_dir: &Path) { println!("Install {} stage{} ({})", package, stage, host); let package_name = format!("{}-{}-{}", name, version, host); @@ -81,6 +91,7 @@ fn install_sh(build: &Build, package: &str, name: &str, version: &str, stage: u3 cmd.current_dir(empty_dir) .arg(sanitize_sh(&tmpdir(build).join(&package_name).join("install.sh"))) .arg(format!("--prefix={}", sanitize_sh(prefix))) + .arg(format!("--sysconfdir={}", sanitize_sh(sysconfdir))) .arg(format!("--docdir={}", sanitize_sh(docdir))) .arg(format!("--bindir={}", sanitize_sh(bindir))) .arg(format!("--libdir={}", sanitize_sh(libdir))) From 6dbd706906d922ae5606eb5654dd804095ffc8c8 Mon Sep 17 00:00:00 2001 From: est31 Date: Tue, 16 May 2017 08:53:02 +0200 Subject: [PATCH 061/103] put option_try macro def under #[cfg(unix)] --- src/librustc/util/common.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 7b5e2253109..17564671a1e 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -116,6 +116,7 @@ pub fn record_time(accu: &Cell, f: F) -> T where } // Like std::macros::try!, but for Option<>. +#[cfg(unix)] macro_rules! option_try( ($e:expr) => (match $e { Some(e) => e, None => return None }) ); From 282b40249e158376fcc4682879be40fb80c4e36f Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Tue, 16 May 2017 09:21:30 +0200 Subject: [PATCH 062/103] (hopefully) fix pprust error --- src/libsyntax/print/pprust.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index bdb4ce34b91..83c289ff80b 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -961,9 +961,11 @@ impl<'a> State<'a> { { self.rbox(0, b)?; let len = elts.len(); - for (i, elt) in elts.iter().enumerate() { + let mut i = 0; + for elt in elts { self.maybe_print_comment(get_span(elt).hi)?; op(self, elt)?; + i += 1; if i < len { word(&mut self.s, ",")?; self.maybe_print_trailing_comment(get_span(elt), From bf2e0c2fe18f20d41afe0869acbeb6c7ce6d3d31 Mon Sep 17 00:00:00 2001 From: faso Date: Tue, 16 May 2017 10:56:07 +0300 Subject: [PATCH 063/103] Typo --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0314a5dfd8d..8f121f8d6ed 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -177,7 +177,7 @@ python x.py test src/test/rustdoc python x.py build src/libcore --stage 0 ``` -You can explore the build system throught the various `--help` pages for each +You can explore the build system through the various `--help` pages for each subcommand. For example to learn more about a command you can run: ``` From 7a50784336f9de7c3b95cf0ae540ac0f3e8ab992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Huchet?= Date: Mon, 15 May 2017 17:16:58 +0200 Subject: [PATCH 064/103] improve collapse toggle render (css) --- src/librustdoc/html/static/rustdoc.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 60ea6ed1d8d..570a1980782 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -617,6 +617,11 @@ a.test-arrow:hover{ top: 0; } +h3 > .collapse-toggle, h4 > .collapse-toggle { + font-size: 0.8em; + top: 5px; +} + .toggle-wrapper > .collapse-toggle { left: -24px; margin-top: 0px; From d731b04af11e212a9132a86f986ccebb3372aef5 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 16 May 2017 15:03:20 +0200 Subject: [PATCH 065/103] Don't use queries::try_get() in assoc_ty projection --- src/librustc/traits/project.rs | 41 +++++++++++++--------------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index e119ead7473..0b12531f60a 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -29,7 +29,6 @@ use infer::type_variable::TypeVariableOrigin; use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap}; use syntax::ast; use syntax::symbol::Symbol; -use syntax_pos::DUMMY_SP; use ty::subst::Subst; use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt}; use ty::fold::{TypeFoldable, TypeFolder}; @@ -1324,32 +1323,24 @@ fn assoc_ty_def<'cx, 'gcx, 'tcx>( // This function may be called while we are still building the // specialization graph that is queried below (via TraidDef::ancestors()), - // so, in order to avoid infinite recursion, we detect this case by - // seeing if a query of the specialization graph fails with a cycle error. - // If we are in cycle, and thus still building the graph, we perform a - // reduced version of the associated item lookup that does not need the - // specialization graph. - let specialization_graph_complete = - ty::queries::specialization_graph_of::try_get(tcx, - DUMMY_SP, - trait_def_id).is_ok(); - if !specialization_graph_complete { - let impl_node = specialization_graph::Node::Impl(impl_def_id); - for item in impl_node.items(tcx) { - if item.kind == ty::AssociatedKind::Type && item.name == assoc_ty_name { - return Some(specialization_graph::NodeItem { - node: specialization_graph::Node::Impl(impl_def_id), - item: item, - }); - } + // so, in order to avoid unnecessary infinite recursion, we manually look + // for the associated item at the given impl. + // If there is no such item in that impl, this function will fail with a + // cycle error if the specialization graph is currently being built. + let impl_node = specialization_graph::Node::Impl(impl_def_id); + for item in impl_node.items(tcx) { + if item.kind == ty::AssociatedKind::Type && item.name == assoc_ty_name { + return Some(specialization_graph::NodeItem { + node: specialization_graph::Node::Impl(impl_def_id), + item: item, + }); } - None - } else { - trait_def - .ancestors(tcx, impl_def_id) - .defs(tcx, assoc_ty_name, ty::AssociatedKind::Type) - .next() } + + trait_def + .ancestors(tcx, impl_def_id) + .defs(tcx, assoc_ty_name, ty::AssociatedKind::Type) + .next() } // # Cache From 0a77a588578b69497caac7a507f875c8f258c9aa Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 16 May 2017 15:04:32 +0200 Subject: [PATCH 066/103] Add test cases for cyclic specialization graph construction --- .../coherence-inherited-assoc-ty-cycle-err.rs | 34 +++++++++++++++++++ .../specialization/assoc-ty-graph-cycle.rs | 33 ++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 src/test/compile-fail/coherence-inherited-assoc-ty-cycle-err.rs create mode 100644 src/test/run-pass/specialization/assoc-ty-graph-cycle.rs diff --git a/src/test/compile-fail/coherence-inherited-assoc-ty-cycle-err.rs b/src/test/compile-fail/coherence-inherited-assoc-ty-cycle-err.rs new file mode 100644 index 00000000000..5d7f3396740 --- /dev/null +++ b/src/test/compile-fail/coherence-inherited-assoc-ty-cycle-err.rs @@ -0,0 +1,34 @@ +// 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. + +// Formerly this ICEd with the following message: +// Tried to project an inherited associated type during coherence checking, +// which is currently not supported. +// +// No we expect to run into a more user-friendly cycle error instead. + +#![feature(specialization)] + +trait Trait { type Assoc; } +//~^ unsupported cyclic reference between types/traits detected [E0391] + +impl Trait for Vec { + type Assoc = (); +} + +impl Trait for Vec {} + +impl Trait for String { + type Assoc = (); +} + +impl Trait< as Trait>::Assoc> for String {} + +fn main() {} diff --git a/src/test/run-pass/specialization/assoc-ty-graph-cycle.rs b/src/test/run-pass/specialization/assoc-ty-graph-cycle.rs new file mode 100644 index 00000000000..a65dcf33d85 --- /dev/null +++ b/src/test/run-pass/specialization/assoc-ty-graph-cycle.rs @@ -0,0 +1,33 @@ +// 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. + +// Make sure we don't crash with a cycle error during coherence. + +#![feature(specialization)] + +trait Trait { + type Assoc; +} + +impl Trait for Vec { + default type Assoc = (); +} + +impl Trait for Vec { + type Assoc = u8; +} + +impl Trait for String { + type Assoc = (); +} + +impl Trait< as Trait>::Assoc> for String {} + +fn main() {} From 08cc29e7628628d3511870ef59d4c4b6efe96a74 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Perennou Date: Tue, 16 May 2017 16:28:36 +0200 Subject: [PATCH 067/103] update lzma-sys to 0.1.4 fixes build when DESTDIR is set Signed-off-by: Marc-Antoine Perennou --- src/Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 9269fc0f448..2b76dea6122 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -345,7 +345,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lzma-sys" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1126,7 +1126,7 @@ name = "xz2" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lzma-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "lzma-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1160,7 +1160,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf" "checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135" "checksum log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5141eca02775a762cc6cd564d8d2c50f67c0ea3a372cbf1c51592b3e029e10ad" -"checksum lzma-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c5eaaa53b35fa17482ee2c001b04242827b47ae0faba72663fee3dee32366248" +"checksum lzma-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "fedff6a5cbb24494ec6ee4784e9ac5c187161fede04c7767d49bf87544013afa" "checksum mdbook 0.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "f1e2e9d848514dcfad4195788d0d42ae5153a477c191d75d5b84fab10f222fbd" "checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4" "checksum miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "28eaee17666671fa872e567547e8428e83308ebe5808cdf6a0e28397dbe2c726" From c9f616cba0af77ecb341d794487df7434d793181 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 16 May 2017 07:56:20 -0700 Subject: [PATCH 068/103] Update cargo submodule This pulls in a fix for #41797 to the master branch, I'll send a separate PR for the beta branch. --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 13d92c64d01..b007d82be9a 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 13d92c64d0153d95dbabeb49b828bbbef4b1bb34 +Subproject commit b007d82be9aa82ae69d382b392d91c151df16da2 From 42051ceb162b8e69bcc9df580974ccff8f22f3c8 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 16 May 2017 17:12:00 +0200 Subject: [PATCH 069/103] Use tcx.type_of(impl) instead of TraitRef::self_ty() for getting Self in relevant_impls_for(). --- src/librustc/ty/trait_def.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs index eb60f9d1010..865297c7ecb 100644 --- a/src/librustc/ty/trait_def.rs +++ b/src/librustc/ty/trait_def.rs @@ -170,12 +170,12 @@ pub(super) fn trait_impls_of_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, .map(|&node_id| tcx.hir.local_def_id(node_id)); for impl_def_id in local_impls.chain(remote_impls.into_iter()) { - let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); - if impl_def_id.is_local() && impl_trait_ref.references_error() { + let impl_self_ty = tcx.type_of(impl_def_id); + if impl_def_id.is_local() && impl_self_ty.references_error() { continue } - if fast_reject::simplify_type(tcx, impl_trait_ref.self_ty(), false).is_some() { + if fast_reject::simplify_type(tcx, impl_self_ty, false).is_some() { non_blanket_impls.push(impl_def_id); } else { blanket_impls.push(impl_def_id); @@ -201,9 +201,9 @@ pub(super) fn relevant_trait_impls_provider<'a, 'tcx>( .iter() .cloned() .filter(|&impl_def_id| { - let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); + let impl_self_ty = tcx.type_of(impl_def_id); let impl_simple_self_ty = fast_reject::simplify_type(tcx, - impl_trait_ref.self_ty(), + impl_self_ty, false).unwrap(); impl_simple_self_ty == self_ty }) From dda2d756facc1c8100261e2ebd4e115c84f515cc Mon Sep 17 00:00:00 2001 From: Marc-Antoine Perennou Date: Tue, 16 May 2017 17:22:52 +0200 Subject: [PATCH 070/103] rustbuild: fix bash completion installation dir Signed-off-by: Marc-Antoine Perennou --- src/bootstrap/dist.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 6557b8410b1..511f2c9e80e 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -596,7 +596,7 @@ pub fn cargo(build: &Build, stage: u32, target: &str) { // Prepare the image directory t!(fs::create_dir_all(image.join("share/zsh/site-functions"))); - t!(fs::create_dir_all(image.join("etc/bash_completions.d"))); + t!(fs::create_dir_all(image.join("etc/bash_completion.d"))); let cargo = build.cargo_out(&compiler, Mode::Tool, target) .join(exe("cargo", target)); install(&cargo, &image.join("bin"), 0o755); @@ -606,7 +606,7 @@ pub fn cargo(build: &Build, stage: u32, target: &str) { } install(&etc.join("_cargo"), &image.join("share/zsh/site-functions"), 0o644); copy(&etc.join("cargo.bashcomp.sh"), - &image.join("etc/bash_completions.d/cargo")); + &image.join("etc/bash_completion.d/cargo")); let doc = image.join("share/doc/cargo"); install(&src.join("README.md"), &doc, 0o644); install(&src.join("LICENSE-MIT"), &doc, 0o644); From 08660afe90d6c2257c59408116c718929af58963 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 16 May 2017 17:31:18 +0200 Subject: [PATCH 071/103] Remove unreachable branches in traits::project --- src/librustc/traits/project.rs | 186 +++++++++++++-------------------- 1 file changed, 71 insertions(+), 115 deletions(-) diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 0b12531f60a..d7911870f39 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -900,96 +900,50 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>( // In either case, we handle this by not adding a // candidate for an impl if it contains a `default` // type. - let opt_node_item = assoc_ty_def(selcx, - impl_data.impl_def_id, - obligation.predicate.item_name); - let new_candidate = if let Some(node_item) = opt_node_item { - let is_default = if node_item.node.is_from_trait() { - // If true, the impl inherited a `type Foo = Bar` - // given in the trait, which is implicitly default. - // Otherwise, the impl did not specify `type` and - // neither did the trait: - // - // ```rust - // trait Foo { type T; } - // impl Foo for Bar { } - // ``` - // - // This is an error, but it will be - // reported in `check_impl_items_against_trait`. - // We accept it here but will flag it as - // an error when we confirm the candidate - // (which will ultimately lead to `normalize_to_error` - // being invoked). - node_item.item.defaultness.has_value() - } else { - node_item.item.defaultness.is_default() || - selcx.tcx().impl_is_default(node_item.node.def_id()) - }; + let node_item = assoc_ty_def(selcx, + impl_data.impl_def_id, + obligation.predicate.item_name); - // Only reveal a specializable default if we're past type-checking - // and the obligations is monomorphic, otherwise passes such as - // transmute checking and polymorphic MIR optimizations could - // get a result which isn't correct for all monomorphizations. - if !is_default { + let is_default = if node_item.node.is_from_trait() { + // If true, the impl inherited a `type Foo = Bar` + // given in the trait, which is implicitly default. + // Otherwise, the impl did not specify `type` and + // neither did the trait: + // + // ```rust + // trait Foo { type T; } + // impl Foo for Bar { } + // ``` + // + // This is an error, but it will be + // reported in `check_impl_items_against_trait`. + // We accept it here but will flag it as + // an error when we confirm the candidate + // (which will ultimately lead to `normalize_to_error` + // being invoked). + node_item.item.defaultness.has_value() + } else { + node_item.item.defaultness.is_default() || + selcx.tcx().impl_is_default(node_item.node.def_id()) + }; + + // Only reveal a specializable default if we're past type-checking + // and the obligations is monomorphic, otherwise passes such as + // transmute checking and polymorphic MIR optimizations could + // get a result which isn't correct for all monomorphizations. + let new_candidate = if !is_default { + Some(ProjectionTyCandidate::Select) + } else if selcx.projection_mode() == Reveal::All { + assert!(!poly_trait_ref.needs_infer()); + if !poly_trait_ref.needs_subst() { Some(ProjectionTyCandidate::Select) - } else if selcx.projection_mode() == Reveal::All { - assert!(!poly_trait_ref.needs_infer()); - if !poly_trait_ref.needs_subst() { - Some(ProjectionTyCandidate::Select) - } else { - None - } } else { None } } else { - // This is saying that neither the trait nor - // the impl contain a definition for this - // associated type. Normally this situation - // could only arise through a compiler bug -- - // if the user wrote a bad item name, it - // should have failed in astconv. **However**, - // at coherence-checking time, we only look at - // the topmost impl (we don't even consider - // the trait itself) for the definition -- and - // so in that case it may be that the trait - // *DOES* have a declaration, but we don't see - // it, and we end up in this branch. - // - // This is kind of tricky to handle actually. - // For now, we just unconditionally ICE, - // because otherwise, examples like the - // following will succeed: - // - // ``` - // trait Assoc { - // type Output; - // } - // - // impl Assoc for T { - // default type Output = bool; - // } - // - // impl Assoc for u8 {} - // impl Assoc for u16 {} - // - // trait Foo {} - // impl Foo for ::Output {} - // impl Foo for ::Output {} - // return None; - // } - // ``` - // - // The essential problem here is that the - // projection fails, leaving two unnormalized - // types, which appear not to unify -- so the - // overlap check succeeds, when it should - // fail. - span_bug!(obligation.cause.span, - "Tried to project an inherited associated type during \ - coherence checking, which is currently not supported."); + None }; + candidate_set.vec.extend(new_candidate); } super::VtableParam(..) => { @@ -1274,35 +1228,25 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>( let VtableImplData { substs, nested, impl_def_id } = impl_vtable; let tcx = selcx.tcx(); - let trait_ref = obligation.predicate.trait_ref; let assoc_ty = assoc_ty_def(selcx, impl_def_id, obligation.predicate.item_name); - match assoc_ty { - Some(node_item) => { - let ty = if !node_item.item.defaultness.has_value() { - // This means that the impl is missing a definition for the - // associated type. This error will be reported by the type - // checker method `check_impl_items_against_trait`, so here we - // just return TyError. - debug!("confirm_impl_candidate: no associated type {:?} for {:?}", - node_item.item.name, - obligation.predicate.trait_ref); - tcx.types.err - } else { - tcx.type_of(node_item.item.def_id) - }; - let substs = translate_substs(selcx.infcx(), impl_def_id, substs, node_item.node); - Progress { - ty: ty.subst(tcx, substs), - obligations: nested, - cacheable: true - } - } - None => { - span_bug!(obligation.cause.span, - "No associated type for {:?}", - trait_ref); - } + let ty = if !assoc_ty.item.defaultness.has_value() { + // This means that the impl is missing a definition for the + // associated type. This error will be reported by the type + // checker method `check_impl_items_against_trait`, so here we + // just return TyError. + debug!("confirm_impl_candidate: no associated type {:?} for {:?}", + assoc_ty.item.name, + obligation.predicate.trait_ref); + tcx.types.err + } else { + tcx.type_of(assoc_ty.item.def_id) + }; + let substs = translate_substs(selcx.infcx(), impl_def_id, substs, assoc_ty.node); + Progress { + ty: ty.subst(tcx, substs), + obligations: nested, + cacheable: true } } @@ -1315,7 +1259,7 @@ fn assoc_ty_def<'cx, 'gcx, 'tcx>( selcx: &SelectionContext<'cx, 'gcx, 'tcx>, impl_def_id: DefId, assoc_ty_name: ast::Name) - -> Option> + -> specialization_graph::NodeItem { let tcx = selcx.tcx(); let trait_def_id = tcx.impl_trait_ref(impl_def_id).unwrap().def_id; @@ -1330,17 +1274,29 @@ fn assoc_ty_def<'cx, 'gcx, 'tcx>( let impl_node = specialization_graph::Node::Impl(impl_def_id); for item in impl_node.items(tcx) { if item.kind == ty::AssociatedKind::Type && item.name == assoc_ty_name { - return Some(specialization_graph::NodeItem { + return specialization_graph::NodeItem { node: specialization_graph::Node::Impl(impl_def_id), item: item, - }); + }; } } - trait_def + if let Some(assoc_item) = trait_def .ancestors(tcx, impl_def_id) .defs(tcx, assoc_ty_name, ty::AssociatedKind::Type) - .next() + .next() { + assoc_item + } else { + // This is saying that neither the trait nor + // the impl contain a definition for this + // associated type. Normally this situation + // could only arise through a compiler bug -- + // if the user wrote a bad item name, it + // should have failed in astconv. + bug!("No associated type `{}` for {}", + assoc_ty_name, + tcx.item_path_str(impl_def_id)) + } } // # Cache From 3f980beb3eeb545ff9de7f3976beb7872b4e2ae6 Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Tue, 16 May 2017 18:54:41 +0100 Subject: [PATCH 072/103] loop_break_value: fix tests (but ignore one expected not to compile) --- .../src/language-features/loop-break-value.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/loop-break-value.md b/src/doc/unstable-book/src/language-features/loop-break-value.md index 7218cad1c22..9e36ea7b1a7 100644 --- a/src/doc/unstable-book/src/language-features/loop-break-value.md +++ b/src/doc/unstable-book/src/language-features/loop-break-value.md @@ -15,6 +15,8 @@ never exits. A `loop` can instead evaluate to a useful value via *break with value*: ```rust +#![feature(loop_break_value)] + // Find the first square number over 1000: let mut n = 1; let square = loop { @@ -28,6 +30,8 @@ let square = loop { The evaluation type may be specified externally: ```rust +#![feature(loop_break_value)] + // Declare that value returned is unsigned 64-bit: let n: u64 = loop { break 1; @@ -37,9 +41,11 @@ let n: u64 = loop { It is an error if types do not agree, either between a "break" value and an external requirement, or between multiple "break" values: -```rust +```no_compile +#![feature(loop_break_value)] + loop { - if random_bool() { + if true { break 1u32; } else { break 0u8; // error: types do not agree @@ -69,6 +75,8 @@ When no value is given, the value `()` is assumed, thus `break;` is equivalent t Using a label allows returning a value from an inner loop: ```rust +#![feature(loop_break_value)] + let result = 'outer: loop { for n in 1..10 { if n > 4 { From ff399a098e6ee6112c4b3685d3041a83b50aa58a Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 16 May 2017 16:00:13 -0400 Subject: [PATCH 073/103] Update the various books to latest This includes a draft of chapter 20 of the book! --- src/doc/book | 2 +- src/doc/reference | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/book b/src/doc/book index ad7de198561..97422981c53 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit ad7de198561b3a12217ea2da76d796d9c7fc0ed3 +Subproject commit 97422981c53a00f7c3d6584d363443117f179fff diff --git a/src/doc/reference b/src/doc/reference index 6b0de90d87d..f7a108dfa9e 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 6b0de90d87dda15e323ef24cdf7ed873ac5cf4d3 +Subproject commit f7a108dfa9e90b07821700c55d01f08a9adf005c From e616d12cbbe2b38ab3d683233e716104ca56d388 Mon Sep 17 00:00:00 2001 From: Austin Bonander Date: Sat, 22 Apr 2017 23:05:35 -0700 Subject: [PATCH 074/103] Document the `proc_macro` feature in the Unstable Book --- .../src/language-features/proc-macro.md | 231 ++++++++++++++++++ 1 file changed, 231 insertions(+) diff --git a/src/doc/unstable-book/src/language-features/proc-macro.md b/src/doc/unstable-book/src/language-features/proc-macro.md index f8b53bd5a2f..1bd8c41629e 100644 --- a/src/doc/unstable-book/src/language-features/proc-macro.md +++ b/src/doc/unstable-book/src/language-features/proc-macro.md @@ -6,5 +6,236 @@ The tracking issue for this feature is: [#38356] ------------------------ +This feature flag guards the new procedural macro features as laid out by [RFC 1566], which alongside the now-stable +[custom derives], provide stabilizable alternatives to the compiler plugin API (which requires the use of +perma-unstable internal APIs) for programmatically modifying Rust code at compile-time. +The two new procedural macro kinds are: + +* Function-like procedural macros which are invoked like regular declarative macros, and: +* Attribute-like procedural macros which can be applied to any item which built-in attributes can +be applied to, and which can take arguments in their invocation as well. + +Additionally, this feature flag implicitly enables the [`use_extern_macros`](language-features/use-extern-macros.html) feature, +which allows macros to be imported like any other item with `use` statements, as compared to +applying `#[macro_use]` to an `extern crate` declaration. It is important to note that procedural macros may +**only** be imported in this manner, and will throw an error otherwise. + +You **must** declare the `proc_macro` feature in both the crate declaring these new procedural macro kinds as well as +in any crates that use them. + +### Common Concepts + +As with custom derives, procedural macros may only be declared in crates of the `proc-macro` type, and must be public +functions. No other public items may be declared in `proc-macro` crates, but private items are fine. + +To declare your crate as a `proc-macro` crate, simply add: + +```toml +[lib] +proc-macro = true +``` + +to your `Cargo.toml`. + +Unlike custom derives, however, the name of the function implementing the procedural macro is used directly as the +procedural macro's name, so choose carefully. + +Additionally, both new kinds of procedural macros return a `TokenStream` which *wholly* replaces the original +invocation and its input. + +#### Importing + +As referenced above, the new procedural macros are not meant to be imported via `#[macro_use]` and will throw an +error if they are. Instead, they are meant to be imported like any other item in Rust, with `use` statements: + +```rust,ignore +#![feature(proc_macro)] + +// Where `my_proc_macros` is some crate of type `proc_macro` +extern crate my_proc_macros; + +// And declares a `#[proc_macro] pub fn my_bang_macro()` at its root. +use my_proc_macros::my_bang_macro; + +fn main() { + println!("{}", my_bang_macro!()); +} +``` + +#### Error Reporting + +Any panics in a procedural macro implementation will be caught by the compiler and turned into an error message pointing +to the problematic invocation. Thus, it is important to make your panic messages as informative as possible: use +`Option::expect` instead of `Option::unwrap` and `Result::expect` instead of `Result::unwrap`, and inform the user of +the error condition as unambiguously as you can. + +#### `TokenStream` + +The `proc_macro::TokenStream` type is hardcoded into the signatures of procedural macro functions for both input and +output. It is a wrapper around the compiler's internal representation for a given chunk of Rust code. + +### Function-like Procedural Macros + +These are procedural macros that are invoked like regular declarative macros. They are declared as public functions in +crates of the `proc_macro` type and using the `#[proc_macro]` attribute. The name of the declared function becomes the +name of the macro as it is to be imported and used. The function must be of the kind `fn(TokenStream) -> TokenStream` +where the sole argument is the input to the macro and the return type is the macro's output. + +This kind of macro can expand to anything that is valid for the context it is invoked in, including expressions and +statements, as well as items. + +**Note**: invocations of this kind of macro require a wrapping `[]`, `{}` or `()` like regular macros, but these do not +appear in the input, only the tokens between them. The tokens between the braces do not need to be valid Rust syntax. + +my_macro_crate/src/lib.rs + +```rust,ignore +#![feature(proc_macro)] + +// This is always necessary to get the `TokenStream` typedef. +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro] +pub fn say_hello(_input: TokenStream) -> TokenStream { + // This macro will accept any input because it ignores it. + // To enforce correctness in macros which don't take input, + // you may want to add `assert!(_input.to_string().is_empty());`. + "println!(\"Hello, world!\")".parse().unwrap() +} +``` + +my_macro_user/Cargo.toml + +```toml +[dependencies] +my_macro_crate = { path = "" } +``` + +my_macro_user/src/lib.rs + +```rust,ignore +#![feature(proc_macro)] + +extern crate my_macro_crate; + +use my_macro_crate::say_hello; + +fn main() { + say_hello!(); +} +``` + +As expected, this prints `Hello, world!`. + +### Attribute-like Procedural Macros + +These are arguably the most powerful flavor of procedural macro as they can be applied anywhere attributes are allowed. + +They are declared as public functions in crates of the `proc-macro` type, using the `#[proc_macro_attribute]` attribute. +The name of the function becomes the name of the attribute as it is to be imported and used. The function must be of the +kind `fn(TokenStream, TokenStream) -> TokenStream` where: + +The first argument represents any metadata for the attribute (see [the reference chapter on attributes][refr-attr]). +Only the metadata itself will appear in this argument, for example: + + * `#[my_macro]` will get an empty string. + * `#[my_macro = "string"]` will get `= "string"`. + * `#[my_macro(ident)]` will get `(ident)`. + * etc. + +The second argument is the item that the attribute is applied to. It can be a function, a type definition, +an impl block, an `extern` block, or a module—attribute invocations can take the inner form (`#![my_attr]`) +or outer form (`#[my_attr]`). + +The return type is the output of the macro which *wholly* replaces the item it was applied to. Thus, if your intention +is to merely modify an item, it *must* be copied to the output. The output must be an item; expressions, statements +and bare blocks are not allowed. + +There is no restriction on how many items an attribute-like procedural macro can emit as long as they are valid in +the given context. + +my_macro_crate/src/lib.rs + +```rust,ignore +#![feature(proc_macro)] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +/// Adds a `/// ### Panics` docstring to the end of the input's documentation +/// +/// Does not assert that its receiver is a function or method. +#[proc_macro_attribute] +pub fn panics_note(args: TokenStream, input: TokenStream) -> TokenStream { + let args = args.to_string(); + let mut input = input.to_string(); + + assert!(args.starts_with("= \""), "`#[panics_note]` requires an argument of the form \ + `#[panics_note = \"panic note here\"]`"); + + // Get just the bare note string + let panics_note = args.trim_matches(&['=', ' ', '"'][..]); + + // The input will include all docstrings regardless of where the attribute is placed, + // so we need to find the last index before the start of the item + let insert_idx = idx_after_last_docstring(&input); + + // And insert our `### Panics` note there so it always appears at the end of an item's docs + input.insert_str(insert_idx, &format!("/// # Panics \n/// {}\n", panics_note)); + + input.parse().unwrap() +} + +// `proc-macro` crates can contain any kind of private item still +fn idx_after_last_docstring(input: &str) -> usize { + // Skip docstring lines to find the start of the item proper + input.lines().skip_while(|line| line.trim_left().starts_with("///")).next() + // Find the index of the first non-docstring line in the input + // Note: assumes this exact line is unique in the input + .and_then(|line_after| input.find(line_after)) + // No docstrings in the input + .unwrap_or(0) +} +``` + +my_macro_user/Cargo.toml + +```toml +[dependencies] +my_macro_crate = { path = "" } +``` + +my_macro_user/src/lib.rs + +```rust,ignore +#![feature(proc_macro)] + +extern crate my_macro_crate; + +use my_macro_crate::panics_note; + +/// Do the `foo` thing. +#[panics_note = "Always."] +pub fn foo() { + panic!() +} +``` + +Then the rendered documentation for `pub fn foo` will look like this: + +> `pub fn foo()` +> +> ---- +> Do the `foo` thing. +> # Panics +> Always. + +[RFC 1566]: https://github.com/rust-lang/rfcs/blob/master/text/1566-proc-macros.md +[custom derives]: https://doc.rust-lang.org/book/procedural-macros.html +[rust-lang/rust#41430]: https://github.com/rust-lang/rust/issues/41430 +[refr-attr]: https://doc.rust-lang.org/reference/attributes.html From 7ab35b703a2213eba91cadcad90aefa169f48f1f Mon Sep 17 00:00:00 2001 From: Diggory Hardy Date: Wed, 17 May 2017 13:00:10 +0100 Subject: [PATCH 075/103] loop_break_value doc: remove note about other loops --- .../unstable-book/src/language-features/loop-break-value.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/loop-break-value.md b/src/doc/unstable-book/src/language-features/loop-break-value.md index 9e36ea7b1a7..e8fefe3b733 100644 --- a/src/doc/unstable-book/src/language-features/loop-break-value.md +++ b/src/doc/unstable-book/src/language-features/loop-break-value.md @@ -57,10 +57,6 @@ let n: i32 = loop { }; ``` -For now, breaking with a value is only possible with `loop`; the same functionality may -some day be added to `for` and `while` (this would require some new syntax like -`while f() { break 1; } default { break 0; }`). - #### Break: label, value Four forms of `break` are available, where EXPR is some expression which evaluates to a value: From 1b6a182cf1e400b63ae8692e3183beabe541ea6c Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 17 May 2017 15:14:30 +0200 Subject: [PATCH 076/103] Improve the error management when /proc is not mounted This PR does two things: * Triggers an error on GNU/Linux & Android when /proc/self/exe doesn't exist * Handle the error properly --- src/librustc/session/filesearch.rs | 11 ++++++++--- src/libstd/sys/unix/os.rs | 7 ++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/librustc/session/filesearch.rs b/src/librustc/session/filesearch.rs index 82c2425aead..47b988a21b4 100644 --- a/src/librustc/session/filesearch.rs +++ b/src/librustc/session/filesearch.rs @@ -159,9 +159,14 @@ pub fn get_or_default_sysroot() -> PathBuf { }) } - match canonicalize(env::current_exe().ok()) { - Some(mut p) => { p.pop(); p.pop(); p } - None => bug!("can't determine value for sysroot") + match env::current_exe() { + Ok(exe) => { + match canonicalize(Some(exe)) { + Some(mut p) => { p.pop(); p.pop(); return p; }, + None => bug!("can't determine value for sysroot") + } + } + Err(ref e) => panic!(format!("failed to get current_exe: {}", e)) } } diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 36928696c40..8e41fd009be 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -253,7 +253,12 @@ pub fn current_exe() -> io::Result { #[cfg(any(target_os = "linux", target_os = "android", target_os = "emscripten"))] pub fn current_exe() -> io::Result { - ::fs::read_link("/proc/self/exe") + let selfexe = PathBuf::from("/proc/self/exe"); + if selfexe.exists() { + ::fs::read_link(selfexe) + } else { + Err(io::Error::new(io::ErrorKind::Other, "no /proc/self/exe available. Is /proc mounted?")) + } } #[cfg(any(target_os = "macos", target_os = "ios"))] From 0e79b9790a5d1b547b7766762cb0e2938cfc369a Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Sun, 30 Apr 2017 08:11:58 +0900 Subject: [PATCH 077/103] Unify all stage2 tools into a workspace This avoids double compiled Cargo. Hopefully this would speed up (extended) compilation for ~10m. Notes: when updating Cargo submodule, the replacement version may also need to be updated. --- .gitmodules | 4 +- src/Cargo.lock | 1121 +++++++++++++++++++++++++++++++++++--- src/Cargo.toml | 7 +- src/tools/rust-installer | 2 +- 4 files changed, 1055 insertions(+), 79 deletions(-) diff --git a/.gitmodules b/.gitmodules index 791404344ef..1ef3c086a1c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -23,7 +23,7 @@ url = https://github.com/rust-lang-nursery/nomicon.git [submodule "src/tools/cargo"] path = src/tools/cargo - url = https://github.com/rust-lang/cargo + url = https://github.com/rust-lang/cargo.git [submodule "reference"] path = src/doc/reference url = https://github.com/rust-lang-nursery/reference.git @@ -32,4 +32,4 @@ url = https://github.com/rust-lang/book.git [submodule "src/tools/rls"] path = src/tools/rls - url = https://github.com/rust-lang-nursery/rls + url = https://github.com/rust-lang-nursery/rls.git diff --git a/src/Cargo.lock b/src/Cargo.lock index c9de8f99008..804fd580773 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -6,6 +6,23 @@ dependencies = [ "libc 0.0.0", ] +[[package]] +name = "advapi32-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "aho-corasick" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "aho-corasick" version = "0.6.3" @@ -48,16 +65,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "arena" version = "0.0.0" -[[package]] -name = "atty" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "backtrace" version = "0.3.0" @@ -67,7 +74,7 @@ dependencies = [ "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -78,7 +85,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -86,6 +93,11 @@ name = "bitflags" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bitflags" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "bitflags" version = "0.8.2" @@ -100,17 +112,22 @@ dependencies = [ "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "bufstream" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "build-manifest" version = "0.1.0" dependencies = [ - "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -121,6 +138,78 @@ dependencies = [ "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "cargo" +version = "0.20.0" +source = "git+https://github.com/rust-lang/cargo#2b32084293d8da63b48de56363a0f2e986ec3367" +replace = "cargo 0.20.0" + +[[package]] +name = "cargo" +version = "0.20.0" +dependencies = [ + "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cargotest 0.1.0", + "chrono 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crates-io 0.9.0", + "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "curl 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "docopt 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", + "fs2 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "git2 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "git2-curl 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "hamcrest 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "libgit2-sys 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)", + "psapi-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_ignored 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "shell-escape 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tar 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cargotest" +version = "0.1.0" +dependencies = [ + "bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo 0.20.0", + "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", + "git2 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "hamcrest 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tar 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cargotest2" version = "0.1.0" @@ -130,19 +219,28 @@ name = "cfg-if" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "chrono" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "clap" -version = "2.22.1" +version = "2.19.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-segmentation 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -180,13 +278,54 @@ dependencies = [ "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "core" version = "0.0.0" +[[package]] +name = "crates-io" +version = "0.9.0" +dependencies = [ + "curl 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "curl" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "curl-sys 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-probe 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "curl-sys" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "libz-sys 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "dbghelp-sys" version = "0.2.0" @@ -196,16 +335,58 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "derive-new" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "diff" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "docopt" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "dtoa" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "either" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "enum_primitive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "env_logger" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "env_logger" version = "0.4.2" @@ -232,7 +413,7 @@ name = "filetime" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -248,7 +429,7 @@ name = "flate2" version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -256,11 +437,35 @@ dependencies = [ name = "fmt_macros" version = "0.0.0" +[[package]] +name = "foreign-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "fs2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "gcc" version = "0.3.46" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "gdi32-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "getopts" version = "0.0.0" @@ -270,29 +475,77 @@ name = "getopts" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "git2" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "libgit2-sys 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-probe 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "git2-curl" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "curl 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "git2 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "glob" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "graphviz" version = "0.0.0" +[[package]] +name = "hamcrest" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "handlebars" -version = "0.25.2" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "idna" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "installer" version = "0.0.0" dependencies = [ - "clap 2.22.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.19.3 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -303,6 +556,14 @@ dependencies = [ "xz2 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "itertools" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "itoa" version = "0.3.1" @@ -317,6 +578,19 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "languageserver-types" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "lazy_static" version = "0.2.8" @@ -331,9 +605,46 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.21" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "libgit2-sys" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cmake 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", + "curl-sys 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libz-sys 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libssh2-sys" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cmake 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "libz-sys 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libz-sys" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "linkchecker" version = "0.1.0" @@ -350,24 +661,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "matches" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "mdbook" version = "0.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "clap 2.22.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.19.3 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "handlebars 0.25.2 (registry+https://github.com/rust-lang/crates.io-index)", + "handlebars 0.25.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "open 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memchr" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -375,7 +699,7 @@ name = "memchr" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -384,7 +708,96 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "miow" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "multimap" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "net2" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-bigint 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "num-complex 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", + "num-iter 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", + "num-rational 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-bigint" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-complex" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-integer" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-iter" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-rational" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-bigint 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -397,7 +810,7 @@ name = "num_cpus" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -405,6 +818,35 @@ name = "open" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "openssl" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "openssl-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "openssl-sys" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", + "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "owning_ref" version = "0.3.3" @@ -436,6 +878,11 @@ name = "pest" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "pkg-config" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "proc_macro" version = "0.0.0" @@ -452,6 +899,15 @@ dependencies = [ "syntax_pos 0.0.0", ] +[[package]] +name = "psapi-sys" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "pulldown-cmark" version = "0.0.8" @@ -471,9 +927,33 @@ dependencies = [ [[package]] name = "quick-error" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "quote" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "quote" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "racer" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "clap 2.19.3 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_errors 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "typed-arena 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand" version = "0.0.0" @@ -481,6 +961,31 @@ dependencies = [ "core 0.0.0", ] +[[package]] +name = "rand" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "redox_syscall" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "regex" +version = "0.1.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "regex" version = "0.2.1" @@ -493,6 +998,11 @@ dependencies = [ "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "regex-syntax" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "regex-syntax" version = "0.4.0" @@ -506,13 +1016,48 @@ version = "0.1.0" name = "remote-test-server" version = "0.1.0" +[[package]] +name = "rls" +version = "0.1.0" +dependencies = [ + "cargo 0.20.0 (git+https://github.com/rust-lang/cargo)", + "derive-new 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "languageserver-types 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "racer 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-analysis 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-data 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-vfs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustfmt 0.8.4 (git+https://github.com/rust-lang-nursery/rustfmt)", + "serde 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rls-analysis" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "derive-new 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-data 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rls-data" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -520,14 +1065,25 @@ name = "rls-span" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rls-vfs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "racer 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustbook" version = "0.1.0" dependencies = [ - "clap 2.22.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.19.3 (registry+https://github.com/rust-lang/crates.io-index)", "mdbook 0.0.21 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -566,7 +1122,7 @@ dependencies = [ [[package]] name = "rustc-serialize" -version = "0.3.23" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -823,7 +1379,7 @@ dependencies = [ "rls-data 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", - "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_typeck 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", @@ -902,6 +1458,33 @@ dependencies = [ "syntax_pos 0.0.0", ] +[[package]] +name = "rustfmt" +version = "0.8.4" +source = "git+https://github.com/rust-lang-nursery/rustfmt#bf9b3fa1d7cab2f7bd541539d397a92b4954ec96" +dependencies = [ + "diff 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "multimap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "strings 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_errors 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "same-file" version = "0.1.3" @@ -912,25 +1495,86 @@ dependencies = [ ] [[package]] -name = "serde" -version = "0.9.11" +name = "semver" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "serde" +version = "0.9.15" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde_derive" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive_internals 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_derive_internals" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_ignored" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "serde_json" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_json" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serialize" version = "0.0.0" +[[package]] +name = "shell-escape" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "stable_deref_trait" version = "1.0.0" @@ -967,11 +1611,51 @@ dependencies = [ "core 0.0.0", ] +[[package]] +name = "strings" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "strsim" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "strsim" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "syn" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "synom" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "syntax" version = "0.0.0" @@ -1003,27 +1687,113 @@ dependencies = [ "serialize 0.0.0", ] +[[package]] +name = "syntex_errors" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_pos 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syntex_errors" +version = "0.58.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_pos 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syntex_pos" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syntex_pos" +version = "0.58.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syntex_syntax" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_errors 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_pos 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syntex_syntax" +version = "0.58.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_errors 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_pos 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tar" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "xattr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tempdir" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "term" version = "0.0.0" +[[package]] +name = "term" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "term_size" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1037,11 +1807,28 @@ dependencies = [ [[package]] name = "thread-id" -version = "3.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thread-id" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thread_local" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1049,7 +1836,7 @@ name = "thread_local" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "thread-id 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1057,25 +1844,75 @@ dependencies = [ name = "tidy" version = "0.1.0" +[[package]] +name = "time" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "toml" version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "toml" -version = "0.3.1" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "toml" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "toml" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "typed-arena" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-bidi" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-segmentation" -version = "1.1.0" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-segmentation" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1083,6 +1920,16 @@ name = "unicode-width" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicode-xid" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-xid" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unreachable" version = "0.1.1" @@ -1091,6 +1938,38 @@ dependencies = [ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "url" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "idna 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "url_serde" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "user32-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "utf8-ranges" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "utf8-ranges" version = "1.0.0" @@ -1098,7 +1977,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "vec_map" -version = "0.7.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1126,12 +2005,21 @@ name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "xattr" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1148,69 +2036,158 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] +"checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a" +"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66" "checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699" "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" -"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159" "checksum backtrace 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f551bc2ddd53aea015d453ef0b635af89444afa5ed2405dd0b2062ad5d600d80" "checksum backtrace-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d192fd129132fbc97497c1f2ec2c2c5174e376b95f535199ef4fe0a293d33842" "checksum bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23" +"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4" +"checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32" +"checksum cargo 0.20.0 (git+https://github.com/rust-lang/cargo)" = "" "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c" -"checksum clap 2.22.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e17a4a72ffea176f77d6e2db609c6c919ef221f23862c9915e687fb54d833485" +"checksum chrono 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d9123be86fd2a8f627836c235ecdf331fdd067ecf7ac05aa1a68fbcf2429f056" +"checksum clap 2.19.3 (registry+https://github.com/rust-lang/crates.io-index)" = "95b78f3fe0fc94c13c731714363260e04b557a637166f33a4570d3189d642374" "checksum cmake 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "92278eb79412c8f75cfc89e707a1bb3a6490b68f7f2e78d15c774f30fe701122" +"checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97" +"checksum curl 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c90e1240ef340dd4027ade439e5c7c2064dd9dc652682117bd50d1486a3add7b" +"checksum curl-sys 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "23e7e544dc5e1ba42c4a4a678bd47985e84b9c3f4d3404c29700622a029db9c3" "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" +"checksum derive-new 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41be6ca3b99e0c0483fb2389685448f650459c3ecbe4e18d7705d8010ec4ab8e" "checksum diff 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0a515461b6c8c08419850ced27bc29e86166dcdcde8fbe76f8b1f0589bb49472" +"checksum docopt 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab32ea6e284d87987066f21a9e809a73c14720571ef34516f0890b3d355ccfd8" "checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90" +"checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a" +"checksum enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180" +"checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f" "checksum env_logger 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e3856f1697098606fc6cb97a93de88ca3f3bc35bb878c725920e6e82ecf05e83" "checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" "checksum filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "5363ab8e4139b8568a6237db5248646e5a8a2f89bd5ccb02092182b11fd3e922" "checksum flate2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)" = "36df0166e856739905cd3d7e0b210fe818592211a008862599845e012d8d304c" +"checksum foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e4056b9bd47f8ac5ba12be771f77a0dae796d1bbaaf5fd0b9c2d38b69b8a29d" +"checksum fs2 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34edaee07555859dc13ca387e6ae05686bb4d0364c95d649b6dab959511f4baf" "checksum gcc 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)" = "181e3cebba1d663bd92eb90e2da787e10597e027eb00de8d742b260a7850948f" +"checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518" "checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685" -"checksum handlebars 0.25.2 (registry+https://github.com/rust-lang/crates.io-index)" = "663e1728d8037fb0d4e13bcd1b1909fb5d913690a9929eb385922df157c2ff8f" +"checksum git2 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9de9df4358c17e448a778d90cd0272e1dab5eae30244502333fa2001c4e24357" +"checksum git2-curl 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "68676bc784bf0bef83278898929bf64a251e87c0340723d0b93fa096c9c5bf8e" +"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" +"checksum hamcrest 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bf088f042a467089e9baa4972f57f9247e42a0cc549ba264c7a04fbb8ecb89d4" +"checksum handlebars 0.25.3 (registry+https://github.com/rust-lang/crates.io-index)" = "15bdf598fc3c2de40c6b340213028301c0d225eea55a2294e6cc148074e557a1" +"checksum idna 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac85ec3f80c8e4e99d9325521337e14ec7555c458a14e377d189659a427f375" +"checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc" "checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum languageserver-types 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97c2985bfcbbcb0189cfa25e1c10c1ac7111df2b6214b652c690127aefdf4e5b" "checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf" -"checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135" +"checksum libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)" = "babb8281da88cba992fa1f4ddec7d63ed96280a1a53ec9b919fd37b53d71e502" +"checksum libgit2-sys 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "dd89dd7196d5fa35b659c3eaf3c1b14b9bd961bfd1a07dfca49adeb8a6aa3763" +"checksum libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0db4ec23611747ef772db1c4d650f8bd762f07b461727ec998f953c614024b75" +"checksum libz-sys 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e5ee912a45d686d393d5ac87fac15ba0ba18daae14e8e7543c63ebf7fb7e970c" "checksum log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5141eca02775a762cc6cd564d8d2c50f67c0ea3a372cbf1c51592b3e029e10ad" "checksum lzma-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "fedff6a5cbb24494ec6ee4784e9ac5c187161fede04c7767d49bf87544013afa" +"checksum matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efd7622e3022e1a6eaa602c4cea8912254e5582c9c692e9167714182244801b1" "checksum mdbook 0.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "f1e2e9d848514dcfad4195788d0d42ae5153a477c191d75d5b84fab10f222fbd" +"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" "checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4" "checksum miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "28eaee17666671fa872e567547e8428e83308ebe5808cdf6a0e28397dbe2c726" +"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +"checksum multimap 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9223f4774d08e06185e44e555b9a7561243d387bac49c78a6205c42d6975fbf2" +"checksum net2 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)" = "bc01404e7568680f1259aa5729539f221cb1e6d047a0d9053cab4be8a73b5d67" +"checksum num 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "98b15ba84e910ea7a1973bccd3df7b31ae282bf9d8bd2897779950c9b8303d40" +"checksum num-bigint 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "ba6d838b16e56da1b6c383d065ff1ec3c7d7797f65a3e8f6ba7092fd87820bac" +"checksum num-complex 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "148eb324ca772230853418731ffdf13531738b50f89b30692a01fcdcb0a64677" +"checksum num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "ef1a4bf6f9174aa5783a9b4cc892cacd11aebad6c69ad027a0b65c6ca5f8aa37" +"checksum num-iter 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d1891bd7b936f12349b7d1403761c8a0b85a18b148e9da4429d5d102c1a41e" +"checksum num-rational 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "c2dc5ea04020a8f18318ae485c751f8cfa1c0e69dcf465c29ddaaa64a313cc44" "checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99" "checksum num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca313f1862c7ec3e0dfe8ace9fa91b1d9cb5c84ace3d00f5ec4216238e93c167" "checksum open 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3478ed1686bd1300c8a981a940abc92b06fac9cbef747f4c668d4e032ff7b842" +"checksum openssl 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bb5d1663b73d10c6a3eda53e2e9d0346f822394e7b858d7257718f65f61dfbe2" +"checksum openssl-probe 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d98df0270d404ccd3c050a41d579c52d1db15375168bb3471e04ec0f5f378daf" +"checksum openssl-sys 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)" = "3a5886d87d3e2a0d890bf62dc8944f5e3769a405f7e1e9ef6e517e47fd7a0897" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6dda33d67c26f0aac90d324ab2eb7239c819fc7b2552fe9faa4fe88441edc8" +"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" +"checksum psapi-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "abcd5d1a07d360e29727f757a9decb3ce8bc6e0efa8969cfaad669a8317a2478" "checksum pulldown-cmark 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9ab1e588ef8efd702c7ed9d2bd774db5e6f4d878bb5a1a9f371828fbdff6973" "checksum pulldown-cmark 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1058d7bb927ca067656537eec4e02c2b4b70eaaa129664c5b90c111e20326f41" -"checksum quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0aad603e8d7fb67da22dbdf1f4b826ce8829e406124109e73cf1b2454b93a71c" +"checksum quick-error 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c36987d4978eb1be2e422b1e0423a557923a5c3e7e6f31d5699e9aafaefa469" +"checksum quote 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4c5cf478fe1006dbcc72567121d23dbdae5f1632386068c5c86ff4f645628504" +"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" +"checksum racer 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b0d72b3afd67882adfca61d609fafb8d7aa5f9e814f12c32fcc6e171995920e8" +"checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d" +"checksum redox_syscall 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "29dbdfd4b9df8ab31dec47c6087b7b13cbf4a776f335e4de8efba8288dda075b" +"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f" "checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01" +"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" "checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457" +"checksum rls-analysis 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a62d88c341375c6f3f8b2e18b9b364896e7d3e7aa916907de717d0267e116506" "checksum rls-data 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fc4277ce3c57f456b11fe3145b181a844a25201bab5cbaa1978457e6e2f27d47" "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a" +"checksum rls-vfs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "986eada111517bcb5a7a75205b3f2b70c82e7766653cca61a23f5afce79bdb94" "checksum rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3058a43ada2c2d0b92b3ae38007a2d0fa5e9db971be260e0171408a4ff471c95" -"checksum rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "684ce48436d6465300c9ea783b6b14c4361d6b8dcbb1375b486a69cc19e2dfb0" +"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" +"checksum rustfmt 0.8.4 (git+https://github.com/rust-lang-nursery/rustfmt)" = "" "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7" -"checksum serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "a702319c807c016e51f672e5c77d6f0b46afddd744b5e437d6b8436b888b458f" -"checksum serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "dbc45439552eb8fb86907a2c41c1fd0ef97458efb87ff7f878db466eb581824e" +"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" +"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +"checksum serde 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)" = "34b623917345a631dc9608d5194cc206b3fe6c3554cd1c75b937e55e285254af" +"checksum serde 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "38a3db3a5757f68069aba764b793823ea9fb9717c42c016f8903f8add50f508a" +"checksum serde_derive 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e46ef71ee001a4279a4513e79a6ebbb59da3a4987bf77a6df2e5534cd6f21d82" +"checksum serde_derive_internals 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "021c338d22c7e30f957a6ab7e388cb6098499dda9fd4ba1661ee074ca7a180d1" +"checksum serde_ignored 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c10e798e4405d7dcec3658989e35ee6706f730a9ed7c1184d5ebd84317e82f46" +"checksum serde_json 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ad8bcf487be7d2e15d3d543f04312de991d631cfe1b43ea0ade69e6a8a5b16a1" +"checksum serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "48b04779552e92037212c3615370f6bd57a40ebba7f20e554ff9f55e41a69a7b" +"checksum shell-escape 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5cc96481d54583947bfe88bf30c23d53f883c6cd0145368b69989d97b84ef8" "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" +"checksum strings 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "54f86446ab480b4f60782188f4f78886465c5793aee248cbb48b7fdc0d022420" +"checksum strsim 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "67f84c44fbb2f91db7fef94554e6b2ac05909c9c0b0bc23bb98d3a1aebfe7f7c" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" +"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" +"checksum syn 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6ae6fb0dcc9bd85f89a1a4adc0df2fd90c90c98849d61433983dd7a9df6363f7" +"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +"checksum syntex_errors 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9e52bffe6202cfb67587784cf23e0ec5bf26d331eef4922a16d5c42e12aa1e9b" +"checksum syntex_errors 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "867cc5c2d7140ae7eaad2ae9e8bf39cb18a67ca651b7834f88d46ca98faadb9c" +"checksum syntex_pos 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "955ef4b16af4c468e4680d1497f873ff288f557d338180649e18f915af5e15ac" +"checksum syntex_pos 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13ad4762fe52abc9f4008e85c4fb1b1fe3aa91ccb99ff4826a439c7c598e1047" +"checksum syntex_syntax 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "76a302e717e348aa372ff577791c3832395650073b8d8432f8b3cb170b34afde" +"checksum syntex_syntax 0.58.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6e0e4dbae163dd98989464c23dd503161b338790640e11537686f2ef0f25c791" "checksum tar 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ab0ef9ead2fe0aa9e18475a96a207bfd5143f4124779ef7429503a8665416ce8" +"checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6" +"checksum term 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d168af3930b369cfe245132550579d47dfd873d69470755a19c2c6568dbbd989" "checksum term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "07b6c1ac5b3fffd75073276bca1ceed01f67a28537097a2a9539e116e50fb21a" -"checksum thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4437c97558c70d129e40629a5b385b3fb1ffac301e63941335e4d354081ec14a" +"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03" +"checksum thread-id 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8df7875b676fddfadffd96deea3b1124e5ede707d4884248931077518cf1f773" +"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5" "checksum thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c85048c6260d17cf486ceae3282d9fb6b90be220bf5b28c400f5485ffc29f0c7" +"checksum time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "ffd7ccbf969a892bf83f1e441126968a07a3941c24ff522a26af9f9f4585d1a3" "checksum toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "0590d72182e50e879c4da3b11c6488dae18fccb1ae0c7a3eda18e16795844796" -"checksum toml 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3474f3c6eaf32eedb4f4a66a26214f020f828a6d96c37e38a35e3a379bbcfd11" -"checksum unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18127285758f0e2c6cf325bb3f3d138a12fee27de4f23e146cd6a179f26c2cf3" +"checksum toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "736b60249cb25337bc196faa43ee12c705e426f3d55c214d73a4e7be06f92cb4" +"checksum toml 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd86ad9ebee246fdedd610e0f6d0587b754a3d81438db930a244d0480ed7878f" +"checksum toml 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4cc5dbfb20a481e64b99eb7ae280859ec76730c7191570ba5edaa962394edb0a" +"checksum typed-arena 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e2f9dc90da4f9d66ffc9ad3ead2c7d57582a26f4a3292d2ce7011bd29965100" +"checksum unicode-bidi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3a078ebdd62c0e71a709c3d53d2af693fe09fe93fbff8344aebe289b78f9032" +"checksum unicode-normalization 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e28fa37426fceeb5cf8f41ee273faa7c82c47dc8fba5853402841e665fcd86ff" +"checksum unicode-segmentation 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c3bc443ded17b11305ffffe6b37e2076f328a5a8cb6aa877b1b98f77699e98b5" +"checksum unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8083c594e02b8ae1654ae26f0ade5158b119bd88ad0e8227a5d8fcd72407946" "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" +"checksum unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "36dff09cafb4ec7c8cf0023eb0b686cb6ce65499116a12201c9e11840ca01beb" +"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91" +"checksum url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5ba8a749fb4479b043733416c244fa9d1d3af3d7c23804944651c8a448cb87e" +"checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea" +"checksum user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ef4711d107b21b410a3a974b1204d9accc8b10dad75d8324b5d755de1617d47" +"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" -"checksum vec_map 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8cdc8b93bd0198ed872357fb2e667f7125646b1762f16d60b2c96350d361897" +"checksum vec_map 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cac5efe5cb0fa14ec2f84f83c701c562ee63f6dcc680861b21d65c682adfb05f" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum xattr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "5f04de8a1346489a2f9e9bd8526b73d135ec554227b17568456e86aa35b6f3fc" "checksum xz2 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e9510bdf100731599107c61f77daf46713a69a568f75458999c1f9dbf6ba25b0" "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" diff --git a/src/Cargo.toml b/src/Cargo.toml index 99e8b9f256a..85a6df3573a 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -14,10 +14,6 @@ members = [ "tools/remote-test-client", "tools/remote-test-server", "tools/rust-installer", -] - -# These projects have their own Cargo.lock -exclude = [ "tools/cargo", "tools/rls", ] @@ -38,3 +34,6 @@ debug-assertions = false [profile.test] debug = false debug-assertions = false + +[replace] +"https://github.com/rust-lang/cargo#0.20.0" = { path = "tools/cargo" } diff --git a/src/tools/rust-installer b/src/tools/rust-installer index 6a2c5d12910..daa2a05ebe7 160000 --- a/src/tools/rust-installer +++ b/src/tools/rust-installer @@ -1 +1 @@ -Subproject commit 6a2c5d129101762d204185b888d62a244011c422 +Subproject commit daa2a05ebe7b8d07a309e8891ebc548652362954 From e119a6390166c97f16e06c26232fdc9b97d5d633 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Fri, 12 May 2017 19:24:04 +0900 Subject: [PATCH 078/103] Add metadata suffix, close rust-lang/cargo#4028 --- src/bootstrap/bin/rustc.rs | 19 ++++++++++++++++++- src/bootstrap/lib.rs | 28 +++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 906c468241a..eb2cef133a3 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -38,7 +38,24 @@ use std::path::PathBuf; use std::process::{Command, ExitStatus}; fn main() { - let args = env::args_os().skip(1).collect::>(); + let mut args = env::args_os().skip(1).collect::>(); + + // Append metadata suffix for internal crates. See the corresponding entry + // in bootstrap/lib.rs for details. + if let Ok(s) = env::var("RUSTC_METADATA_SUFFIX") { + for i in 1..args.len() { + // Dirty code for borrowing issues + let mut new = None; + if let Some(current_as_str) = args[i].to_str() { + if (&*args[i - 1] == "-C" && current_as_str.starts_with("metadata")) || + current_as_str.starts_with("-Cmetadata") { + new = Some(format!("{}-{}", current_as_str, s)); + } + } + if let Some(new) = new { args[i] = new.into(); } + } + } + // Detect whether or not we're a build script depending on whether --target // is passed (a bit janky...) let target = args.windows(2) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index ea0b521a2ce..4b36fcef91b 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -475,12 +475,30 @@ impl Build { .env("RUSTDOC_REAL", self.rustdoc(compiler)) .env("RUSTC_FLAGS", self.rustc_flags(target).join(" ")); - // Tools don't get debuginfo right now, e.g. cargo and rls don't get - // compiled with debuginfo. if mode != Mode::Tool { - cargo.env("RUSTC_DEBUGINFO", self.config.rust_debuginfo.to_string()) - .env("RUSTC_DEBUGINFO_LINES", self.config.rust_debuginfo_lines.to_string()) - .env("RUSTC_FORCE_UNSTABLE", "1"); + // Tools don't get debuginfo right now, e.g. cargo and rls don't + // get compiled with debuginfo. + cargo.env("RUSTC_DEBUGINFO", self.config.rust_debuginfo.to_string()) + .env("RUSTC_DEBUGINFO_LINES", self.config.rust_debuginfo_lines.to_string()) + .env("RUSTC_FORCE_UNSTABLE", "1"); + + // Currently the compiler depends on crates from crates.io, and + // then other crates can depend on the compiler (e.g. proc-macro + // crates). Let's say, for example that rustc itself depends on the + // bitflags crate. If an external crate then depends on the + // bitflags crate as well, we need to make sure they don't + // conflict, even if they pick the same verison of bitflags. We'll + // want to make sure that e.g. a plugin and rustc each get their + // own copy of bitflags. + + // Cargo ensures that this works in general through the -C metadata + // flag. This flag will frob the symbols in the binary to make sure + // they're different, even though the source code is the exact + // same. To solve this problem for the compiler we extend Cargo's + // already-passed -C metadata flag with our own. Our rustc.rs + // wrapper around the actual rustc will detect -C metadata being + // passed and frob it with this extra string we're passing in. + cargo.env("RUSTC_METADATA_SUFFIX", "rustc"); } // Enable usage of unstable features From 510d6b8afbb6fe956c442a8cfcb838b9aea280da Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Sat, 13 May 2017 14:21:35 +0900 Subject: [PATCH 079/103] Move submodule initialization to bootstrap.py --- src/bootstrap/bootstrap.py | 39 +++++++++++- src/bootstrap/lib.rs | 119 +------------------------------------ 2 files changed, 37 insertions(+), 121 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index ad3cf31c1b9..d7a15864ef7 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -14,6 +14,7 @@ import contextlib import datetime import hashlib import os +import re import shutil import subprocess import sys @@ -297,8 +298,10 @@ class RustBuild(object): def get_toml(self, key): for line in self.config_toml.splitlines(): - if line.startswith(key + ' ='): - return self.get_string(line) + match = re.match(r'^{}\s*=(.*)$'.format(key), line) + if match is not None: + value = match.group(1) + return self.get_string(value) or value.strip() return None def get_mk(self, key): @@ -329,6 +332,8 @@ class RustBuild(object): def get_string(self, line): start = line.find('"') + if start == -1: + return None end = start + 1 + line[start + 1:].find('"') return line[start + 1:end] @@ -386,7 +391,7 @@ class RustBuild(object): args.append("--frozen") self.run(args, env) - def run(self, args, env): + def run(self, args, env=None): proc = subprocess.Popen(args, env=env) ret = proc.wait() if ret != 0: @@ -529,6 +534,32 @@ class RustBuild(object): return "{}-{}".format(cputype, ostype) + def update_submodules(self): + if (not os.path.exists(os.path.join(self.rust_root, ".git"))) or \ + self.get_toml('submodules') == "false" or \ + self.get_mk('CFG_DISABLE_MANAGE_SUBMODULES') == "1": + return + + print('Updating submodules') + self.run(["git", "-C", self.rust_root, "submodule", "-q", "sync"]) + # FIXME: nobody does, but this won't work well with whitespace in + # submodule path + submodules = [s.split()[1] for s in subprocess.check_output( + ["git", "config", "--file", os.path.join( + self.rust_root, ".gitmodules"), "--get-regexp", "path"]).splitlines()] + for module in submodules: + if module.endswith(b"llvm") and \ + (self.get_toml('llvm-config') or self.get_mk('CFG_LLVM_ROOT')): + continue + if module.endswith(b"jemalloc") and \ + (self.get_toml('jemalloc') or self.get_mk('CFG_JEMALLOC_ROOT')): + continue + self.run(["git", "-C", self.rust_root, + "submodule", "update", "--init", module]) + self.run(["git", "-C", self.rust_root, "submodule", "-q", + "foreach", "git", "reset", "-q", "--hard"]) + self.run(["git", "-C", self.rust_root, "submodule", + "-q", "foreach", "git", "clean", "-qdfx"]) def bootstrap(): parser = argparse.ArgumentParser(description='Build rust') parser.add_argument('--config') @@ -597,6 +628,8 @@ def bootstrap(): else: rb._download_url = 'https://static.rust-lang.org' + rb.update_submodules() + # Fetch/build the bootstrap rb.build = rb.build_triple() rb.download_stage0() diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 4b36fcef91b..ca9de43f542 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -82,7 +82,7 @@ use std::env; use std::ffi::OsString; use std::fs::{self, File}; use std::io::Read; -use std::path::{Component, PathBuf, Path}; +use std::path::{PathBuf, Path}; use std::process::Command; use build_helper::{run_silent, run_suppressed, output, mtime}; @@ -285,129 +285,12 @@ impl Build { self.verbose(&format!("auto-detected local-rebuild {}", local_release)); self.local_rebuild = true; } - self.verbose("updating submodules"); - self.update_submodules(); self.verbose("learning about cargo"); metadata::build(self); step::run(self); } - /// Updates all git submodules that we have. - /// - /// This will detect if any submodules are out of date an run the necessary - /// commands to sync them all with upstream. - fn update_submodules(&self) { - struct Submodule<'a> { - path: &'a Path, - state: State, - } - - enum State { - // The submodule may have staged/unstaged changes - MaybeDirty, - // Or could be initialized but never updated - NotInitialized, - // The submodule, itself, has extra commits but those changes haven't been commited to - // the (outer) git repository - OutOfSync, - } - - if !self.src_is_git || !self.config.submodules { - return - } - let git = || { - let mut cmd = Command::new("git"); - cmd.current_dir(&self.src); - return cmd - }; - let git_submodule = || { - let mut cmd = Command::new("git"); - cmd.current_dir(&self.src).arg("submodule"); - return cmd - }; - - // FIXME: this takes a seriously long time to execute on Windows and a - // nontrivial amount of time on Unix, we should have a better way - // of detecting whether we need to run all the submodule commands - // below. - let out = output(git_submodule().arg("status")); - let mut submodules = vec![]; - for line in out.lines() { - // NOTE `git submodule status` output looks like this: - // - // -5066b7dcab7e700844b0e2ba71b8af9dc627a59b src/liblibc - // +b37ef24aa82d2be3a3cc0fe89bf82292f4ca181c src/compiler-rt (remotes/origin/..) - // e058ca661692a8d01f8cf9d35939dfe3105ce968 src/jemalloc (3.6.0-533-ge058ca6) - // - // The first character can be '-', '+' or ' ' and denotes the `State` of the submodule - // Right next to this character is the SHA-1 of the submodule HEAD - // And after that comes the path to the submodule - let path = Path::new(line[1..].split(' ').skip(1).next().unwrap()); - let state = if line.starts_with('-') { - State::NotInitialized - } else if line.starts_with('+') { - State::OutOfSync - } else if line.starts_with(' ') { - State::MaybeDirty - } else { - panic!("unexpected git submodule state: {:?}", line.chars().next()); - }; - - submodules.push(Submodule { path: path, state: state }) - } - - self.run(git_submodule().arg("sync")); - - for submodule in submodules { - // If using llvm-root then don't touch the llvm submodule. - if submodule.path.components().any(|c| c == Component::Normal("llvm".as_ref())) && - self.config.target_config.get(&self.config.build) - .and_then(|c| c.llvm_config.as_ref()).is_some() - { - continue - } - - if submodule.path.components().any(|c| c == Component::Normal("jemalloc".as_ref())) && - !self.config.use_jemalloc - { - continue - } - - // `submodule.path` is the relative path to a submodule (from the repository root) - // `submodule_path` is the path to a submodule from the cwd - - // use `submodule.path` when e.g. executing a submodule specific command from the - // repository root - // use `submodule_path` when e.g. executing a normal git command for the submodule - // (set via `current_dir`) - let submodule_path = self.src.join(submodule.path); - - match submodule.state { - State::MaybeDirty => { - // drop staged changes - self.run(git().current_dir(&submodule_path) - .args(&["reset", "--hard"])); - // drops unstaged changes - self.run(git().current_dir(&submodule_path) - .args(&["clean", "-fdx"])); - }, - State::NotInitialized => { - self.run(git_submodule().arg("init").arg(submodule.path)); - self.run(git_submodule().arg("update").arg(submodule.path)); - }, - State::OutOfSync => { - // drops submodule commits that weren't reported to the (outer) git repository - self.run(git_submodule().arg("update").arg(submodule.path)); - self.run(git().current_dir(&submodule_path) - .args(&["reset", "--hard"])); - self.run(git().current_dir(&submodule_path) - .args(&["clean", "-fdx"])); - }, - } - } - } - /// Clear out `dir` if `input` is newer. /// /// After this executes, it will also ensure that `dir` exists. From 182a4ff037ef7605d7e0bd0ac900dd4846d5a31a Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Thu, 18 May 2017 00:30:15 +0900 Subject: [PATCH 080/103] Whitelist strings crate for license As we can't wait for the maintainer. --- src/tools/tidy/src/deps.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 8b7da2267cd..c8d371a3d37 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -32,6 +32,7 @@ static EXCEPTIONS: &'static [&'static str] = &[ "openssl", // BSD+advertising clause, cargo, mdbook "pest", // MPL2, mdbook via handlebars "thread-id", // Apache-2.0, mdbook + "strings", // not in published manifest ]; pub fn check(path: &Path, bad: &mut bool) { From db69d894e73aa5ae2315f7e2490104a3e5503afb Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 17 May 2017 09:15:44 -0700 Subject: [PATCH 081/103] Reset submodule management to what master does Basically just translate what's done on master in Rust to Python here. --- src/bootstrap/bootstrap.py | 69 +++++++++++++++++++++++++++----------- src/tools/tidy/src/deps.rs | 2 +- 2 files changed, 51 insertions(+), 20 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index d7a15864ef7..e15304a7e6e 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -127,13 +127,13 @@ def unpack(tarball, dst, verbose=False, match=None): shutil.move(tp, fp) shutil.rmtree(os.path.join(dst, fname)) -def run(args, verbose=False, exception=False): +def run(args, verbose=False, exception=False, cwd=None): if verbose: print("running: " + ' '.join(args)) sys.stdout.flush() # Use Popen here instead of call() as it apparently allows powershell on # Windows to not lock up waiting for input presumably. - ret = subprocess.Popen(args) + ret = subprocess.Popen(args, cwd=cwd) code = ret.wait() if code != 0: err = "failed to run: " + ' '.join(args) @@ -391,12 +391,21 @@ class RustBuild(object): args.append("--frozen") self.run(args, env) - def run(self, args, env=None): - proc = subprocess.Popen(args, env=env) + def run(self, args, env=None, cwd=None): + proc = subprocess.Popen(args, env=env, cwd=cwd) ret = proc.wait() if ret != 0: sys.exit(ret) + def output(self, args, env=None, cwd=None): + proc = subprocess.Popen(args, stdout=subprocess.PIPE, env=env, cwd=cwd) + (out, err) = proc.communicate() + ret = proc.wait() + if ret != 0: + print(out) + sys.exit(ret) + return out + def build_triple(self): default_encoding = sys.getdefaultencoding() config = self.get_toml('build') @@ -541,25 +550,47 @@ class RustBuild(object): return print('Updating submodules') - self.run(["git", "-C", self.rust_root, "submodule", "-q", "sync"]) - # FIXME: nobody does, but this won't work well with whitespace in - # submodule path - submodules = [s.split()[1] for s in subprocess.check_output( - ["git", "config", "--file", os.path.join( - self.rust_root, ".gitmodules"), "--get-regexp", "path"]).splitlines()] - for module in submodules: - if module.endswith(b"llvm") and \ + output = self.output(["git", "submodule", "status"], cwd=self.rust_root) + submodules = [] + for line in output.splitlines(): + # NOTE `git submodule status` output looks like this: + # + # -5066b7dcab7e700844b0e2ba71b8af9dc627a59b src/liblibc + # +b37ef24aa82d2be3a3cc0fe89bf82292f4ca181c src/compiler-rt (remotes/origin/..) + # e058ca661692a8d01f8cf9d35939dfe3105ce968 src/jemalloc (3.6.0-533-ge058ca6) + # + # The first character can be '-', '+' or ' ' and denotes the + # `State` of the submodule Right next to this character is the + # SHA-1 of the submodule HEAD And after that comes the path to the + # submodule + path = line[1:].split(' ')[1] + submodules.append([path, line[0]]) + + self.run(["git", "submodule", "sync"], cwd=self.rust_root) + + for submod in submodules: + path, status = submod + if path.endswith(b"llvm") and \ (self.get_toml('llvm-config') or self.get_mk('CFG_LLVM_ROOT')): continue - if module.endswith(b"jemalloc") and \ + if path.endswith(b"jemalloc") and \ (self.get_toml('jemalloc') or self.get_mk('CFG_JEMALLOC_ROOT')): continue - self.run(["git", "-C", self.rust_root, - "submodule", "update", "--init", module]) - self.run(["git", "-C", self.rust_root, "submodule", "-q", - "foreach", "git", "reset", "-q", "--hard"]) - self.run(["git", "-C", self.rust_root, "submodule", - "-q", "foreach", "git", "clean", "-qdfx"]) + submod_path = os.path.join(self.rust_root, path) + + if status == ' ': + self.run(["git", "reset", "--hard"], cwd=submod_path) + self.run(["git", "clean", "-fdx"], cwd=submod_path) + elif status == '+': + self.run(["git", "submodule", "update", path], cwd=self.rust_root) + self.run(["git", "reset", "--hard"], cwd=submod_path) + self.run(["git", "clean", "-fdx"], cwd=submod_path) + elif status == '-': + self.run(["git", "submodule", "init", path], cwd=self.rust_root) + self.run(["git", "submodule", "update", path], cwd=self.rust_root) + else: + raise ValueError('unknown submodule status: ' + status) + def bootstrap(): parser = argparse.ArgumentParser(description='Build rust') parser.add_argument('--config') diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index c8d371a3d37..ba02ee0c6d7 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -32,7 +32,7 @@ static EXCEPTIONS: &'static [&'static str] = &[ "openssl", // BSD+advertising clause, cargo, mdbook "pest", // MPL2, mdbook via handlebars "thread-id", // Apache-2.0, mdbook - "strings", // not in published manifest + "strings", // this is actually MIT/Apache-2.0 but it's not in the manifest yet ]; pub fn check(path: &Path, bad: &mut bool) { From 307d8e5aa5f0c66881b1028fe1dc7f17e5ea317a Mon Sep 17 00:00:00 2001 From: Marco A L Barbosa Date: Fri, 12 May 2017 15:18:34 -0300 Subject: [PATCH 082/103] ci: allows shared scripts --- src/ci/docker/android-ndk.sh | 7 +- .../install-sdk.sh => android-sdk.sh} | 6 +- ...-emulator.sh => android-start-emulator.sh} | 0 src/ci/docker/arm-android/Dockerfile | 72 +++++++++---------- src/ci/docker/arm-android/install-ndk.sh | 35 --------- src/ci/docker/armhf-gnu/Dockerfile | 6 +- src/ci/docker/cross/Dockerfile | 4 +- .../disabled/dist-aarch64-android/Dockerfile | 49 ++++++------- .../disabled/dist-armv7-android/Dockerfile | 51 ++++++------- .../disabled/dist-i686-android/Dockerfile | 51 ++++++------- .../disabled/dist-x86_64-android/Dockerfile | 49 ++++++------- src/ci/docker/dist-aarch64-linux/Dockerfile | 2 +- src/ci/docker/dist-android/Dockerfile | 46 ++++++------ src/ci/docker/dist-android/install-ndk.sh | 35 --------- src/ci/docker/dist-arm-linux/Dockerfile | 2 +- src/ci/docker/dist-armhf-linux/Dockerfile | 2 +- src/ci/docker/dist-armv7-linux/Dockerfile | 2 +- src/ci/docker/dist-fuchsia/Dockerfile | 2 +- .../docker/dist-i586-gnu-i686-musl/Dockerfile | 2 +- src/ci/docker/dist-i686-freebsd/Dockerfile | 2 +- src/ci/docker/dist-i686-linux/Dockerfile | 16 ++--- src/ci/docker/dist-powerpc64-linux/Dockerfile | 4 +- .../docker/dist-powerpc64le-linux/Dockerfile | 2 +- src/ci/docker/dist-s390x-linux/Dockerfile | 4 +- src/ci/docker/dist-x86_64-freebsd/Dockerfile | 2 +- src/ci/docker/dist-x86_64-linux/Dockerfile | 16 ++--- src/ci/docker/dist-x86_64-musl/Dockerfile | 2 +- src/ci/docker/dist-x86_64-netbsd/Dockerfile | 2 +- src/ci/docker/dumb-init.sh | 15 ++++ src/ci/docker/emscripten/Dockerfile | 2 +- src/ci/docker/run.sh | 3 +- src/ci/docker/sccache.sh | 16 +++++ 32 files changed, 243 insertions(+), 266 deletions(-) rename src/ci/docker/{arm-android/install-sdk.sh => android-sdk.sh} (92%) rename src/ci/docker/{arm-android/start-emulator.sh => android-start-emulator.sh} (100%) delete mode 100644 src/ci/docker/arm-android/install-ndk.sh delete mode 100644 src/ci/docker/dist-android/install-ndk.sh create mode 100644 src/ci/docker/dumb-init.sh create mode 100644 src/ci/docker/sccache.sh diff --git a/src/ci/docker/android-ndk.sh b/src/ci/docker/android-ndk.sh index 4849f843007..c3d83c087e5 100644 --- a/src/ci/docker/android-ndk.sh +++ b/src/ci/docker/android-ndk.sh @@ -1,4 +1,3 @@ -#!/bin/sh # 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. @@ -33,3 +32,9 @@ make_standalone_toolchain() { remove_ndk() { rm -rf /android/ndk/ndk } + +download_and_make_toolchain() { + download_ndk $1 && \ + make_standalone_toolchain $2 $3 && \ + remove_ndk +} diff --git a/src/ci/docker/arm-android/install-sdk.sh b/src/ci/docker/android-sdk.sh similarity index 92% rename from src/ci/docker/arm-android/install-sdk.sh rename to src/ci/docker/android-sdk.sh index 258fc47a7a6..7d8110efede 100644 --- a/src/ci/docker/arm-android/install-sdk.sh +++ b/src/ci/docker/android-sdk.sh @@ -1,4 +1,3 @@ -#!/bin/sh # 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. @@ -47,3 +46,8 @@ create_avd() { --abi $abi } +download_and_create_avd() { + download_sdk $1 + download_sysimage $2 $3 + create_avd $2 $3 +} diff --git a/src/ci/docker/arm-android/start-emulator.sh b/src/ci/docker/android-start-emulator.sh similarity index 100% rename from src/ci/docker/arm-android/start-emulator.sh rename to src/ci/docker/android-start-emulator.sh diff --git a/src/ci/docker/arm-android/Dockerfile b/src/ci/docker/arm-android/Dockerfile index 93f15baf55e..6fd3ed7c6a9 100644 --- a/src/ci/docker/arm-android/Dockerfile +++ b/src/ci/docker/arm-android/Dockerfile @@ -2,52 +2,44 @@ FROM ubuntu:16.04 RUN apt-get update && \ apt-get install -y --no-install-recommends \ - g++ \ - make \ - file \ - curl \ ca-certificates \ - python2.7 \ - git \ cmake \ - unzip \ - sudo \ - xz-utils \ + curl \ + file \ + g++ \ + git \ libssl-dev \ - pkg-config + make \ + pkg-config \ + python2.7 \ + sudo \ + unzip \ + xz-utils -RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ - dpkg -i dumb-init_*.deb && \ - rm dumb-init_*.deb +# dumb-init +COPY dumb-init.sh /scripts/ +RUN sh /scripts/dumb-init.sh -RUN curl -o /usr/local/bin/sccache \ - https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \ - chmod +x /usr/local/bin/sccache +# ndk +COPY android-ndk.sh /scripts/ +RUN . /scripts/android-ndk.sh && \ + download_and_make_toolchain android-ndk-r13b-linux-x86_64.zip arm 9 -# Install NDK -COPY install-ndk.sh /tmp -RUN . /tmp/install-ndk.sh && \ - download_ndk android-ndk-r13b-linux-x86_64.zip && \ - make_standalone_toolchain arm 9 && \ - remove_ndk - -# Install SDK +# sdk RUN dpkg --add-architecture i386 && \ apt-get update && \ apt-get install -y --no-install-recommends \ - openjdk-9-jre-headless \ - tzdata \ - libstdc++6:i386 \ libgl1-mesa-glx \ - libpulse0 + libpulse0 \ + libstdc++6:i386 \ + openjdk-9-jre-headless \ + tzdata -COPY install-sdk.sh /tmp -RUN . /tmp/install-sdk.sh && \ - download_sdk tools_r25.2.5-linux.zip && \ - download_sysimage armeabi-v7a 18 && \ - create_avd armeabi-v7a 18 +COPY android-sdk.sh /scripts/ +RUN . /scripts/android-sdk.sh && \ + download_and_create_avd tools_r25.2.5-linux.zip armeabi-v7a 18 -# Setup env +# env ENV PATH=$PATH:/android/sdk/tools ENV PATH=$PATH:/android/sdk/platform-tools @@ -57,8 +49,12 @@ ENV RUST_CONFIGURE_ARGS \ --target=$TARGETS \ --arm-linux-androideabi-ndk=/android/ndk/arm-9 -ENV SCRIPT python2.7 ../x.py test --target $TARGETS --verbose +ENV SCRIPT python2.7 ../x.py test --target $TARGETS -# Entrypoint -COPY start-emulator.sh /android/ -ENTRYPOINT ["/usr/bin/dumb-init", "--", "/android/start-emulator.sh"] +# sccache +COPY sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +# init +COPY android-start-emulator.sh /scripts/ +ENTRYPOINT ["/usr/bin/dumb-init", "--", "/scripts/android-start-emulator.sh"] diff --git a/src/ci/docker/arm-android/install-ndk.sh b/src/ci/docker/arm-android/install-ndk.sh deleted file mode 100644 index 80818721199..00000000000 --- a/src/ci/docker/arm-android/install-ndk.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh -# Copyright 2016 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. - -set -ex - -URL=https://dl.google.com/android/repository - -download_ndk() { - mkdir -p /android/ndk - cd /android/ndk - curl -O $URL/$1 - unzip -q $1 - rm $1 - mv android-ndk-* ndk -} - -make_standalone_toolchain() { - # See https://developer.android.com/ndk/guides/standalone_toolchain.html - python2.7 /android/ndk/ndk/build/tools/make_standalone_toolchain.py \ - --install-dir /android/ndk/$1-$2 \ - --arch $1 \ - --api $2 -} - -remove_ndk() { - rm -rf /android/ndk/ndk -} diff --git a/src/ci/docker/armhf-gnu/Dockerfile b/src/ci/docker/armhf-gnu/Dockerfile index 801de69a63d..03e0b78ba89 100644 --- a/src/ci/docker/armhf-gnu/Dockerfile +++ b/src/ci/docker/armhf-gnu/Dockerfile @@ -31,7 +31,7 @@ WORKDIR /build # The `vexpress_config` config file was a previously generated config file for # the kernel. This file was generated by running `make vexpress_defconfig` # followed by `make menuconfig` and then enabling the IPv6 protocol page. -COPY vexpress_config /build/.config +COPY armhf-gnu/vexpress_config /build/.config RUN curl https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.4.42.tar.xz | \ tar xJf - && \ cd /build/linux-4.4.42 && \ @@ -63,11 +63,11 @@ RUN curl http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/ubuntu-bas # Copy over our init script, which starts up our test server and also a few # other misc tasks. -COPY rcS rootfs/etc/init.d/rcS +COPY armhf-gnu/rcS rootfs/etc/init.d/rcS RUN chmod +x rootfs/etc/init.d/rcS # Helper to quickly fill the entropy pool in the kernel. -COPY addentropy.c /tmp/ +COPY armhf-gnu/addentropy.c /tmp/ RUN arm-linux-gnueabihf-gcc addentropy.c -o rootfs/addentropy -static # TODO: What is this?! diff --git a/src/ci/docker/cross/Dockerfile b/src/ci/docker/cross/Dockerfile index 30a699c3ba2..7759d91e1bb 100644 --- a/src/ci/docker/cross/Dockerfile +++ b/src/ci/docker/cross/Dockerfile @@ -32,10 +32,10 @@ ENTRYPOINT ["/usr/bin/dumb-init", "--"] WORKDIR /tmp -COPY build-rumprun.sh /tmp/ +COPY cross/build-rumprun.sh /tmp/ RUN ./build-rumprun.sh -COPY build-arm-musl.sh /tmp/ +COPY cross/build-arm-musl.sh /tmp/ RUN ./build-arm-musl.sh # originally from diff --git a/src/ci/docker/disabled/dist-aarch64-android/Dockerfile b/src/ci/docker/disabled/dist-aarch64-android/Dockerfile index e15876edbd8..5a966518759 100644 --- a/src/ci/docker/disabled/dist-aarch64-android/Dockerfile +++ b/src/ci/docker/disabled/dist-aarch64-android/Dockerfile @@ -2,36 +2,30 @@ FROM ubuntu:16.04 RUN apt-get update && \ apt-get install -y --no-install-recommends \ - g++ \ - make \ - file \ - curl \ ca-certificates \ - python2.7 \ - git \ cmake \ - unzip \ - sudo \ - xz-utils \ + curl \ + file \ + g++ \ + git \ libssl-dev \ - pkg-config + make \ + pkg-config \ + python2.7 \ + sudo \ + unzip \ + xz-utils -RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ - dpkg -i dumb-init_*.deb && \ - rm dumb-init_*.deb +# dumb-init +COPY dumb-init.sh /scripts/ +RUN sh /scripts/dumb-init.sh -RUN curl -o /usr/local/bin/sccache \ - https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \ - chmod +x /usr/local/bin/sccache - -ENTRYPOINT ["/usr/bin/dumb-init", "--"] - -COPY android-ndk.sh / -RUN . /android-ndk.sh && \ - download_ndk android-ndk-r13b-linux-x86_64.zip && \ - make_standalone_toolchain arm64 21 && \ - remove_ndk +# ndk +COPY android-ndk.sh /scripts/ +RUN . /scripts/android-ndk.sh && \ + download_and_make_toolchain android-ndk-r13b-linux-x86_64.zip arm64 21 +# env ENV PATH=$PATH:/android/ndk/arm64-21/bin ENV DEP_Z_ROOT=/android/ndk/arm64-21/sysroot/usr/ @@ -47,3 +41,10 @@ ENV RUST_CONFIGURE_ARGS \ --enable-cargo-openssl-static ENV SCRIPT python2.7 ../x.py dist --target $HOSTS --host $HOSTS + +# sccache +COPY sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +# init +ENTRYPOINT ["/usr/bin/dumb-init", "--"] diff --git a/src/ci/docker/disabled/dist-armv7-android/Dockerfile b/src/ci/docker/disabled/dist-armv7-android/Dockerfile index 0d81e404b5c..f92a28a7946 100644 --- a/src/ci/docker/disabled/dist-armv7-android/Dockerfile +++ b/src/ci/docker/disabled/dist-armv7-android/Dockerfile @@ -2,37 +2,36 @@ FROM ubuntu:16.04 RUN apt-get update && \ apt-get install -y --no-install-recommends \ - g++ \ - make \ - file \ - curl \ ca-certificates \ - python2.7 \ - git \ cmake \ - unzip \ - sudo \ - xz-utils \ + curl \ + file \ + g++ \ + git \ libssl-dev \ - pkg-config + make \ + pkg-config \ + python2.7 \ + sudo \ + unzip \ + xz-utils -RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ - dpkg -i dumb-init_*.deb && \ - rm dumb-init_*.deb +# dumb-init +COPY dumb-init.sh /scripts/ +RUN sh /scripts/dumb-init.sh -RUN curl -o /usr/local/bin/sccache \ - https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \ - chmod +x /usr/local/bin/sccache - -ENTRYPOINT ["/usr/bin/dumb-init", "--"] - -COPY android-ndk.sh / -RUN . /android-ndk.sh && \ +# ndk +COPY android-ndk.sh /scripts/ +RUN . /scripts/android-ndk.sh && \ download_ndk android-ndk-r13b-linux-x86_64.zip && \ make_standalone_toolchain arm 9 && \ make_standalone_toolchain arm 21 && \ remove_ndk +RUN chmod 777 /android/ndk && \ + ln -s /android/ndk/arm-21 /android/ndk/arm + +# env ENV PATH=$PATH:/android/ndk/arm-9/bin ENV DEP_Z_ROOT=/android/ndk/arm-9/sysroot/usr/ @@ -54,12 +53,16 @@ ENV RUST_CONFIGURE_ARGS \ # level 9), the default linker behavior is to generate an error, to allow the # build to finish we use --warn-unresolved-symbols. Note that the missing # symbols does not affect std, only the compiler (llvm) and cargo (openssl). -RUN chmod 777 /android/ndk && \ - ln -s /android/ndk/arm-21 /android/ndk/arm - ENV SCRIPT \ python2.7 ../x.py build src/llvm --host $HOSTS --target $HOSTS && \ (export RUSTFLAGS="\"-C link-arg=-Wl,--warn-unresolved-symbols\""; \ rm /android/ndk/arm && \ ln -s /android/ndk/arm-9 /android/ndk/arm && \ python2.7 ../x.py dist --host $HOSTS --target $HOSTS) + +# sccache +COPY sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +# init +ENTRYPOINT ["/usr/bin/dumb-init", "--"] diff --git a/src/ci/docker/disabled/dist-i686-android/Dockerfile b/src/ci/docker/disabled/dist-i686-android/Dockerfile index 37930639b8a..c475c19ebde 100644 --- a/src/ci/docker/disabled/dist-i686-android/Dockerfile +++ b/src/ci/docker/disabled/dist-i686-android/Dockerfile @@ -2,37 +2,36 @@ FROM ubuntu:16.04 RUN apt-get update && \ apt-get install -y --no-install-recommends \ - g++ \ - make \ - file \ - curl \ ca-certificates \ - python2.7 \ - git \ cmake \ - unzip \ - sudo \ - xz-utils \ + curl \ + file \ + g++ \ + git \ libssl-dev \ - pkg-config + make \ + pkg-config \ + python2.7 \ + sudo \ + unzip \ + xz-utils -RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ - dpkg -i dumb-init_*.deb && \ - rm dumb-init_*.deb +# dumb-init +COPY dumb-init.sh /scripts/ +RUN sh /scripts/dumb-init.sh -RUN curl -o /usr/local/bin/sccache \ - https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \ - chmod +x /usr/local/bin/sccache - -ENTRYPOINT ["/usr/bin/dumb-init", "--"] - -COPY android-ndk.sh / -RUN . /android-ndk.sh && \ +# ndk +COPY android-ndk.sh /scripts/ +RUN . /scripts/android-ndk.sh && \ download_ndk android-ndk-r13b-linux-x86_64.zip && \ make_standalone_toolchain x86 9 && \ make_standalone_toolchain x86 21 && \ remove_ndk +RUN chmod 777 /android/ndk && \ + ln -s /android/ndk/x86-21 /android/ndk/x86 + +# env ENV PATH=$PATH:/android/ndk/x86-9/bin ENV DEP_Z_ROOT=/android/ndk/x86-9/sysroot/usr/ @@ -54,12 +53,16 @@ ENV RUST_CONFIGURE_ARGS \ # level 9), the default linker behavior is to generate an error, to allow the # build to finish we use --warn-unresolved-symbols. Note that the missing # symbols does not affect std, only the compiler (llvm) and cargo (openssl). -RUN chmod 777 /android/ndk && \ - ln -s /android/ndk/x86-21 /android/ndk/x86 - ENV SCRIPT \ python2.7 ../x.py build src/llvm --host $HOSTS --target $HOSTS && \ (export RUSTFLAGS="\"-C link-arg=-Wl,--warn-unresolved-symbols\""; \ rm /android/ndk/x86 && \ ln -s /android/ndk/x86-9 /android/ndk/x86 && \ python2.7 ../x.py dist --host $HOSTS --target $HOSTS) + +# sccache +COPY sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +# init +ENTRYPOINT ["/usr/bin/dumb-init", "--"] diff --git a/src/ci/docker/disabled/dist-x86_64-android/Dockerfile b/src/ci/docker/disabled/dist-x86_64-android/Dockerfile index a642d8ed6ec..4f4f5fae18d 100644 --- a/src/ci/docker/disabled/dist-x86_64-android/Dockerfile +++ b/src/ci/docker/disabled/dist-x86_64-android/Dockerfile @@ -2,36 +2,30 @@ FROM ubuntu:16.04 RUN apt-get update && \ apt-get install -y --no-install-recommends \ - g++ \ - make \ - file \ - curl \ ca-certificates \ - python2.7 \ - git \ cmake \ - unzip \ - sudo \ - xz-utils \ + curl \ + file \ + g++ \ + git \ libssl-dev \ - pkg-config + make \ + pkg-config \ + python2.7 \ + sudo \ + unzip \ + xz-utils -RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ - dpkg -i dumb-init_*.deb && \ - rm dumb-init_*.deb +# dumb-init +COPY dumb-init.sh /scripts/ +RUN sh /scripts/dumb-init.sh -RUN curl -o /usr/local/bin/sccache \ - https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \ - chmod +x /usr/local/bin/sccache - -ENTRYPOINT ["/usr/bin/dumb-init", "--"] - -COPY android-ndk.sh / -RUN . /android-ndk.sh && \ - download_ndk android-ndk-r13b-linux-x86_64.zip && \ - make_standalone_toolchain x86_64 21 && \ - remove_ndk +# ndk +COPY android-ndk.sh /scripts/ +RUN . /scripts/android-ndk.sh && \ + download_and_make_toolchain android-ndk-r13b-linux-x86_64.zip x86_64 21 +# env ENV PATH=$PATH:/android/ndk/x86_64-21/bin ENV DEP_Z_ROOT=/android/ndk/x86_64-21/sysroot/usr/ @@ -47,3 +41,10 @@ ENV RUST_CONFIGURE_ARGS \ --enable-cargo-openssl-static ENV SCRIPT python2.7 ../x.py dist --target $HOSTS --host $HOSTS + +# sccache +COPY sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +# init +ENTRYPOINT ["/usr/bin/dumb-init", "--"] diff --git a/src/ci/docker/dist-aarch64-linux/Dockerfile b/src/ci/docker/dist-aarch64-linux/Dockerfile index c8257c05acd..0134a540793 100644 --- a/src/ci/docker/dist-aarch64-linux/Dockerfile +++ b/src/ci/docker/dist-aarch64-linux/Dockerfile @@ -56,7 +56,7 @@ RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools USER rustbuild WORKDIR /tmp -COPY aarch64-linux-gnu.config build-toolchains.sh /tmp/ +COPY dist-aarch64-linux/aarch64-linux-gnu.config dist-aarch64-linux/build-toolchains.sh /tmp/ RUN ./build-toolchains.sh USER root diff --git a/src/ci/docker/dist-android/Dockerfile b/src/ci/docker/dist-android/Dockerfile index 711c0ee5747..13d76536113 100644 --- a/src/ci/docker/dist-android/Dockerfile +++ b/src/ci/docker/dist-android/Dockerfile @@ -2,33 +2,27 @@ FROM ubuntu:16.04 RUN apt-get update && \ apt-get install -y --no-install-recommends \ - g++ \ - make \ - file \ - curl \ ca-certificates \ - python2.7 \ - git \ cmake \ - unzip \ - sudo \ - xz-utils \ + curl \ + file \ + g++ \ + git \ libssl-dev \ - pkg-config + make \ + pkg-config \ + python2.7 \ + sudo \ + unzip \ + xz-utils -RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ - dpkg -i dumb-init_*.deb && \ - rm dumb-init_*.deb +# dumb-init +COPY dumb-init.sh /scripts/ +RUN sh /scripts/dumb-init.sh -RUN curl -o /usr/local/bin/sccache \ - https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl && \ - chmod +x /usr/local/bin/sccache - -ENTRYPOINT ["/usr/bin/dumb-init", "--"] - -# Install NDK -COPY install-ndk.sh /tmp -RUN . /tmp/install-ndk.sh && \ +# ndk +COPY android-ndk.sh /scripts/ +RUN . /scripts/android-ndk.sh && \ download_ndk android-ndk-r13b-linux-x86_64.zip && \ make_standalone_toolchain arm 9 && \ make_standalone_toolchain x86 9 && \ @@ -36,6 +30,7 @@ RUN . /tmp/install-ndk.sh && \ make_standalone_toolchain x86_64 21 && \ remove_ndk +# env ENV TARGETS=arm-linux-androideabi ENV TARGETS=$TARGETS,armv7-linux-androideabi ENV TARGETS=$TARGETS,i686-linux-android @@ -52,3 +47,10 @@ ENV RUST_CONFIGURE_ARGS \ --x86_64-linux-android-ndk=/android/ndk/x86_64-21 ENV SCRIPT python2.7 ../x.py dist --target $TARGETS + +# cache +COPY sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +# init +ENTRYPOINT ["/usr/bin/dumb-init", "--"] diff --git a/src/ci/docker/dist-android/install-ndk.sh b/src/ci/docker/dist-android/install-ndk.sh deleted file mode 100644 index 80818721199..00000000000 --- a/src/ci/docker/dist-android/install-ndk.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh -# Copyright 2016 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. - -set -ex - -URL=https://dl.google.com/android/repository - -download_ndk() { - mkdir -p /android/ndk - cd /android/ndk - curl -O $URL/$1 - unzip -q $1 - rm $1 - mv android-ndk-* ndk -} - -make_standalone_toolchain() { - # See https://developer.android.com/ndk/guides/standalone_toolchain.html - python2.7 /android/ndk/ndk/build/tools/make_standalone_toolchain.py \ - --install-dir /android/ndk/$1-$2 \ - --arch $1 \ - --api $2 -} - -remove_ndk() { - rm -rf /android/ndk/ndk -} diff --git a/src/ci/docker/dist-arm-linux/Dockerfile b/src/ci/docker/dist-arm-linux/Dockerfile index af2b58f7d6b..862818a7c91 100644 --- a/src/ci/docker/dist-arm-linux/Dockerfile +++ b/src/ci/docker/dist-arm-linux/Dockerfile @@ -56,7 +56,7 @@ RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools USER rustbuild WORKDIR /tmp -COPY arm-linux-gnueabi.config build-toolchains.sh /tmp/ +COPY dist-arm-linux/arm-linux-gnueabi.config dist-arm-linux/build-toolchains.sh /tmp/ RUN ./build-toolchains.sh USER root diff --git a/src/ci/docker/dist-armhf-linux/Dockerfile b/src/ci/docker/dist-armhf-linux/Dockerfile index 076bc50946c..7f1f91f844c 100644 --- a/src/ci/docker/dist-armhf-linux/Dockerfile +++ b/src/ci/docker/dist-armhf-linux/Dockerfile @@ -56,7 +56,7 @@ RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools USER rustbuild WORKDIR /tmp -COPY arm-linux-gnueabihf.config build-toolchains.sh /tmp/ +COPY dist-armhf-linux/arm-linux-gnueabihf.config dist-armhf-linux/build-toolchains.sh /tmp/ RUN ./build-toolchains.sh USER root diff --git a/src/ci/docker/dist-armv7-linux/Dockerfile b/src/ci/docker/dist-armv7-linux/Dockerfile index 9367a5a6270..030fd24ebcd 100644 --- a/src/ci/docker/dist-armv7-linux/Dockerfile +++ b/src/ci/docker/dist-armv7-linux/Dockerfile @@ -56,7 +56,7 @@ RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools USER rustbuild WORKDIR /tmp -COPY build-toolchains.sh armv7-linux-gnueabihf.config /tmp/ +COPY dist-armv7-linux/build-toolchains.sh dist-armv7-linux/armv7-linux-gnueabihf.config /tmp/ RUN ./build-toolchains.sh USER root diff --git a/src/ci/docker/dist-fuchsia/Dockerfile b/src/ci/docker/dist-fuchsia/Dockerfile index 8699e0d87d7..d1d9767d35e 100644 --- a/src/ci/docker/dist-fuchsia/Dockerfile +++ b/src/ci/docker/dist-fuchsia/Dockerfile @@ -21,7 +21,7 @@ RUN curl -L https://cmake.org/files/v3.8/cmake-3.8.0-rc1-Linux-x86_64.tar.gz | \ tar xzf - -C /usr/local --strip-components=1 WORKDIR /tmp -COPY shared.sh build-toolchain.sh compiler-rt-dso-handle.patch /tmp/ +COPY dist-fuchsia/shared.sh dist-fuchsia/build-toolchain.sh dist-fuchsia/compiler-rt-dso-handle.patch /tmp/ RUN /tmp/build-toolchain.sh RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ diff --git a/src/ci/docker/dist-i586-gnu-i686-musl/Dockerfile b/src/ci/docker/dist-i586-gnu-i686-musl/Dockerfile index 3e823339eaa..805d238de1f 100644 --- a/src/ci/docker/dist-i586-gnu-i686-musl/Dockerfile +++ b/src/ci/docker/dist-i586-gnu-i686-musl/Dockerfile @@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ pkg-config WORKDIR /build/ -COPY musl-libunwind-patch.patch build-musl.sh /build/ +COPY dist-i586-gnu-i686-musl/musl-libunwind-patch.patch dist-i586-gnu-i686-musl/build-musl.sh /build/ RUN sh /build/build-musl.sh && rm -rf /build RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ diff --git a/src/ci/docker/dist-i686-freebsd/Dockerfile b/src/ci/docker/dist-i686-freebsd/Dockerfile index a1f36257f96..9c4d43bfa92 100644 --- a/src/ci/docker/dist-i686-freebsd/Dockerfile +++ b/src/ci/docker/dist-i686-freebsd/Dockerfile @@ -16,7 +16,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libssl-dev \ pkg-config -COPY build-toolchain.sh /tmp/ +COPY dist-i686-freebsd/build-toolchain.sh /tmp/ RUN /tmp/build-toolchain.sh i686 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ diff --git a/src/ci/docker/dist-i686-linux/Dockerfile b/src/ci/docker/dist-i686-linux/Dockerfile index 8335147de60..a3c08e93ed1 100644 --- a/src/ci/docker/dist-i686-linux/Dockerfile +++ b/src/ci/docker/dist-i686-linux/Dockerfile @@ -29,13 +29,13 @@ ENV PATH=/rustroot/bin:$PATH ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib ENV PKG_CONFIG_PATH=/rustroot/lib/pkgconfig WORKDIR /tmp -COPY shared.sh build-binutils.sh /tmp/ +COPY dist-i686-linux/shared.sh dist-i686-linux/build-binutils.sh /tmp/ # We need a build of openssl which supports SNI to download artifacts from # static.rust-lang.org. This'll be used to link into libcurl below (and used # later as well), so build a copy of OpenSSL with dynamic libraries into our # generic root. -COPY build-openssl.sh /tmp/ +COPY dist-i686-linux/build-openssl.sh /tmp/ RUN ./build-openssl.sh # The `curl` binary on CentOS doesn't support SNI which is needed for fetching @@ -44,7 +44,7 @@ RUN ./build-openssl.sh # # Note that we also disable a bunch of optional features of curl that we don't # really need. -COPY build-curl.sh /tmp/ +COPY dist-i686-linux/build-curl.sh /tmp/ RUN ./build-curl.sh # binutils < 2.22 has a bug where the 32-bit executables it generates @@ -54,26 +54,26 @@ RUN ./build-curl.sh RUN ./build-binutils.sh # Need a newer version of gcc than centos has to compile LLVM nowadays -COPY build-gcc.sh /tmp/ +COPY dist-i686-linux/build-gcc.sh /tmp/ RUN ./build-gcc.sh # CentOS 5.5 has Python 2.4 by default, but LLVM needs 2.7+ -COPY build-python.sh /tmp/ +COPY dist-i686-linux/build-python.sh /tmp/ RUN ./build-python.sh # Apparently CentOS 5.5 desn't have `git` in yum, but we're gonna need it for # cloning, so download and build it here. -COPY build-git.sh /tmp/ +COPY dist-i686-linux/build-git.sh /tmp/ RUN ./build-git.sh # libssh2 (a dependency of Cargo) requires cmake 2.8.11 or higher but CentOS # only has 2.6.4, so build our own -COPY build-cmake.sh /tmp/ +COPY dist-i686-linux/build-cmake.sh /tmp/ RUN ./build-cmake.sh # for sanitizers, we need kernel headers files newer than the ones CentOS ships # with so we install newer ones here -COPY build-headers.sh /tmp/ +COPY dist-i686-linux/build-headers.sh /tmp/ RUN ./build-headers.sh RUN curl -Lo /rustroot/dumb-init \ diff --git a/src/ci/docker/dist-powerpc64-linux/Dockerfile b/src/ci/docker/dist-powerpc64-linux/Dockerfile index 58b09fd0fa7..bd38ee0c111 100644 --- a/src/ci/docker/dist-powerpc64-linux/Dockerfile +++ b/src/ci/docker/dist-powerpc64-linux/Dockerfile @@ -56,8 +56,8 @@ RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools USER rustbuild WORKDIR /tmp -COPY patches/ /tmp/patches/ -COPY shared.sh powerpc64-linux-gnu.config build-powerpc64-toolchain.sh /tmp/ +COPY dist-powerpc64-linux/patches/ /tmp/patches/ +COPY dist-powerpc64-linux/shared.sh dist-powerpc64-linux/powerpc64-linux-gnu.config dist-powerpc64-linux/build-powerpc64-toolchain.sh /tmp/ RUN ./build-powerpc64-toolchain.sh USER root diff --git a/src/ci/docker/dist-powerpc64le-linux/Dockerfile b/src/ci/docker/dist-powerpc64le-linux/Dockerfile index 08f1d1d7ed5..cbded156b4c 100644 --- a/src/ci/docker/dist-powerpc64le-linux/Dockerfile +++ b/src/ci/docker/dist-powerpc64le-linux/Dockerfile @@ -59,7 +59,7 @@ WORKDIR /tmp USER root RUN apt-get install -y --no-install-recommends rpm2cpio cpio -COPY shared.sh build-powerpc64le-toolchain.sh /tmp/ +COPY dist-powerpc64le-linux/shared.sh dist-powerpc64le-linux/build-powerpc64le-toolchain.sh /tmp/ RUN ./build-powerpc64le-toolchain.sh RUN curl -o /usr/local/bin/sccache \ diff --git a/src/ci/docker/dist-s390x-linux/Dockerfile b/src/ci/docker/dist-s390x-linux/Dockerfile index 5eb238fa887..5c00287107a 100644 --- a/src/ci/docker/dist-s390x-linux/Dockerfile +++ b/src/ci/docker/dist-s390x-linux/Dockerfile @@ -56,8 +56,8 @@ RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools USER rustbuild WORKDIR /tmp -COPY patches/ /tmp/patches/ -COPY s390x-linux-gnu.config build-s390x-toolchain.sh /tmp/ +COPY dist-s390x-linux/patches/ /tmp/patches/ +COPY dist-s390x-linux/s390x-linux-gnu.config dist-s390x-linux/build-s390x-toolchain.sh /tmp/ RUN ./build-s390x-toolchain.sh USER root diff --git a/src/ci/docker/dist-x86_64-freebsd/Dockerfile b/src/ci/docker/dist-x86_64-freebsd/Dockerfile index 0ac58468147..a6c4eee5e81 100644 --- a/src/ci/docker/dist-x86_64-freebsd/Dockerfile +++ b/src/ci/docker/dist-x86_64-freebsd/Dockerfile @@ -16,7 +16,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libssl-dev \ pkg-config -COPY build-toolchain.sh /tmp/ +COPY dist-x86_64-freebsd/build-toolchain.sh /tmp/ RUN /tmp/build-toolchain.sh x86_64 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ diff --git a/src/ci/docker/dist-x86_64-linux/Dockerfile b/src/ci/docker/dist-x86_64-linux/Dockerfile index d688bb7f8a4..e2e42836dcd 100644 --- a/src/ci/docker/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/dist-x86_64-linux/Dockerfile @@ -29,13 +29,13 @@ ENV PATH=/rustroot/bin:$PATH ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib ENV PKG_CONFIG_PATH=/rustroot/lib/pkgconfig WORKDIR /tmp -COPY shared.sh build-binutils.sh /tmp/ +COPY dist-x86_64-linux/shared.sh dist-x86_64-linux/build-binutils.sh /tmp/ # We need a build of openssl which supports SNI to download artifacts from # static.rust-lang.org. This'll be used to link into libcurl below (and used # later as well), so build a copy of OpenSSL with dynamic libraries into our # generic root. -COPY build-openssl.sh /tmp/ +COPY dist-x86_64-linux/build-openssl.sh /tmp/ RUN ./build-openssl.sh # The `curl` binary on CentOS doesn't support SNI which is needed for fetching @@ -44,7 +44,7 @@ RUN ./build-openssl.sh # # Note that we also disable a bunch of optional features of curl that we don't # really need. -COPY build-curl.sh /tmp/ +COPY dist-x86_64-linux/build-curl.sh /tmp/ RUN ./build-curl.sh # binutils < 2.22 has a bug where the 32-bit executables it generates @@ -54,26 +54,26 @@ RUN ./build-curl.sh RUN ./build-binutils.sh # Need a newer version of gcc than centos has to compile LLVM nowadays -COPY build-gcc.sh /tmp/ +COPY dist-x86_64-linux/build-gcc.sh /tmp/ RUN ./build-gcc.sh # CentOS 5.5 has Python 2.4 by default, but LLVM needs 2.7+ -COPY build-python.sh /tmp/ +COPY dist-x86_64-linux/build-python.sh /tmp/ RUN ./build-python.sh # Apparently CentOS 5.5 desn't have `git` in yum, but we're gonna need it for # cloning, so download and build it here. -COPY build-git.sh /tmp/ +COPY dist-x86_64-linux/build-git.sh /tmp/ RUN ./build-git.sh # libssh2 (a dependency of Cargo) requires cmake 2.8.11 or higher but CentOS # only has 2.6.4, so build our own -COPY build-cmake.sh /tmp/ +COPY dist-x86_64-linux/build-cmake.sh /tmp/ RUN ./build-cmake.sh # for sanitizers, we need kernel headers files newer than the ones CentOS ships # with so we install newer ones here -COPY build-headers.sh /tmp/ +COPY dist-x86_64-linux/build-headers.sh /tmp/ RUN ./build-headers.sh RUN curl -Lo /rustroot/dumb-init \ diff --git a/src/ci/docker/dist-x86_64-musl/Dockerfile b/src/ci/docker/dist-x86_64-musl/Dockerfile index 87550641bc6..2eea5ab1469 100644 --- a/src/ci/docker/dist-x86_64-musl/Dockerfile +++ b/src/ci/docker/dist-x86_64-musl/Dockerfile @@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ pkg-config WORKDIR /build/ -COPY build-musl.sh /build/ +COPY dist-x86_64-musl/build-musl.sh /build/ RUN sh /build/build-musl.sh && rm -rf /build RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \ diff --git a/src/ci/docker/dist-x86_64-netbsd/Dockerfile b/src/ci/docker/dist-x86_64-netbsd/Dockerfile index b6d9c221c1c..f76e6271f4c 100644 --- a/src/ci/docker/dist-x86_64-netbsd/Dockerfile +++ b/src/ci/docker/dist-x86_64-netbsd/Dockerfile @@ -56,7 +56,7 @@ RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools USER rustbuild WORKDIR /tmp -COPY build-netbsd-toolchain.sh /tmp/ +COPY dist-x86_64-netbsd/build-netbsd-toolchain.sh /tmp/ RUN ./build-netbsd-toolchain.sh USER root diff --git a/src/ci/docker/dumb-init.sh b/src/ci/docker/dumb-init.sh new file mode 100644 index 00000000000..839c3907992 --- /dev/null +++ b/src/ci/docker/dumb-init.sh @@ -0,0 +1,15 @@ +# 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. + +set -ex + +curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb +dpkg -i dumb-init_*.deb +rm dumb-init_*.deb diff --git a/src/ci/docker/emscripten/Dockerfile b/src/ci/docker/emscripten/Dockerfile index 09657d2f892..0f0e5b69c32 100644 --- a/src/ci/docker/emscripten/Dockerfile +++ b/src/ci/docker/emscripten/Dockerfile @@ -24,7 +24,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini ENTRYPOINT ["/usr/bin/dumb-init", "--"] WORKDIR /tmp -COPY build-emscripten.sh /tmp/ +COPY emscripten/build-emscripten.sh /tmp/ RUN ./build-emscripten.sh ENV PATH=$PATH:/tmp/emsdk_portable ENV PATH=$PATH:/tmp/emsdk_portable/clang/tag-e1.37.10/build_tag-e1.37.10_32/bin diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index 6abbf0530af..bb9a860574d 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -26,7 +26,8 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then build \ --rm \ -t rust-ci \ - "$docker_dir/$image" + -f "$docker_dir/$image/Dockerfile" \ + "$docker_dir" elif [ -f "$docker_dir/disabled/$image/Dockerfile" ]; then if [ -n "$TRAVIS_OS_NAME" ]; then echo Cannot run disabled images on travis! diff --git a/src/ci/docker/sccache.sh b/src/ci/docker/sccache.sh new file mode 100644 index 00000000000..7a2befaf671 --- /dev/null +++ b/src/ci/docker/sccache.sh @@ -0,0 +1,16 @@ +# 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. + +set -ex + +curl -o /usr/local/bin/sccache \ + https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-05-12-sccache-x86_64-unknown-linux-musl + +chmod +x /usr/local/bin/sccache From 3fa04a9a9318dde57e7d056411276a925a4b76d9 Mon Sep 17 00:00:00 2001 From: Mike Lubinets Date: Thu, 18 May 2017 01:55:15 +0300 Subject: [PATCH 083/103] Cargo submodule update --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index b007d82be9a..41e490480b0 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit b007d82be9aa82ae69d382b392d91c151df16da2 +Subproject commit 41e490480b01ef8d15ef061b578fbf1e08d0faa9 From b9552963d1269ac6008dceda3c2cca65a2d746dc Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 17 May 2017 23:36:24 +0200 Subject: [PATCH 084/103] misc doc improvements for std::env --- src/libstd/env.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 64eb52e28bc..96c10c5d10d 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -43,16 +43,19 @@ use sys::os as os_imp; /// use std::env; /// /// // We assume that we are in a valid directory. -/// let p = env::current_dir().unwrap(); -/// println!("The current directory is {}", p.display()); +/// let path = env::current_dir().unwrap(); +/// println!("The current directory is {}", path.display()); /// ``` #[stable(feature = "env", since = "1.0.0")] pub fn current_dir() -> io::Result { os_imp::getcwd() } -/// Changes the current working directory to the specified path, returning -/// whether the change was completed successfully or not. +/// Changes the current working directory to the specified path. +/// +/// Returns an [`Err`] if the operation fails. +/// +/// [`Err`]: ../../std/result/enum.Result.html#method.err /// /// # Examples /// @@ -65,8 +68,8 @@ pub fn current_dir() -> io::Result { /// println!("Successfully changed working directory to {}!", root.display()); /// ``` #[stable(feature = "env", since = "1.0.0")] -pub fn set_current_dir>(p: P) -> io::Result<()> { - os_imp::chdir(p.as_ref()) +pub fn set_current_dir>(path: P) -> io::Result<()> { + os_imp::chdir(path.as_ref()) } /// An iterator over a snapshot of the environment variables of this process. @@ -175,10 +178,10 @@ impl fmt::Debug for VarsOs { /// /// The returned result is [`Ok(s)`] if the environment variable is present and is /// valid unicode. If the environment variable is not present, or it is not -/// valid unicode, then [`Err`] will be returned. +/// valid unicode, then [`VarError`] will be returned. /// /// [`Ok(s)`]: ../result/enum.Result.html#variant.Ok -/// [`Err`]: ../result/enum.Result.html#variant.Err +/// [`VarError`]: enum.VarError.html /// /// # Examples /// @@ -199,7 +202,7 @@ pub fn var>(key: K) -> Result { fn _var(key: &OsStr) -> Result { match var_os(key) { Some(s) => s.into_string().map_err(VarError::NotUnicode), - None => Err(VarError::NotPresent) + None => Err(VarError::NotPresent), } } From f4e33a011ecbd4744c0a2c594ad69fd1a52bd9c5 Mon Sep 17 00:00:00 2001 From: Denis Andrejew Date: Thu, 18 May 2017 08:45:18 +0200 Subject: [PATCH 085/103] fix typo in libstd/sync/mpsc/mod.rs docs --- src/libstd/sync/mpsc/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 2cb649ce67b..284a5fbd9d5 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -1067,7 +1067,7 @@ impl Receiver { Receiver { inner: UnsafeCell::new(inner) } } - /// Attempts to return a pending value on this receiver without blocking + /// Attempts to return a pending value on this receiver without blocking. /// /// This method will never block the caller in order to wait for data to /// become available. Instead, this will always return immediately with a From 1eb6639508ce6874e4d5dbdb02dbb6111565d902 Mon Sep 17 00:00:00 2001 From: pravic Date: Thu, 18 May 2017 10:35:18 +0300 Subject: [PATCH 086/103] Make documentation works again by removing two unnecessary ES6 pieces. --- src/librustdoc/html/static/main.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index c115a6ccba6..f09ce1cc648 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -215,14 +215,14 @@ } else if (ev.target.tagName === 'SPAN' && hasClass(ev.target.parentNode, 'line-numbers')) { var prev_id = 0; - function set_fragment(name) { + var set_fragment = function (name) { if (browserSupportsHistoryApi()) { history.replaceState(null, null, '#' + name); window.hashchange(); } else { location.replace('#' + name); } - } + }; var cur_id = parseInt(ev.target.id, 10); @@ -685,7 +685,7 @@ } function escape(content) { - let h1 = document.createElement('h1'); + var h1 = document.createElement('h1'); h1.textContent = content; return h1.innerHTML; } From 1b8df3d7fb1f575ed12c13a79455af6c7de05632 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 17 May 2017 14:04:53 +0200 Subject: [PATCH 087/103] Enable cross-crate incremental compilation by default. --- src/librustc/session/config.rs | 2 +- .../add_private_fn_at_krate_root_cc/auxiliary/point.rs | 2 -- .../incremental/callee_caller_cross_crate/auxiliary/a.rs | 2 -- .../incremental/change_private_fn_cc/auxiliary/point.rs | 2 -- .../change_private_impl_method_cc/auxiliary/point.rs | 2 -- .../incremental/remapped_paths_cc/auxiliary/extern_crate.rs | 6 +++--- .../remove-private-item-cross-crate/auxiliary/a.rs | 2 -- src/test/incremental/rlib_cross_crate/auxiliary/a.rs | 1 - .../struct_change_field_type_cross_crate/auxiliary/a.rs | 2 -- src/test/incremental/type_alias_cross_crate/auxiliary/a.rs | 2 -- 10 files changed, 4 insertions(+), 19 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 4212fa1f8b1..e3b43b3290f 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -963,7 +963,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "attempt to recover from parse errors (experimental)"), incremental: Option = (None, parse_opt_string, [UNTRACKED], "enable incremental compilation (experimental)"), - incremental_cc: bool = (false, parse_bool, [UNTRACKED], + incremental_cc: bool = (true, parse_bool, [UNTRACKED], "enable cross-crate incremental compilation (even more experimental)"), incremental_info: bool = (false, parse_bool, [UNTRACKED], "print high-level information about incremental reuse (or the lack thereof)"), diff --git a/src/test/incremental/add_private_fn_at_krate_root_cc/auxiliary/point.rs b/src/test/incremental/add_private_fn_at_krate_root_cc/auxiliary/point.rs index 1064c97b744..adc2b23441e 100644 --- a/src/test/incremental/add_private_fn_at_krate_root_cc/auxiliary/point.rs +++ b/src/test/incremental/add_private_fn_at_krate_root_cc/auxiliary/point.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z incremental-cc - pub struct Point { pub x: f32, pub y: f32, diff --git a/src/test/incremental/callee_caller_cross_crate/auxiliary/a.rs b/src/test/incremental/callee_caller_cross_crate/auxiliary/a.rs index a02b71a753c..d802c9a8352 100644 --- a/src/test/incremental/callee_caller_cross_crate/auxiliary/a.rs +++ b/src/test/incremental/callee_caller_cross_crate/auxiliary/a.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z incremental-cc - #![crate_type="rlib"] #[cfg(rpass1)] diff --git a/src/test/incremental/change_private_fn_cc/auxiliary/point.rs b/src/test/incremental/change_private_fn_cc/auxiliary/point.rs index 08eef2a73f6..dcc1ced635f 100644 --- a/src/test/incremental/change_private_fn_cc/auxiliary/point.rs +++ b/src/test/incremental/change_private_fn_cc/auxiliary/point.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z incremental-cc - pub struct Point { pub x: f32, pub y: f32, diff --git a/src/test/incremental/change_private_impl_method_cc/auxiliary/point.rs b/src/test/incremental/change_private_impl_method_cc/auxiliary/point.rs index e69dc51119e..8df1cf54da2 100644 --- a/src/test/incremental/change_private_impl_method_cc/auxiliary/point.rs +++ b/src/test/incremental/change_private_impl_method_cc/auxiliary/point.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z incremental-cc - pub struct Point { pub x: f32, pub y: f32, diff --git a/src/test/incremental/remapped_paths_cc/auxiliary/extern_crate.rs b/src/test/incremental/remapped_paths_cc/auxiliary/extern_crate.rs index 9feefb4c037..1483bf92c97 100644 --- a/src/test/incremental/remapped_paths_cc/auxiliary/extern_crate.rs +++ b/src/test/incremental/remapped_paths_cc/auxiliary/extern_crate.rs @@ -10,9 +10,9 @@ // ignore-tidy-linelength -//[rpass1] compile-flags: -g -Zincremental-cc -//[rpass2] compile-flags: -g -Zincremental-cc -//[rpass3] compile-flags: -g -Zincremental-cc -Zremap-path-prefix-from={{src-base}} -Zremap-path-prefix-to=/the/src +//[rpass1] compile-flags: -g +//[rpass2] compile-flags: -g +//[rpass3] compile-flags: -g -Zremap-path-prefix-from={{src-base}} -Zremap-path-prefix-to=/the/src #![feature(rustc_attrs)] #![crate_type="rlib"] diff --git a/src/test/incremental/remove-private-item-cross-crate/auxiliary/a.rs b/src/test/incremental/remove-private-item-cross-crate/auxiliary/a.rs index 39547fb7359..4d84e844ded 100644 --- a/src/test/incremental/remove-private-item-cross-crate/auxiliary/a.rs +++ b/src/test/incremental/remove-private-item-cross-crate/auxiliary/a.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z incremental-cc - #![allow(warnings)] #![crate_name = "a"] #![crate_type = "rlib"] diff --git a/src/test/incremental/rlib_cross_crate/auxiliary/a.rs b/src/test/incremental/rlib_cross_crate/auxiliary/a.rs index 3ecd9aff3f8..ff5fd634714 100644 --- a/src/test/incremental/rlib_cross_crate/auxiliary/a.rs +++ b/src/test/incremental/rlib_cross_crate/auxiliary/a.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z incremental-cc // no-prefer-dynamic #![crate_type="rlib"] diff --git a/src/test/incremental/struct_change_field_type_cross_crate/auxiliary/a.rs b/src/test/incremental/struct_change_field_type_cross_crate/auxiliary/a.rs index d14ebf78d82..2ddcaf15721 100644 --- a/src/test/incremental/struct_change_field_type_cross_crate/auxiliary/a.rs +++ b/src/test/incremental/struct_change_field_type_cross_crate/auxiliary/a.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z incremental-cc - #![crate_type="rlib"] #[cfg(rpass1)] diff --git a/src/test/incremental/type_alias_cross_crate/auxiliary/a.rs b/src/test/incremental/type_alias_cross_crate/auxiliary/a.rs index 0393bcda991..e1dba131770 100644 --- a/src/test/incremental/type_alias_cross_crate/auxiliary/a.rs +++ b/src/test/incremental/type_alias_cross_crate/auxiliary/a.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z incremental-cc - #![crate_type="rlib"] #[cfg(rpass1)] From 474cc91440ecb89a4d7ea81b1786fddbf2b70641 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 17 May 2017 16:41:07 +0200 Subject: [PATCH 088/103] Use in-memory representation for Fingerprint that is more amenable to hashing. --- src/librustc/ich/fingerprint.rs | 72 ++++++++++++--------------------- 1 file changed, 26 insertions(+), 46 deletions(-) diff --git a/src/librustc/ich/fingerprint.rs b/src/librustc/ich/fingerprint.rs index ccdbab88b8b..a947f6aeff7 100644 --- a/src/librustc/ich/fingerprint.rs +++ b/src/librustc/ich/fingerprint.rs @@ -10,95 +10,75 @@ use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; use rustc_data_structures::stable_hasher; -use rustc_data_structures::ToHex; - -const FINGERPRINT_LENGTH: usize = 16; +use std::mem; +use std::slice; #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)] -pub struct Fingerprint(pub [u8; FINGERPRINT_LENGTH]); +pub struct Fingerprint(u64, u64); impl Fingerprint { #[inline] pub fn zero() -> Fingerprint { - Fingerprint([0; FINGERPRINT_LENGTH]) + Fingerprint(0, 0) } + #[inline] pub fn from_smaller_hash(hash: u64) -> Fingerprint { - let mut result = Fingerprint::zero(); - result.0[0] = (hash >> 0) as u8; - result.0[1] = (hash >> 8) as u8; - result.0[2] = (hash >> 16) as u8; - result.0[3] = (hash >> 24) as u8; - result.0[4] = (hash >> 32) as u8; - result.0[5] = (hash >> 40) as u8; - result.0[6] = (hash >> 48) as u8; - result.0[7] = (hash >> 56) as u8; - result + Fingerprint(hash, hash) } + #[inline] pub fn to_smaller_hash(&self) -> u64 { - ((self.0[0] as u64) << 0) | - ((self.0[1] as u64) << 8) | - ((self.0[2] as u64) << 16) | - ((self.0[3] as u64) << 24) | - ((self.0[4] as u64) << 32) | - ((self.0[5] as u64) << 40) | - ((self.0[6] as u64) << 48) | - ((self.0[7] as u64) << 56) + self.0 } pub fn to_hex(&self) -> String { - self.0.to_hex() + format!("{:x}{:x}", self.0, self.1) } } impl Encodable for Fingerprint { #[inline] fn encode(&self, s: &mut S) -> Result<(), S::Error> { - for &byte in &self.0 { - s.emit_u8(byte)?; - } - Ok(()) + s.emit_u64(self.0.to_le())?; + s.emit_u64(self.1.to_le()) } } impl Decodable for Fingerprint { #[inline] fn decode(d: &mut D) -> Result { - let mut result = Fingerprint([0u8; FINGERPRINT_LENGTH]); - for byte in &mut result.0 { - *byte = d.read_u8()?; - } - Ok(result) + let _0 = u64::from_le(d.read_u64()?); + let _1 = u64::from_le(d.read_u64()?); + Ok(Fingerprint(_0, _1)) } } impl ::std::fmt::Display for Fingerprint { fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { - for i in 0 .. self.0.len() { - if i > 0 { - write!(formatter, "::")?; - } - - write!(formatter, "{}", self.0[i])?; - } - Ok(()) + write!(formatter, "{:x}-{:x}", self.0, self.1) } } - impl stable_hasher::StableHasherResult for Fingerprint { fn finish(mut hasher: stable_hasher::StableHasher) -> Self { - let mut fingerprint = Fingerprint::zero(); - fingerprint.0.copy_from_slice(hasher.finalize()); - fingerprint + let hash_bytes: &[u8] = hasher.finalize(); + + assert!(hash_bytes.len() >= mem::size_of::() * 2); + let hash_bytes: &[u64] = unsafe { + slice::from_raw_parts(hash_bytes.as_ptr() as *const u64, 2) + }; + + // The bytes returned bytes the Blake2B hasher are always little-endian. + Fingerprint(u64::from_le(hash_bytes[0]), u64::from_le(hash_bytes[1])) } } impl stable_hasher::HashStable for Fingerprint { + #[inline] fn hash_stable(&self, _: &mut CTX, hasher: &mut stable_hasher::StableHasher) { - ::std::hash::Hash::hash(&self.0, hasher); + ::std::hash::Hash::hash(self, hasher); } } From 4549423f28dc05ae47447a1111326b1b7055c1a9 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 18 May 2017 10:54:20 +0200 Subject: [PATCH 089/103] Use 128 instead of 64 bits for DefPath hashes --- src/librustc/hir/map/definitions.rs | 17 +++++++++-------- src/librustc/ich/hcx.rs | 2 +- src/librustc/middle/cstore.rs | 4 ++-- src/librustc/ty/mod.rs | 4 ++-- src/librustc/ty/sty.rs | 5 +++-- src/librustc/ty/trait_def.rs | 5 +++-- src/librustc_incremental/calculate_svh/mod.rs | 2 +- src/librustc_metadata/cstore_impl.rs | 3 ++- src/librustc_metadata/decoder.rs | 3 ++- 9 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 6118df2ddfc..9537b40b28a 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -16,6 +16,7 @@ use hir; use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, DefIndexAddressSpace}; +use ich::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::stable_hasher::StableHasher; @@ -34,7 +35,7 @@ use util::nodemap::NodeMap; pub struct DefPathTable { index_to_key: [Vec; 2], key_to_index: FxHashMap, - def_path_hashes: [Vec; 2], + def_path_hashes: [Vec; 2], } // Unfortunately we have to provide a manual impl of Clone because of the @@ -55,7 +56,7 @@ impl DefPathTable { fn allocate(&mut self, key: DefKey, - def_path_hash: u64, + def_path_hash: Fingerprint, address_space: DefIndexAddressSpace) -> DefIndex { let index = { @@ -79,7 +80,7 @@ impl DefPathTable { } #[inline(always)] - pub fn def_path_hash(&self, index: DefIndex) -> u64 { + pub fn def_path_hash(&self, index: DefIndex) -> Fingerprint { self.def_path_hashes[index.address_space().index()] [index.as_array_index()] } @@ -146,8 +147,8 @@ impl Decodable for DefPathTable { let index_to_key_lo: Vec = Decodable::decode(d)?; let index_to_key_hi: Vec = Decodable::decode(d)?; - let def_path_hashes_lo: Vec = Decodable::decode(d)?; - let def_path_hashes_hi: Vec = Decodable::decode(d)?; + let def_path_hashes_lo: Vec = Decodable::decode(d)?; + let def_path_hashes_hi: Vec = Decodable::decode(d)?; let index_to_key = [index_to_key_lo, index_to_key_hi]; let def_path_hashes = [def_path_hashes_lo, def_path_hashes_hi]; @@ -210,7 +211,7 @@ pub struct DefKey { } impl DefKey { - fn compute_stable_hash(&self, parent_hash: u64) -> u64 { + fn compute_stable_hash(&self, parent_hash: Fingerprint) -> Fingerprint { let mut hasher = StableHasher::new(); // We hash a 0u8 here to disambiguate between regular DefPath hashes, @@ -221,7 +222,7 @@ impl DefKey { hasher.finish() } - fn root_parent_stable_hash(crate_name: &str, crate_disambiguator: &str) -> u64 { + fn root_parent_stable_hash(crate_name: &str, crate_disambiguator: &str) -> Fingerprint { let mut hasher = StableHasher::new(); // Disambiguate this from a regular DefPath hash, // see compute_stable_hash() above. @@ -396,7 +397,7 @@ impl Definitions { } #[inline(always)] - pub fn def_path_hash(&self, index: DefIndex) -> u64 { + pub fn def_path_hash(&self, index: DefIndex) -> Fingerprint { self.table.def_path_hash(index) } diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 786d1c5035d..f25ec8ecd4d 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -110,7 +110,7 @@ impl<'a, 'tcx: 'a> StableHashingContext<'a, 'tcx> { } #[inline] - pub fn def_path_hash(&mut self, def_id: DefId) -> u64 { + pub fn def_path_hash(&mut self, def_id: DefId) -> ich::Fingerprint { self.tcx.def_path_hash(def_id) } diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index a68aca46000..8ad1db78595 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -282,7 +282,7 @@ pub trait CrateStore { -> Option; fn def_key(&self, def: DefId) -> DefKey; fn def_path(&self, def: DefId) -> hir_map::DefPath; - fn def_path_hash(&self, def: DefId) -> u64; + fn def_path_hash(&self, def: DefId) -> ich::Fingerprint; fn struct_field_names(&self, def: DefId) -> Vec; fn item_children(&self, did: DefId) -> Vec; fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro; @@ -414,7 +414,7 @@ impl CrateStore for DummyCrateStore { fn def_path(&self, def: DefId) -> hir_map::DefPath { bug!("relative_def_path") } - fn def_path_hash(&self, def: DefId) -> u64 { + fn def_path_hash(&self, def: DefId) -> ich::Fingerprint { bug!("wa") } fn struct_field_names(&self, def: DefId) -> Vec { bug!("struct_field_names") } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index a86d7351ef4..359722ce96e 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -19,7 +19,7 @@ use dep_graph::DepNode; use hir::{map as hir_map, FreevarMap, TraitMap}; use hir::def::{Def, CtorKind, ExportMap}; use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; -use ich::StableHashingContext; +use ich::{self, StableHashingContext}; use middle::const_val::ConstVal; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; use middle::privacy::AccessLevels; @@ -2248,7 +2248,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } #[inline] - pub fn def_path_hash(self, def_id: DefId) -> u64 { + pub fn def_path_hash(self, def_id: DefId) -> ich::Fingerprint { if def_id.is_local() { self.hir.definitions().def_path_hash(def_id.index) } else { diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index cfbf1244db3..348d164af41 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -29,6 +29,7 @@ use util::nodemap::FxHashMap; use serialize; use hir; +use ich; use self::InferTy::*; use self::TypeVariants::*; @@ -849,7 +850,7 @@ impl<'a, 'tcx, 'gcx> ExistentialProjection<'tcx> { self.item_name // safe to skip the binder to access a name } - pub fn sort_key(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> (u64, InternedString) { + pub fn sort_key(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> (ich::Fingerprint, InternedString) { // We want something here that is stable across crate boundaries. // The DefId isn't but the `deterministic_hash` of the corresponding // DefPath is. @@ -884,7 +885,7 @@ impl<'a, 'tcx, 'gcx> PolyExistentialProjection<'tcx> { self.skip_binder().item_name() } - pub fn sort_key(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> (u64, InternedString) { + pub fn sort_key(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> (ich::Fingerprint, InternedString) { self.skip_binder().sort_key(tcx) } diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs index 865297c7ecb..86774136bd6 100644 --- a/src/librustc/ty/trait_def.rs +++ b/src/librustc/ty/trait_def.rs @@ -9,6 +9,7 @@ // except according to those terms. use hir::def_id::DefId; +use ich::Fingerprint; use traits::specialization_graph; use ty::fast_reject; use ty::fold::TypeFoldable; @@ -32,7 +33,7 @@ pub struct TraitDef { /// The ICH of this trait's DefPath, cached here so it doesn't have to be /// recomputed all the time. - pub def_path_hash: u64, + pub def_path_hash: Fingerprint, } // We don't store the list of impls in a flat list because each cached list of @@ -94,7 +95,7 @@ impl<'a, 'gcx, 'tcx> TraitDef { unsafety: hir::Unsafety, paren_sugar: bool, has_default_impl: bool, - def_path_hash: u64) + def_path_hash: Fingerprint) -> TraitDef { TraitDef { def_id, diff --git a/src/librustc_incremental/calculate_svh/mod.rs b/src/librustc_incremental/calculate_svh/mod.rs index 8cdabc1d894..c9ed9ad3c7d 100644 --- a/src/librustc_incremental/calculate_svh/mod.rs +++ b/src/librustc_incremental/calculate_svh/mod.rs @@ -224,7 +224,7 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { { let tcx = self.hcx.tcx(); - let mut impls: Vec<(u64, Fingerprint)> = krate + let mut impls: Vec<(Fingerprint, Fingerprint)> = krate .trait_impls .iter() .map(|(&trait_id, impls)| { diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 4b7083590d2..7478f902e06 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -17,6 +17,7 @@ use rustc::middle::cstore::{CrateStore, CrateSource, LibSource, DepKind, ExternCrate, NativeLibrary, MetadataLoader, LinkMeta, LinkagePreference, LoadedMacro, EncodedMetadata}; use rustc::hir::def; +use rustc::ich; use rustc::middle::lang_items; use rustc::session::Session; use rustc::ty::{self, TyCtxt}; @@ -337,7 +338,7 @@ impl CrateStore for cstore::CStore { self.get_crate_data(def.krate).def_path(def.index) } - fn def_path_hash(&self, def: DefId) -> u64 { + fn def_path_hash(&self, def: DefId) -> ich::Fingerprint { self.get_crate_data(def.krate).def_path_hash(def.index) } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 754f27810c4..d8826d87d4d 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -16,6 +16,7 @@ use schema::*; use rustc::dep_graph::{DepGraph, DepNode, GlobalMetaDataKind}; use rustc::hir::map::{DefKey, DefPath, DefPathData}; use rustc::hir; +use rustc::ich; use rustc::middle::cstore::LinkagePreference; use rustc::hir::def::{self, Def, CtorKind}; @@ -1106,7 +1107,7 @@ impl<'a, 'tcx> CrateMetadata { } #[inline] - pub fn def_path_hash(&self, index: DefIndex) -> u64 { + pub fn def_path_hash(&self, index: DefIndex) -> ich::Fingerprint { self.def_path_table.def_path_hash(index) } From b2fc7b1cbeae1e6cb1a5b4797d221733592ae6a4 Mon Sep 17 00:00:00 2001 From: Michael Kohl Date: Thu, 11 May 2017 22:49:16 +0700 Subject: [PATCH 090/103] Add documentation for `ExitStatus` As requested in #29370. --- src/libstd/process.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 3896fc20a2d..d0e7defbbbb 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -754,6 +754,13 @@ impl fmt::Debug for Stdio { } /// Describes the result of a process after it has terminated. +/// +/// This `struct` is used to represent the exit status of a child process. +/// Child processes are created via the [`Command`] struct and their exit +/// status is exposed through the [`status`] method. +/// +/// [`Command`]: struct.Command.html +/// [`status`]: struct.Command.html#method.status #[derive(PartialEq, Eq, Clone, Copy, Debug)] #[stable(feature = "process", since = "1.0.0")] pub struct ExitStatus(imp::ExitStatus); @@ -788,6 +795,22 @@ impl ExitStatus { /// On Unix, this will return `None` if the process was terminated /// by a signal; `std::os::unix` provides an extension trait for /// extracting the signal and other details from the `ExitStatus`. + /// + /// # Examples + /// + /// ```no_run + /// use std::process::Command; + /// + /// let status = Command::new("mkdir") + /// .arg("projects") + /// .status() + /// .expect("failed to execute mkdir"); + /// + /// match status.code() { + /// Some(code) => println!("Exited with status code: {}", code), + /// None => println!("Process terminated by signal") + /// } + /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn code(&self) -> Option { self.0.code() From d15c950ac6604662b2e74420c73639f23396a93b Mon Sep 17 00:00:00 2001 From: Marco A L Barbosa Date: Thu, 18 May 2017 08:33:10 -0300 Subject: [PATCH 091/103] ci: move shared scripts to src/ci/docker/scripts/ --- src/ci/docker/arm-android/Dockerfile | 10 +++++----- src/ci/docker/disabled/dist-aarch64-android/Dockerfile | 6 +++--- src/ci/docker/disabled/dist-armv7-android/Dockerfile | 6 +++--- src/ci/docker/disabled/dist-i686-android/Dockerfile | 6 +++--- src/ci/docker/disabled/dist-x86_64-android/Dockerfile | 6 +++--- src/ci/docker/dist-android/Dockerfile | 6 +++--- src/ci/docker/{ => scripts}/android-ndk.sh | 0 src/ci/docker/{ => scripts}/android-sdk.sh | 0 src/ci/docker/{ => scripts}/android-start-emulator.sh | 0 src/ci/docker/{ => scripts}/dumb-init.sh | 0 src/ci/docker/{ => scripts}/sccache.sh | 0 11 files changed, 20 insertions(+), 20 deletions(-) rename src/ci/docker/{ => scripts}/android-ndk.sh (100%) rename src/ci/docker/{ => scripts}/android-sdk.sh (100%) rename src/ci/docker/{ => scripts}/android-start-emulator.sh (100%) rename src/ci/docker/{ => scripts}/dumb-init.sh (100%) rename src/ci/docker/{ => scripts}/sccache.sh (100%) diff --git a/src/ci/docker/arm-android/Dockerfile b/src/ci/docker/arm-android/Dockerfile index 6fd3ed7c6a9..2a928c5ec7e 100644 --- a/src/ci/docker/arm-android/Dockerfile +++ b/src/ci/docker/arm-android/Dockerfile @@ -17,11 +17,11 @@ RUN apt-get update && \ xz-utils # dumb-init -COPY dumb-init.sh /scripts/ +COPY scripts/dumb-init.sh /scripts/ RUN sh /scripts/dumb-init.sh # ndk -COPY android-ndk.sh /scripts/ +COPY scripts/android-ndk.sh /scripts/ RUN . /scripts/android-ndk.sh && \ download_and_make_toolchain android-ndk-r13b-linux-x86_64.zip arm 9 @@ -35,7 +35,7 @@ RUN dpkg --add-architecture i386 && \ openjdk-9-jre-headless \ tzdata -COPY android-sdk.sh /scripts/ +COPY scripts/android-sdk.sh /scripts/ RUN . /scripts/android-sdk.sh && \ download_and_create_avd tools_r25.2.5-linux.zip armeabi-v7a 18 @@ -52,9 +52,9 @@ ENV RUST_CONFIGURE_ARGS \ ENV SCRIPT python2.7 ../x.py test --target $TARGETS # sccache -COPY sccache.sh /scripts/ +COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh # init -COPY android-start-emulator.sh /scripts/ +COPY scripts/android-start-emulator.sh /scripts/ ENTRYPOINT ["/usr/bin/dumb-init", "--", "/scripts/android-start-emulator.sh"] diff --git a/src/ci/docker/disabled/dist-aarch64-android/Dockerfile b/src/ci/docker/disabled/dist-aarch64-android/Dockerfile index 5a966518759..918d2911ae2 100644 --- a/src/ci/docker/disabled/dist-aarch64-android/Dockerfile +++ b/src/ci/docker/disabled/dist-aarch64-android/Dockerfile @@ -17,11 +17,11 @@ RUN apt-get update && \ xz-utils # dumb-init -COPY dumb-init.sh /scripts/ +COPY scripts/dumb-init.sh /scripts/ RUN sh /scripts/dumb-init.sh # ndk -COPY android-ndk.sh /scripts/ +COPY scripts/android-ndk.sh /scripts/ RUN . /scripts/android-ndk.sh && \ download_and_make_toolchain android-ndk-r13b-linux-x86_64.zip arm64 21 @@ -43,7 +43,7 @@ ENV RUST_CONFIGURE_ARGS \ ENV SCRIPT python2.7 ../x.py dist --target $HOSTS --host $HOSTS # sccache -COPY sccache.sh /scripts/ +COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh # init diff --git a/src/ci/docker/disabled/dist-armv7-android/Dockerfile b/src/ci/docker/disabled/dist-armv7-android/Dockerfile index f92a28a7946..aed82e6c138 100644 --- a/src/ci/docker/disabled/dist-armv7-android/Dockerfile +++ b/src/ci/docker/disabled/dist-armv7-android/Dockerfile @@ -17,11 +17,11 @@ RUN apt-get update && \ xz-utils # dumb-init -COPY dumb-init.sh /scripts/ +COPY scripts/dumb-init.sh /scripts/ RUN sh /scripts/dumb-init.sh # ndk -COPY android-ndk.sh /scripts/ +COPY scripts/android-ndk.sh /scripts/ RUN . /scripts/android-ndk.sh && \ download_ndk android-ndk-r13b-linux-x86_64.zip && \ make_standalone_toolchain arm 9 && \ @@ -61,7 +61,7 @@ ENV SCRIPT \ python2.7 ../x.py dist --host $HOSTS --target $HOSTS) # sccache -COPY sccache.sh /scripts/ +COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh # init diff --git a/src/ci/docker/disabled/dist-i686-android/Dockerfile b/src/ci/docker/disabled/dist-i686-android/Dockerfile index c475c19ebde..f012e869e78 100644 --- a/src/ci/docker/disabled/dist-i686-android/Dockerfile +++ b/src/ci/docker/disabled/dist-i686-android/Dockerfile @@ -17,11 +17,11 @@ RUN apt-get update && \ xz-utils # dumb-init -COPY dumb-init.sh /scripts/ +COPY scripts/dumb-init.sh /scripts/ RUN sh /scripts/dumb-init.sh # ndk -COPY android-ndk.sh /scripts/ +COPY scripts/android-ndk.sh /scripts/ RUN . /scripts/android-ndk.sh && \ download_ndk android-ndk-r13b-linux-x86_64.zip && \ make_standalone_toolchain x86 9 && \ @@ -61,7 +61,7 @@ ENV SCRIPT \ python2.7 ../x.py dist --host $HOSTS --target $HOSTS) # sccache -COPY sccache.sh /scripts/ +COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh # init diff --git a/src/ci/docker/disabled/dist-x86_64-android/Dockerfile b/src/ci/docker/disabled/dist-x86_64-android/Dockerfile index 4f4f5fae18d..0c586452840 100644 --- a/src/ci/docker/disabled/dist-x86_64-android/Dockerfile +++ b/src/ci/docker/disabled/dist-x86_64-android/Dockerfile @@ -17,11 +17,11 @@ RUN apt-get update && \ xz-utils # dumb-init -COPY dumb-init.sh /scripts/ +COPY scripts/dumb-init.sh /scripts/ RUN sh /scripts/dumb-init.sh # ndk -COPY android-ndk.sh /scripts/ +COPY scripts/android-ndk.sh /scripts/ RUN . /scripts/android-ndk.sh && \ download_and_make_toolchain android-ndk-r13b-linux-x86_64.zip x86_64 21 @@ -43,7 +43,7 @@ ENV RUST_CONFIGURE_ARGS \ ENV SCRIPT python2.7 ../x.py dist --target $HOSTS --host $HOSTS # sccache -COPY sccache.sh /scripts/ +COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh # init diff --git a/src/ci/docker/dist-android/Dockerfile b/src/ci/docker/dist-android/Dockerfile index 13d76536113..31389dd148a 100644 --- a/src/ci/docker/dist-android/Dockerfile +++ b/src/ci/docker/dist-android/Dockerfile @@ -17,11 +17,11 @@ RUN apt-get update && \ xz-utils # dumb-init -COPY dumb-init.sh /scripts/ +COPY scripts/dumb-init.sh /scripts/ RUN sh /scripts/dumb-init.sh # ndk -COPY android-ndk.sh /scripts/ +COPY scripts/android-ndk.sh /scripts/ RUN . /scripts/android-ndk.sh && \ download_ndk android-ndk-r13b-linux-x86_64.zip && \ make_standalone_toolchain arm 9 && \ @@ -49,7 +49,7 @@ ENV RUST_CONFIGURE_ARGS \ ENV SCRIPT python2.7 ../x.py dist --target $TARGETS # cache -COPY sccache.sh /scripts/ +COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh # init diff --git a/src/ci/docker/android-ndk.sh b/src/ci/docker/scripts/android-ndk.sh similarity index 100% rename from src/ci/docker/android-ndk.sh rename to src/ci/docker/scripts/android-ndk.sh diff --git a/src/ci/docker/android-sdk.sh b/src/ci/docker/scripts/android-sdk.sh similarity index 100% rename from src/ci/docker/android-sdk.sh rename to src/ci/docker/scripts/android-sdk.sh diff --git a/src/ci/docker/android-start-emulator.sh b/src/ci/docker/scripts/android-start-emulator.sh similarity index 100% rename from src/ci/docker/android-start-emulator.sh rename to src/ci/docker/scripts/android-start-emulator.sh diff --git a/src/ci/docker/dumb-init.sh b/src/ci/docker/scripts/dumb-init.sh similarity index 100% rename from src/ci/docker/dumb-init.sh rename to src/ci/docker/scripts/dumb-init.sh diff --git a/src/ci/docker/sccache.sh b/src/ci/docker/scripts/sccache.sh similarity index 100% rename from src/ci/docker/sccache.sh rename to src/ci/docker/scripts/sccache.sh From 502eadbf8f68e647f43ca6af206977dd026184e4 Mon Sep 17 00:00:00 2001 From: Marco A L Barbosa Date: Thu, 18 May 2017 09:21:11 -0300 Subject: [PATCH 092/103] ci: add filesystem layout docs --- src/ci/docker/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index 6f3a7e091e1..627b5062df3 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -16,6 +16,12 @@ for example: Images will output artifacts in an `obj` dir at the root of a repository. +## Filesystem layout + +- Each directory, excluding `scripts` and `disabled`, corresponds to a docker image +- `scripts` contains files shared by docker images +- `disabled` contains images that are not build travis + ## Cross toolchains A number of these images take quite a long time to compile as they're building From cd6cbd7a951bd8360b071a32ea73dbcf47b3e7f7 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 18 May 2017 09:52:00 -0700 Subject: [PATCH 093/103] Update the Cargo submodules --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 41e490480b0..397359840ec 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 41e490480b01ef8d15ef061b578fbf1e08d0faa9 +Subproject commit 397359840ecad02d5fe69b2a0cf328e98235ffea From ecfdc9ac1b5ad416661c46cea8075a8a85a09233 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Perennou Date: Wed, 17 May 2017 12:15:15 +0200 Subject: [PATCH 094/103] rustbuild: install rust-analysis and rust-src when extended build is enabled Signed-off-by: Marc-Antoine Perennou --- src/bootstrap/install.rs | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index 386b001971b..5d5ee67c956 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -55,37 +55,47 @@ pub fn install(build: &Build, stage: u32, host: &str) { t!(fs::create_dir_all(&empty_dir)); if build.config.docs { install_sh(&build, "docs", "rust-docs", &build.rust_package_vers(), - stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, + stage, Some(host), &prefix, &sysconfdir, &docdir, &bindir, &libdir, &mandir, &empty_dir); } for target in build.config.target.iter() { install_sh(&build, "std", "rust-std", &build.rust_package_vers(), - stage, target, &prefix, &sysconfdir, &docdir, &bindir, &libdir, + stage, Some(target), &prefix, &sysconfdir, &docdir, &bindir, &libdir, &mandir, &empty_dir); } if build.config.extended { install_sh(&build, "cargo", "cargo", &build.cargo_package_vers(), - stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, + stage, Some(host), &prefix, &sysconfdir, &docdir, &bindir, &libdir, &mandir, &empty_dir); install_sh(&build, "rls", "rls", &build.rls_package_vers(), - stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, + stage, Some(host), &prefix, &sysconfdir, &docdir, &bindir, &libdir, + &mandir, &empty_dir); + install_sh(&build, "analysis", "rust-analysis", &build.rust_package_vers(), + stage, Some(host), &prefix, &sysconfdir, &docdir, &bindir, &libdir, + &mandir, &empty_dir); + install_sh(&build, "src", "rust-src", &build.rust_package_vers(), + stage, None, &prefix, &sysconfdir, &docdir, &bindir, &libdir, &mandir, &empty_dir); } install_sh(&build, "rustc", "rustc", &build.rust_package_vers(), - stage, host, &prefix, &sysconfdir, &docdir, &bindir, &libdir, + stage, Some(host), &prefix, &sysconfdir, &docdir, &bindir, &libdir, &mandir, &empty_dir); t!(fs::remove_dir_all(&empty_dir)); } -fn install_sh(build: &Build, package: &str, name: &str, version: &str, stage: u32, host: &str, +fn install_sh(build: &Build, package: &str, name: &str, version: &str, stage: u32, host: Option<&str>, prefix: &Path, sysconfdir: &Path, docdir: &Path, bindir: &Path, libdir: &Path, mandir: &Path, empty_dir: &Path) { - println!("Install {} stage{} ({})", package, stage, host); - let package_name = format!("{}-{}-{}", name, version, host); + println!("Install {} stage{} ({:?})", package, stage, host); + let package_name = if let Some(host) = host { + format!("{}-{}-{}", name, version, host) + } else { + format!("{}-{}", name, version) + }; let mut cmd = Command::new("sh"); cmd.current_dir(empty_dir) From 801e2b7bdf5a5bda966c9e5c81977da3bed1e6d0 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Perennou Date: Thu, 18 May 2017 10:56:25 +0200 Subject: [PATCH 095/103] rustbuild: refactor install Introduce a new Installer object that hold a reference to all the configured paths for installation Signed-off-by: Marc-Antoine Perennou --- src/bootstrap/install.rs | 185 +++++++++++++++++++++------------------ src/bootstrap/step.rs | 2 +- 2 files changed, 102 insertions(+), 85 deletions(-) diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index 5d5ee67c956..dce0b1670e1 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -21,93 +21,110 @@ use std::process::Command; use Build; use dist::{sanitize_sh, tmpdir}; -/// Installs everything. -pub fn install(build: &Build, stage: u32, host: &str) { - let prefix_default = PathBuf::from("/usr/local"); - let sysconfdir_default = PathBuf::from("/etc"); - let docdir_default = PathBuf::from("share/doc/rust"); - let bindir_default = PathBuf::from("bin"); - let libdir_default = PathBuf::from("lib"); - let mandir_default = PathBuf::from("share/man"); - let prefix = build.config.prefix.as_ref().unwrap_or(&prefix_default); - let sysconfdir = build.config.sysconfdir.as_ref().unwrap_or(&sysconfdir_default); - let docdir = build.config.docdir.as_ref().unwrap_or(&docdir_default); - let bindir = build.config.bindir.as_ref().unwrap_or(&bindir_default); - let libdir = build.config.libdir.as_ref().unwrap_or(&libdir_default); - let mandir = build.config.mandir.as_ref().unwrap_or(&mandir_default); - - let sysconfdir = prefix.join(sysconfdir); - let docdir = prefix.join(docdir); - let bindir = prefix.join(bindir); - let libdir = prefix.join(libdir); - let mandir = prefix.join(mandir); - - let destdir = env::var_os("DESTDIR").map(PathBuf::from); - - let prefix = add_destdir(&prefix, &destdir); - let sysconfdir = add_destdir(&sysconfdir, &destdir); - let docdir = add_destdir(&docdir, &destdir); - let bindir = add_destdir(&bindir, &destdir); - let libdir = add_destdir(&libdir, &destdir); - let mandir = add_destdir(&mandir, &destdir); - - let empty_dir = build.out.join("tmp/empty_dir"); - t!(fs::create_dir_all(&empty_dir)); - if build.config.docs { - install_sh(&build, "docs", "rust-docs", &build.rust_package_vers(), - stage, Some(host), &prefix, &sysconfdir, &docdir, &bindir, &libdir, - &mandir, &empty_dir); - } - - for target in build.config.target.iter() { - install_sh(&build, "std", "rust-std", &build.rust_package_vers(), - stage, Some(target), &prefix, &sysconfdir, &docdir, &bindir, &libdir, - &mandir, &empty_dir); - } - - if build.config.extended { - install_sh(&build, "cargo", "cargo", &build.cargo_package_vers(), - stage, Some(host), &prefix, &sysconfdir, &docdir, &bindir, &libdir, - &mandir, &empty_dir); - install_sh(&build, "rls", "rls", &build.rls_package_vers(), - stage, Some(host), &prefix, &sysconfdir, &docdir, &bindir, &libdir, - &mandir, &empty_dir); - install_sh(&build, "analysis", "rust-analysis", &build.rust_package_vers(), - stage, Some(host), &prefix, &sysconfdir, &docdir, &bindir, &libdir, - &mandir, &empty_dir); - install_sh(&build, "src", "rust-src", &build.rust_package_vers(), - stage, None, &prefix, &sysconfdir, &docdir, &bindir, &libdir, - &mandir, &empty_dir); - } - - install_sh(&build, "rustc", "rustc", &build.rust_package_vers(), - stage, Some(host), &prefix, &sysconfdir, &docdir, &bindir, &libdir, - &mandir, &empty_dir); - - t!(fs::remove_dir_all(&empty_dir)); +pub struct Installer<'a> { + build: &'a Build, + prefix: PathBuf, + sysconfdir: PathBuf, + docdir: PathBuf, + bindir: PathBuf, + libdir: PathBuf, + mandir: PathBuf, } -fn install_sh(build: &Build, package: &str, name: &str, version: &str, stage: u32, host: Option<&str>, - prefix: &Path, sysconfdir: &Path, docdir: &Path, bindir: &Path, libdir: &Path, - mandir: &Path, empty_dir: &Path) { - println!("Install {} stage{} ({:?})", package, stage, host); - let package_name = if let Some(host) = host { - format!("{}-{}-{}", name, version, host) - } else { - format!("{}-{}", name, version) - }; +impl<'a> Installer<'a> { + pub fn new(build: &'a Build) -> Installer<'a> { + let prefix_default = PathBuf::from("/usr/local"); + let sysconfdir_default = PathBuf::from("/etc"); + let docdir_default = PathBuf::from("share/doc/rust"); + let bindir_default = PathBuf::from("bin"); + let libdir_default = PathBuf::from("lib"); + let mandir_default = PathBuf::from("share/man"); + let prefix = build.config.prefix.as_ref().unwrap_or(&prefix_default); + let sysconfdir = build.config.sysconfdir.as_ref().unwrap_or(&sysconfdir_default); + let docdir = build.config.docdir.as_ref().unwrap_or(&docdir_default); + let bindir = build.config.bindir.as_ref().unwrap_or(&bindir_default); + let libdir = build.config.libdir.as_ref().unwrap_or(&libdir_default); + let mandir = build.config.mandir.as_ref().unwrap_or(&mandir_default); - let mut cmd = Command::new("sh"); - cmd.current_dir(empty_dir) - .arg(sanitize_sh(&tmpdir(build).join(&package_name).join("install.sh"))) - .arg(format!("--prefix={}", sanitize_sh(prefix))) - .arg(format!("--sysconfdir={}", sanitize_sh(sysconfdir))) - .arg(format!("--docdir={}", sanitize_sh(docdir))) - .arg(format!("--bindir={}", sanitize_sh(bindir))) - .arg(format!("--libdir={}", sanitize_sh(libdir))) - .arg(format!("--mandir={}", sanitize_sh(mandir))) - .arg("--disable-ldconfig"); - build.run(&mut cmd); + let sysconfdir = prefix.join(sysconfdir); + let docdir = prefix.join(docdir); + let bindir = prefix.join(bindir); + let libdir = prefix.join(libdir); + let mandir = prefix.join(mandir); + + let destdir = env::var_os("DESTDIR").map(PathBuf::from); + + let prefix = add_destdir(&prefix, &destdir); + let sysconfdir = add_destdir(&sysconfdir, &destdir); + let docdir = add_destdir(&docdir, &destdir); + let bindir = add_destdir(&bindir, &destdir); + let libdir = add_destdir(&libdir, &destdir); + let mandir = add_destdir(&mandir, &destdir); + + Installer { + build, + prefix, + sysconfdir, + docdir, + bindir, + libdir, + mandir, + } + } + + /// Installs everything. + pub fn install(&self, stage: u32, host: &str) { + let empty_dir = self.build.out.join("tmp/empty_dir"); + t!(fs::create_dir_all(&empty_dir)); + + if self.build.config.docs { + self.install_sh("docs", "rust-docs", &self.build.rust_package_vers(), + stage, Some(host), &empty_dir); + } + + for target in self.build.config.target.iter() { + self.install_sh("std", "rust-std", &self.build.rust_package_vers(), + stage, Some(target), &empty_dir); + } + + if self.build.config.extended { + self.install_sh("cargo", "cargo", &self.build.cargo_package_vers(), + stage, Some(host), &empty_dir); + self.install_sh("rls", "rls", &self.build.rls_package_vers(), + stage, Some(host), &empty_dir); + self.install_sh("analysis", "rust-analysis", &self.build.rust_package_vers(), + stage, Some(host), &empty_dir); + self.install_sh("src", "rust-src", &self.build.rust_package_vers(), + stage, None, &empty_dir); + } + + self.install_sh("rustc", "rustc", &self.build.rust_package_vers(), + stage, Some(host), &empty_dir); + + t!(fs::remove_dir_all(&empty_dir)); + } + + fn install_sh(&self, package: &str, name: &str, version: &str, + stage: u32, host: Option<&str>, empty_dir: &Path) { + println!("Install {} stage{} ({:?})", package, stage, host); + let package_name = if let Some(host) = host { + format!("{}-{}-{}", name, version, host) + } else { + format!("{}-{}", name, version) + }; + + let mut cmd = Command::new("sh"); + cmd.current_dir(empty_dir) + .arg(sanitize_sh(&tmpdir(self.build).join(&package_name).join("install.sh"))) + .arg(format!("--prefix={}", sanitize_sh(&self.prefix))) + .arg(format!("--sysconfdir={}", sanitize_sh(&self.sysconfdir))) + .arg(format!("--docdir={}", sanitize_sh(&self.docdir))) + .arg(format!("--bindir={}", sanitize_sh(&self.bindir))) + .arg(format!("--libdir={}", sanitize_sh(&self.libdir))) + .arg(format!("--mandir={}", sanitize_sh(&self.mandir))) + .arg("--disable-ldconfig"); + self.build.run(&mut cmd); + } } fn add_destdir(path: &Path, destdir: &Option) -> PathBuf { diff --git a/src/bootstrap/step.rs b/src/bootstrap/step.rs index 92666e8e639..57915446e1d 100644 --- a/src/bootstrap/step.rs +++ b/src/bootstrap/step.rs @@ -761,7 +761,7 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules { .run(move |s| dist::rls(build, s.stage, s.target)); rules.dist("install", "path/to/nowhere") .dep(|s| s.name("default:dist")) - .run(move |s| install::install(build, s.stage, s.target)); + .run(move |s| install::Installer::new(build).install(s.stage, s.target)); rules.dist("dist-cargo", "cargo") .host(true) .only_host_build(true) From c5163aadc5e599d45e9022a3d8df4815b6066bdc Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Thu, 18 May 2017 21:22:15 +0300 Subject: [PATCH 096/103] Fix x.py --- src/bootstrap/bootstrap.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index e15304a7e6e..bfba1a0dede 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -398,13 +398,14 @@ class RustBuild(object): sys.exit(ret) def output(self, args, env=None, cwd=None): + default_encoding = sys.getdefaultencoding() proc = subprocess.Popen(args, stdout=subprocess.PIPE, env=env, cwd=cwd) (out, err) = proc.communicate() ret = proc.wait() if ret != 0: print(out) sys.exit(ret) - return out + return out.decode(default_encoding) def build_triple(self): default_encoding = sys.getdefaultencoding() @@ -570,10 +571,10 @@ class RustBuild(object): for submod in submodules: path, status = submod - if path.endswith(b"llvm") and \ + if path.endswith('llvm') and \ (self.get_toml('llvm-config') or self.get_mk('CFG_LLVM_ROOT')): continue - if path.endswith(b"jemalloc") and \ + if path.endswith('jemalloc') and \ (self.get_toml('jemalloc') or self.get_mk('CFG_JEMALLOC_ROOT')): continue submod_path = os.path.join(self.rust_root, path) From 9b184c0c17701d70f30f1f3c89b2c6c55c68b169 Mon Sep 17 00:00:00 2001 From: Marco A L Barbosa Date: Thu, 18 May 2017 17:11:46 -0300 Subject: [PATCH 097/103] ci: fix dist-powerpc-linux image --- src/ci/docker/dist-powerpc-linux/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/dist-powerpc-linux/Dockerfile b/src/ci/docker/dist-powerpc-linux/Dockerfile index bff6504749e..0074665f34f 100644 --- a/src/ci/docker/dist-powerpc-linux/Dockerfile +++ b/src/ci/docker/dist-powerpc-linux/Dockerfile @@ -56,8 +56,8 @@ RUN mkdir /x-tools && chown rustbuild:rustbuild /x-tools USER rustbuild WORKDIR /tmp -COPY patches/ /tmp/patches/ -COPY powerpc-linux-gnu.config build-powerpc-toolchain.sh /tmp/ +COPY dist-powerpc-linux/patches/ /tmp/patches/ +COPY dist-powerpc-linux/powerpc-linux-gnu.config dist-powerpc-linux/build-powerpc-toolchain.sh /tmp/ RUN ./build-powerpc-toolchain.sh USER root From e86588e2286ac2c0fb4763bf2d8c3046d0abcc22 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 18 May 2017 16:11:22 -0700 Subject: [PATCH 098/103] Give a nicer error for non-Unicode arguments to rustc and rustdoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, any non-Unicode argument would panic rustc: ``` $ rustc $'foo\x80bar' error: internal compiler error: unexpected panic note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports thread 'rustc' panicked at 'called `Result::unwrap()` on an `Err` value: "foo�bar"', /checkout/src/libcore/result.rs:859 note: Run with `RUST_BACKTRACE=1` for a backtrace. ``` Now it gives a clean error: ``` $ rustc $'foo\x80bar' error: Argument 1 is not valid Unicode: "foo�bar" ``` Maybe fixes #15890, although we still can't *compile* arbitrary file names. --- src/librustc_driver/lib.rs | 11 ++++++++++- src/librustdoc/lib.rs | 11 +++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 34f636d0b9a..18a57f78a50 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1148,9 +1148,18 @@ pub fn diagnostics_registry() -> errors::registry::Registry { Registry::new(&all_errors) } +fn get_args() -> Vec { + env::args_os().enumerate() + .map(|(i, arg)| arg.into_string().unwrap_or_else(|arg| { + early_error(ErrorOutputType::default(), + &format!("Argument {} is not valid Unicode: {:?}", i, arg)) + })) + .collect() +} + pub fn main() { env_logger::init().unwrap(); - let result = run(|| run_compiler(&env::args().collect::>(), + let result = run(|| run_compiler(&get_args(), &mut RustcDefaultCalls, None, None)); diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index bbaa7bc2fb6..f682f6aa763 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -107,12 +107,19 @@ pub fn main() { const STACK_SIZE: usize = 32_000_000; // 32MB env_logger::init().unwrap(); let res = std::thread::Builder::new().stack_size(STACK_SIZE).spawn(move || { - let s = env::args().collect::>(); - main_args(&s) + get_args().map(|args| main_args(&args)).unwrap_or(1) }).unwrap().join().unwrap_or(101); process::exit(res as i32); } +fn get_args() -> Option> { + env::args_os().enumerate() + .map(|(i, arg)| arg.into_string().map_err(|arg| { + print_error(format!("Argument {} is not valid Unicode: {:?}", i, arg)); + }).ok()) + .collect() +} + fn stable(g: getopts::OptGroup) -> RustcOptGroup { RustcOptGroup::stable(g) } fn unstable(g: getopts::OptGroup) -> RustcOptGroup { RustcOptGroup::unstable(g) } From e48086c04fb8092253ab638c6b0aa82b09edc8d0 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Fri, 19 May 2017 02:59:04 +0100 Subject: [PATCH 099/103] rustdoc: Fix implementors list javascript * Use a different loop variable, `i` was already taken. This caused missing items in the implementors list. * Use `.getAttribute('href')` rather than `.href` to get the relative URL which is what it needs to actually fix the links. --- src/librustdoc/html/static/main.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index c115a6ccba6..e85f70ffedc 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1083,10 +1083,10 @@ code.innerHTML = structs[j]; var x = code.getElementsByTagName('a'); - for (var i = 0; i < x.length; i++) { - var href = x[i].href; + for (var k = 0; k < x.length; k++) { + var href = x[k].getAttribute('href'); if (href && href.indexOf('http') !== 0) { - x[i].href = rootPath + href; + x[k].setAttribute('href', rootPath + href); } } var li = document.createElement('li'); From 4cd838b274db73be8c974e5335b28f1b6f6b75a0 Mon Sep 17 00:00:00 2001 From: David LeGare Date: Thu, 18 May 2017 21:10:15 -0500 Subject: [PATCH 100/103] Normalize docs in windows::ffi and windows::fs - Remove `()` parens when referencing functions in docs. - Change some examples to be no_run instead of ignore. - Normalize style in examples for `OpenOptionsExt`. - Fix typo in windows mod docs. --- src/libstd/sys/windows/ext/ffi.rs | 10 +-- src/libstd/sys/windows/ext/fs.rs | 113 ++++++++++++++++-------------- src/libstd/sys/windows/ext/mod.rs | 2 +- 3 files changed, 66 insertions(+), 59 deletions(-) diff --git a/src/libstd/sys/windows/ext/ffi.rs b/src/libstd/sys/windows/ext/ffi.rs index cb13595fcd6..3f6c2827a3f 100644 --- a/src/libstd/sys/windows/ext/ffi.rs +++ b/src/libstd/sys/windows/ext/ffi.rs @@ -26,7 +26,7 @@ pub trait OsStringExt { /// Creates an `OsString` from a potentially ill-formed UTF-16 slice of /// 16-bit code units. /// - /// This is lossless: calling [`encode_wide()`] on the resulting string + /// This is lossless: calling [`encode_wide`] on the resulting string /// will always return the original code units. /// /// # Examples @@ -41,7 +41,7 @@ pub trait OsStringExt { /// let string = OsString::from_wide(&source[..]); /// ``` /// - /// [`encode_wide()`]: ./trait.OsStrExt.html#tymethod.encode_wide + /// [`encode_wide`]: ./trait.OsStrExt.html#tymethod.encode_wide #[stable(feature = "rust1", since = "1.0.0")] fn from_wide(wide: &[u16]) -> Self; } @@ -59,8 +59,8 @@ pub trait OsStrExt { /// Re-encodes an `OsStr` as a wide character sequence, i.e. potentially /// ill-formed UTF-16. /// - /// This is lossless: calling [`OsString::from_wide()`] and then - /// `encode_wide()` on the result will yield the original code units. + /// This is lossless: calling [`OsString::from_wide`] and then + /// `encode_wide` on the result will yield the original code units. /// Note that the encoding does not add a final null terminator. /// /// # Examples @@ -78,7 +78,7 @@ pub trait OsStrExt { /// assert_eq!(&source[..], &result[..]); /// ``` /// - /// [`OsString::from_wide()`]: ./trait.OsStringExt.html#tymethod.from_wide + /// [`OsString::from_wide`]: ./trait.OsStringExt.html#tymethod.from_wide #[stable(feature = "rust1", since = "1.0.0")] fn encode_wide(&self) -> EncodeWide; } diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs index 8b227573f98..34f3a0196ce 100644 --- a/src/libstd/sys/windows/ext/fs.rs +++ b/src/libstd/sys/windows/ext/fs.rs @@ -40,7 +40,7 @@ pub trait FileExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::io; /// use std::fs::File; /// use std::os::windows::prelude::*; @@ -75,7 +75,7 @@ pub trait FileExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs::File; /// use std::os::windows::prelude::*; /// @@ -120,10 +120,10 @@ pub trait OpenOptionsExt { /// /// ```no_run /// use std::fs::OpenOptions; - /// use std::os::windows::fs::OpenOptionsExt; + /// use std::os::windows::prelude::*; /// /// // Open without read and write permission, for example if you only need - /// // to call `stat()` on the file + /// // to call `stat` on the file /// let file = OpenOptions::new().access_mode(0).open("foo.txt"); /// ``` /// @@ -145,13 +145,14 @@ pub trait OpenOptionsExt { /// /// ```no_run /// use std::fs::OpenOptions; - /// use std::os::windows::fs::OpenOptionsExt; + /// use std::os::windows::prelude::*; /// /// // Do not allow others to read or modify this file while we have it open /// // for writing. - /// let file = OpenOptions::new().write(true) - /// .share_mode(0) - /// .open("foo.txt"); + /// let file = OpenOptions::new() + /// .write(true) + /// .share_mode(0) + /// .open("foo.txt"); /// ``` /// /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx @@ -170,13 +171,15 @@ pub trait OpenOptionsExt { /// /// ```ignore /// extern crate winapi; - /// use std::fs::OpenOptions; - /// use std::os::windows::fs::OpenOptionsExt; /// - /// let mut options = OpenOptions::new(); - /// options.create(true).write(true); - /// options.custom_flags(winapi::FILE_FLAG_DELETE_ON_CLOSE); - /// let file = options.open("foo.txt"); + /// use std::fs::OpenOptions; + /// use std::os::windows::prelude::*; + /// + /// let file = OpenOptions::new() + /// .create(true) + /// .write(true) + /// .custom_flags(winapi::FILE_FLAG_DELETE_ON_CLOSE) + /// .open("foo.txt"); /// ``` /// /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx @@ -203,12 +206,15 @@ pub trait OpenOptionsExt { /// /// ```ignore /// extern crate winapi; - /// use std::fs::OpenOptions; - /// use std::os::windows::fs::OpenOptionsExt; /// - /// let file = OpenOptions::new().write(true).create(true) - /// .attributes(winapi::FILE_ATTRIBUTE_HIDDEN) - /// .open("foo.txt"); + /// use std::fs::OpenOptions; + /// use std::os::windows::prelude::*; + /// + /// let file = OpenOptions::new() + /// .write(true) + /// .create(true) + /// .attributes(winapi::FILE_ATTRIBUTE_HIDDEN) + /// .open("foo.txt"); /// ``` /// /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx @@ -226,17 +232,18 @@ pub trait OpenOptionsExt { /// /// # Examples /// - /// ```ignore + /// ```no_run /// use std::fs::OpenOptions; - /// use std::os::windows::fs::OpenOptionsExt; + /// use std::os::windows::prelude::*; /// - /// let options = OpenOptions::new(); - /// options.write(true).create(true); + /// let file = OpenOptions::new() + /// .write(true) + /// .create(true) /// - /// // Sets the flag value to `SecurityIdentification`. - /// options.security_qos_flags(1); + /// // Sets the flag value to `SecurityIdentification`. + /// options.security_qos_flags(1) /// - /// let file = options.open("foo.txt"); + /// .open("foo.txt"); /// ``` /// /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx @@ -289,15 +296,15 @@ pub trait MetadataExt { /// /// # Examples /// - /// ```ignore + /// ```no_run /// use std::io; - /// use std::io::prelude::*; - /// use std::fs::File; + /// use std::fs; /// use std::os::windows::prelude::*; /// /// # fn foo() -> io::Result<()> { - /// let mut file = File::open("foo.txt")?; - /// let attributes = file.file_attributes(); + /// let metadata = fs::metadata("foo.txt")?; + /// let attributes = metadata.file_attributes(); + /// # Ok(()) /// # } /// ``` /// @@ -319,15 +326,15 @@ pub trait MetadataExt { /// /// # Examples /// - /// ```ignore + /// ```no_run /// use std::io; - /// use std::io::prelude::*; - /// use std::fs::File; + /// use std::fs; /// use std::os::windows::prelude::*; /// /// # fn foo() -> io::Result<()> { - /// let mut file = File::open("foo.txt")?; - /// let creation_time = file.creation_time(); + /// let metadata = fs::metadata("foo.txt")?; + /// let creation_time = metadata.creation_time(); + /// # Ok(()) /// # } /// ``` /// @@ -354,15 +361,15 @@ pub trait MetadataExt { /// /// # Examples /// - /// ```ignore + /// ```no_run /// use std::io; - /// use std::io::prelude::*; - /// use std::fs::File; + /// use std::fs; /// use std::os::windows::prelude::*; /// /// # fn foo() -> io::Result<()> { - /// let mut file = File::open("foo.txt")?; - /// let last_access_time = file.last_access_time(); + /// let metadata = fs::metadata("foo.txt")?; + /// let last_access_time = metadata.last_access_time(); + /// # Ok(()) /// # } /// ``` /// @@ -387,15 +394,15 @@ pub trait MetadataExt { /// /// # Examples /// - /// ```ignore + /// ```no_run /// use std::io; - /// use std::io::prelude::*; - /// use std::fs::File; + /// use std::fs; /// use std::os::windows::prelude::*; /// /// # fn foo() -> io::Result<()> { - /// let mut file = File::open("foo.txt")?; - /// let last_write_time = file.last_write_time(); + /// let metadata = fs::metadata("foo.txt")?; + /// let last_write_time = metadata.last_write_time(); + /// # Ok(()) /// # } /// ``` /// @@ -410,15 +417,15 @@ pub trait MetadataExt { /// /// # Examples /// - /// ```ignore + /// ```no_run /// use std::io; - /// use std::io::prelude::*; - /// use std::fs::File; + /// use std::fs; /// use std::os::windows::prelude::*; /// /// # fn foo() -> io::Result<()> { - /// let mut file = File::open("foo.txt")?; - /// let file_size = file.file_size(); + /// let metadata = fs::metadata("foo.txt")?; + /// let file_size = metadata.file_size(); + /// # Ok(()) /// # } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] @@ -441,7 +448,7 @@ impl MetadataExt for Metadata { /// /// # Examples /// -/// ```ignore +/// ```no_run /// use std::os::windows::fs; /// /// # fn foo() -> std::io::Result<()> { @@ -462,7 +469,7 @@ pub fn symlink_file, Q: AsRef>(src: P, dst: Q) /// /// # Examples /// -/// ```ignore +/// ```no_run /// use std::os::windows::fs; /// /// # fn foo() -> std::io::Result<()> { diff --git a/src/libstd/sys/windows/ext/mod.rs b/src/libstd/sys/windows/ext/mod.rs index e07acad5e46..11b1337a8ae 100644 --- a/src/libstd/sys/windows/ext/mod.rs +++ b/src/libstd/sys/windows/ext/mod.rs @@ -13,7 +13,7 @@ //! Provides access to platform-level information for Windows, and exposes //! Windows-specific idioms that would otherwise be inappropriate as part //! the core `std` library. These extensions allow developers to use -//! `std` types and idioms with Windows in a way that the noraml +//! `std` types and idioms with Windows in a way that the normal //! platform-agnostic idioms would not normally support. #![stable(feature = "rust1", since = "1.0.0")] From 41debc365e398b95742d9e6910705495e93c0ec6 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Mon, 15 May 2017 12:17:17 +0300 Subject: [PATCH 101/103] Try to optimise char patterns --- src/libcollections/benches/str.rs | 23 +++++++++++++++++------ src/libcollections/str.rs | 14 ++++++++++++++ src/libcore/str/pattern.rs | 28 +++++++++++++++++++++++++++- 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/libcollections/benches/str.rs b/src/libcollections/benches/str.rs index 7f727078101..fc4063fae92 100644 --- a/src/libcollections/benches/str.rs +++ b/src/libcollections/benches/str.rs @@ -195,30 +195,34 @@ fn bench_contains_equal(b: &mut Bencher) { }) } + macro_rules! make_test_inner { - ($s:ident, $code:expr, $name:ident, $str:expr) => { + ($s:ident, $code:expr, $name:ident, $str:expr, $iters:expr) => { #[bench] fn $name(bencher: &mut Bencher) { let mut $s = $str; black_box(&mut $s); - bencher.iter(|| $code); + bencher.iter(|| for _ in 0..$iters { black_box($code); }); } } } macro_rules! make_test { ($name:ident, $s:ident, $code:expr) => { + make_test!($name, $s, $code, 1); + }; + ($name:ident, $s:ident, $code:expr, $iters:expr) => { mod $name { use test::Bencher; use test::black_box; // Short strings: 65 bytes each make_test_inner!($s, $code, short_ascii, - "Mary had a little lamb, Little lamb Mary had a littl lamb, lamb!"); + "Mary had a little lamb, Little lamb Mary had a littl lamb, lamb!", $iters); make_test_inner!($s, $code, short_mixed, - "ศไทย中华Việt Nam; Mary had a little lamb, Little lam!"); + "ศไทย中华Việt Nam; Mary had a little lamb, Little lam!", $iters); make_test_inner!($s, $code, short_pile_of_poo, - "💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩!"); + "💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩!", $iters); make_test_inner!($s, $code, long_lorem_ipsum,"\ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \ ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \ @@ -253,7 +257,7 @@ Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \ vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \ leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \ -malesuada sollicitudin quam eu fermentum!"); +malesuada sollicitudin quam eu fermentum!", $iters); } } } @@ -288,6 +292,13 @@ make_test!(find_zzz_char, s, s.find('\u{1F4A4}')); make_test!(rfind_zzz_char, s, s.rfind('\u{1F4A4}')); make_test!(find_zzz_str, s, s.find("\u{1F4A4}")); +make_test!(starts_with_ascii_char, s, s.starts_with('/'), 1024); +make_test!(ends_with_ascii_char, s, s.ends_with('/'), 1024); +make_test!(starts_with_unichar, s, s.starts_with('\u{1F4A4}'), 1024); +make_test!(ends_with_unichar, s, s.ends_with('\u{1F4A4}'), 1024); +make_test!(starts_with_str, s, s.starts_with("💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩"), 1024); +make_test!(ends_with_str, s, s.ends_with("💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩"), 1024); + make_test!(split_space_char, s, s.split(' ').count()); make_test!(split_terminator_space_char, s, s.split_terminator(' ').count()); diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 5f4578bbeb3..7e67befb700 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -813,6 +813,7 @@ impl str { /// assert!(!bananas.contains("apples")); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool { core_str::StrExt::contains(self, pat) } @@ -900,6 +901,7 @@ impl str { /// assert_eq!(s.find(x), None); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option { core_str::StrExt::find(self, pat) } @@ -944,6 +946,7 @@ impl str { /// assert_eq!(s.rfind(x), None); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option where P::Searcher: ReverseSearcher<'a> { @@ -1057,6 +1060,7 @@ impl str { /// /// [`split_whitespace`]: #method.split_whitespace #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> { core_str::StrExt::split(self, pat) } @@ -1106,6 +1110,7 @@ impl str { /// assert_eq!(v, ["ghi", "def", "abc"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P> where P::Searcher: ReverseSearcher<'a> { @@ -1152,6 +1157,7 @@ impl str { /// assert_eq!(v, ["A", "", "B", ""]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> { core_str::StrExt::split_terminator(self, pat) } @@ -1195,6 +1201,7 @@ impl str { /// assert_eq!(v, ["", "B", "", "A"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P> where P::Searcher: ReverseSearcher<'a> { @@ -1247,6 +1254,7 @@ impl str { /// assert_eq!(v, ["abc", "defXghi"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn splitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> SplitN<'a, P> { core_str::StrExt::splitn(self, n, pat) } @@ -1294,6 +1302,7 @@ impl str { /// assert_eq!(v, ["ghi", "abc1def"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> RSplitN<'a, P> where P::Searcher: ReverseSearcher<'a> { @@ -1334,6 +1343,7 @@ impl str { /// assert_eq!(v, ["1", "2", "3"]); /// ``` #[stable(feature = "str_matches", since = "1.2.0")] + #[inline] pub fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> { core_str::StrExt::matches(self, pat) } @@ -1370,6 +1380,7 @@ impl str { /// assert_eq!(v, ["3", "2", "1"]); /// ``` #[stable(feature = "str_matches", since = "1.2.0")] + #[inline] pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P> where P::Searcher: ReverseSearcher<'a> { @@ -1415,6 +1426,7 @@ impl str { /// assert_eq!(v, [(0, "aba")]); // only the first `aba` /// ``` #[stable(feature = "str_match_indices", since = "1.5.0")] + #[inline] pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> { core_str::StrExt::match_indices(self, pat) } @@ -1457,6 +1469,7 @@ impl str { /// assert_eq!(v, [(2, "aba")]); // only the last `aba` /// ``` #[stable(feature = "str_match_indices", since = "1.5.0")] + #[inline] pub fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P> where P::Searcher: ReverseSearcher<'a> { @@ -1737,6 +1750,7 @@ impl str { /// assert_eq!(s, s.replace("cookie monster", "little lamb")); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[inline] pub fn replace<'a, P: Pattern<'a>>(&'a self, from: P, to: &str) -> String { let mut result = String::new(); let mut last_end = 0; diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs index 8493afe98bc..4918e37eb35 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -429,7 +429,33 @@ impl<'a> DoubleEndedSearcher<'a> for CharSearcher<'a> {} /// Searches for chars that are equal to a given char impl<'a> Pattern<'a> for char { - pattern_methods!(CharSearcher<'a>, CharEqPattern, CharSearcher); + type Searcher = CharSearcher<'a>; + + #[inline] + fn into_searcher(self, haystack: &'a str) -> Self::Searcher { + CharSearcher(CharEqPattern(self).into_searcher(haystack)) + } + + #[inline] + fn is_contained_in(self, haystack: &'a str) -> bool { + if (self as u32) < 128 { + haystack.as_bytes().contains(&(self as u8)) + } else { + let mut buffer = [0u8; 4]; + self.encode_utf8(&mut buffer).is_contained_in(haystack) + } + } + + #[inline] + fn is_prefix_of(self, haystack: &'a str) -> bool { + CharEqPattern(self).is_prefix_of(haystack) + } + + #[inline] + fn is_suffix_of(self, haystack: &'a str) -> bool where Self::Searcher: ReverseSearcher<'a> + { + CharEqPattern(self).is_suffix_of(haystack) + } } ///////////////////////////////////////////////////////////////////////////// From b5acbd3f0360b221e9885be4c99957272b0ede82 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 19 May 2017 10:55:25 +0200 Subject: [PATCH 102/103] debuginfo: Generate unique DW_AT_names for compilation units to work around OSX linker bug. --- src/librustc_trans/context.rs | 5 +- src/librustc_trans/debuginfo/metadata.rs | 29 +++++----- src/test/debuginfo/multi-cgu.rs | 67 ++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 14 deletions(-) create mode 100644 src/test/debuginfo/multi-cgu.rs diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 90cda2f5cad..c2f2c63790a 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -375,7 +375,10 @@ impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> { let dbg_cx = if shared.tcx.sess.opts.debuginfo != NoDebugInfo { let dctx = debuginfo::CrateDebugContext::new(llmod); - debuginfo::metadata::compile_unit_metadata(shared, &dctx, shared.tcx.sess); + debuginfo::metadata::compile_unit_metadata(shared, + codegen_unit.name(), + &dctx, + shared.tcx.sess); Some(dctx) } else { None diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 188f8ee3366..7d8b8161abe 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -762,23 +762,30 @@ fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } pub fn compile_unit_metadata(scc: &SharedCrateContext, + codegen_unit_name: &str, debug_context: &CrateDebugContext, sess: &Session) -> DIDescriptor { - let compile_unit_name = match sess.local_crate_source_file { - None => fallback_path(scc), - Some(ref path) => { - CString::new(&path[..]).unwrap() - } + let mut name_in_debuginfo = match sess.local_crate_source_file { + Some(ref path) => path.clone(), + None => scc.tcx().crate_name(LOCAL_CRATE).to_string(), }; - debug!("compile_unit_metadata: {:?}", compile_unit_name); + // The OSX linker has an idiosyncrasy where it will ignore some debuginfo + // if multiple object files with the same DW_AT_name are linked together. + // As a workaround we generate unique names for each object file. Those do + // not correspond to an actual source file but that should be harmless. + if scc.sess().target.target.options.is_like_osx { + name_in_debuginfo.push_str("@"); + name_in_debuginfo.push_str(codegen_unit_name); + } + + debug!("compile_unit_metadata: {:?}", name_in_debuginfo); // FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice. let producer = format!("clang LLVM (rustc version {})", (option_env!("CFG_VERSION")).expect("CFG_VERSION")); - let compile_unit_name = compile_unit_name.as_ptr(); - + let name_in_debuginfo = CString::new(name_in_debuginfo).unwrap(); let work_dir = CString::new(&sess.working_dir.0[..]).unwrap(); let producer = CString::new(producer).unwrap(); let flags = "\0"; @@ -786,7 +793,7 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext, unsafe { let file_metadata = llvm::LLVMRustDIBuilderCreateFile( - debug_context.builder, compile_unit_name, work_dir.as_ptr()); + debug_context.builder, name_in_debuginfo.as_ptr(), work_dir.as_ptr()); return llvm::LLVMRustDIBuilderCreateCompileUnit( debug_context.builder, @@ -798,10 +805,6 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext, 0, split_name.as_ptr() as *const _) }; - - fn fallback_path(scc: &SharedCrateContext) -> CString { - CString::new(scc.tcx().crate_name(LOCAL_CRATE).to_string()).unwrap() - } } struct MetadataCreationResult { diff --git a/src/test/debuginfo/multi-cgu.rs b/src/test/debuginfo/multi-cgu.rs new file mode 100644 index 00000000000..f4f9f92396f --- /dev/null +++ b/src/test/debuginfo/multi-cgu.rs @@ -0,0 +1,67 @@ +// 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. + + +// This test case makes sure that we get proper break points for binaries +// compiled with multiple codegen units. (see #39160) + + +// min-lldb-version: 310 + +// compile-flags:-g -Ccodegen-units=2 + +// === GDB TESTS =============================================================== + +// gdb-command:run + +// gdb-command:print xxx +// gdb-check:$1 = 12345 +// gdb-command:continue + +// gdb-command:print yyy +// gdb-check:$2 = 67890 +// gdb-command:continue + + +// === LLDB TESTS ============================================================== + +// lldb-command:run + +// lldb-command:print xxx +// lldb-check:[...]$0 = 12345 +// lldb-command:continue + +// lldb-command:print yyy +// lldb-check:[...]$1 = 67890 +// lldb-command:continue + + +#![feature(omit_gdb_pretty_printer_section)] +#![omit_gdb_pretty_printer_section] + +mod a { + pub fn foo(xxx: u32) { + super::_zzz(); // #break + } +} + +mod b { + pub fn bar(yyy: u64) { + super::_zzz(); // #break + } +} + +fn main() { + a::foo(12345); + b::bar(67890); +} + +#[inline(never)] +fn _zzz() {} From a89292514b6d4c4e9be7d6d527ad72e08e27173c Mon Sep 17 00:00:00 2001 From: David LeGare Date: Fri, 19 May 2017 07:29:52 -0500 Subject: [PATCH 103/103] Fix doc test failure for OpenOptionsExt --- src/libstd/sys/windows/ext/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs index 34f3a0196ce..2d00cb38ec4 100644 --- a/src/libstd/sys/windows/ext/fs.rs +++ b/src/libstd/sys/windows/ext/fs.rs @@ -241,7 +241,7 @@ pub trait OpenOptionsExt { /// .create(true) /// /// // Sets the flag value to `SecurityIdentification`. - /// options.security_qos_flags(1) + /// .security_qos_flags(1) /// /// .open("foo.txt"); /// ```